Wine-Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 22 participants
- 84527 discussions
April 14, 2021
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/tests/metafile.c | 51 +++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 9340e20444a..e2592988cea 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -5023,6 +5023,56 @@ static void test_emf_AlphaBlend(void)
ReleaseDC(0, hdc);
}
+static void test_emf_text_extends(void)
+{
+ static const XFORM xform = {0.5f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f};
+ HFONT font, old_font, old_font2;
+ LOGFONTW logfont = {0};
+ HENHMETAFILE emf;
+ SIZE size, size2;
+ HDC dc, emf_dc;
+ BOOL ret;
+
+ dc = GetDC(0);
+ emf_dc = CreateEnhMetaFileW(dc, NULL, NULL, NULL);
+ ok(!!emf_dc, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+
+ logfont.lfWeight = FW_NORMAL;
+ logfont.lfHeight = 20;
+ lstrcpyW(logfont.lfFaceName, L"Tahoma");
+ font = CreateFontIndirectW(&logfont);
+ ok(!!font, "CreateFontIndirectW failed, error %d\n", GetLastError());
+
+ old_font = SelectObject(dc, font);
+ old_font2 = SelectObject(emf_dc, font);
+
+ ret = SetGraphicsMode(dc, GM_ADVANCED);
+ ok(ret, "SetGraphicsMode failed, error %d\n", GetLastError());
+ ret = SetGraphicsMode(emf_dc, GM_ADVANCED);
+ ok(ret, "SetGraphicsMode failed, error %d\n", GetLastError());
+
+ ret = ModifyWorldTransform(dc, &xform, MWT_RIGHTMULTIPLY);
+ ok(ret, "ModifyWorldTransform failed, error %d\n", GetLastError());
+ ret = ModifyWorldTransform(emf_dc, &xform, MWT_RIGHTMULTIPLY);
+ ok(ret, "ModifyWorldTransform failed, error %d\n", GetLastError());
+
+ ret = GetTextExtentPoint32W(dc, L"W", 1, &size);
+ ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
+ ret = GetTextExtentPoint32W(emf_dc, L"W", 1, &size2);
+ ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
+todo_wine
+ ok(size2.cx == size.cx && size2.cy == size.cy, "Expected size %dx%d, got %dx%d\n",
+ size.cx, size.cy, size2.cx, size2.cy);
+
+ SelectObject(emf_dc, old_font2);
+ SelectObject(dc, old_font);
+ DeleteObject(font);
+ emf = CloseEnhMetaFile(emf_dc);
+ ok(!!emf, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ DeleteEnhMetaFile(emf);
+ ReleaseDC(0, dc);
+}
+
START_TEST(metafile)
{
init_function_pointers();
@@ -5041,6 +5091,7 @@ START_TEST(metafile)
test_emf_PolyPolyline();
test_emf_GradientFill();
test_emf_WorldTransform();
+ test_emf_text_extends();
/* For win-format metafiles (mfdrv) */
test_mf_SaveDC();
--
2.27.0
1
0
April 14, 2021
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdi32/tests/metafile.c | 713 +++++++++++++++++++++++++++++++++++-
1 file changed, 712 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 648e9369803..ec9c7894574 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -991,7 +991,7 @@ static void test_mf_SaveDC(void)
/* with the nominal results. */
/* Maximum size of sample metafiles in bytes. */
-#define MF_BUFSIZE 1024
+#define MF_BUFSIZE 2048
/* 8x8 bitmap data for a pattern brush */
static const unsigned char SAMPLE_PATTERN_BRUSH[] = {
@@ -4315,6 +4315,716 @@ static void test_emf_WorldTransform(void)
}
}
+static const unsigned char EMF_ALPHABLEND_1BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_4BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc8, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x68, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_8BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0x88, 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xa4, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x28, 0x04, 0x00, 0x00, 0x94, 0x04, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_16BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x03, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfe, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0, 0x03, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
+ 0xe0, 0x07, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_16BIT_555[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_24BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xa8, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_32BIT_888[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static const unsigned char EMF_ALPHABLEND_32BIT[] =
+{
+ 0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x4f, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,
+ 0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+ 0xc4, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x07, 0x00, 0x00, 0xd0, 0x03, 0x00, 0x00,
+ 0xfc, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x07, 0x00,
+ 0xb9, 0xf0, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x62, 0x00, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x72, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x0a, 0xd7, 0xa3, 0x3b,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0a, 0xd7, 0x23, 0x3c, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00,
+ 0x90, 0x01, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
+ 0xe0, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x00
+};
+
+static void test_emf_AlphaBlend(void)
+{
+ static const XFORM xform = {0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
+ static const BLENDFUNCTION blend = {AC_SRC_OVER, 0, 128, 0};
+ static const int bitmap_width = 4, bitmap_height = 4;
+ unsigned char bmi_buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])];
+ BITMAPINFO *bmi = (BITMAPINFO *)bmi_buffer;
+ HDC hdc, hdc_emf, hdc_emf2, hdc_bitmap;
+ HBITMAP hbitmap, old_hbitmap;
+ HENHMETAFILE hemf, hemf2;
+ int ret, test_idx;
+ char comment[64];
+ void *bits;
+
+ static const struct
+ {
+ WORD bpp;
+ WORD compression;
+ const void *bits;
+ size_t bits_count;
+ DWORD used_color_count;
+ DWORD color_count;
+ RGBQUAD colors[3];
+ }
+ tests[] =
+ {
+ {1, BI_RGB, EMF_ALPHABLEND_1BIT, sizeof(EMF_ALPHABLEND_1BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {4, BI_RGB, EMF_ALPHABLEND_4BIT, sizeof(EMF_ALPHABLEND_4BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {8, BI_RGB, EMF_ALPHABLEND_8BIT, sizeof(EMF_ALPHABLEND_8BIT), 1, 1, {{0xff, 0xff, 0xff}}},
+ {16, BI_RGB, EMF_ALPHABLEND_16BIT_555, sizeof(EMF_ALPHABLEND_16BIT_555)},
+ {24, BI_RGB, EMF_ALPHABLEND_24BIT, sizeof(EMF_ALPHABLEND_24BIT)},
+ {32, BI_RGB, EMF_ALPHABLEND_32BIT_888, sizeof(EMF_ALPHABLEND_32BIT_888)},
+ {16, BI_BITFIELDS, EMF_ALPHABLEND_16BIT, sizeof(EMF_ALPHABLEND_16BIT), 0, 3, {{0x00, 0xf8, 0x00}, {0xe0, 0x07, 0x00}, {0x1f, 0x00, 0x00}}},
+ {32, BI_BITFIELDS, EMF_ALPHABLEND_32BIT, sizeof(EMF_ALPHABLEND_32BIT), 0, 3, {{0x00, 0x00, 0xff}, {0xe0, 0xff, 0x00}, {0xff, 0x00, 0x00}}},
+ };
+
+ hdc = GetDC(0);
+
+ /* Test that source DC cannot be an enhanced metafile */
+ hdc_emf = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+ hdc_emf2 = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf2, "CreateEnhMetaFileW failed, error %d\n", GetLastError());
+
+ ret = GdiAlphaBlend(hdc_emf, 0, 0, 1, 1, hdc_emf2, 0, 0, 1, 1, blend);
+ ok(!ret, "GdiAlphaBlend succeeded\n");
+
+ hemf2 = CloseEnhMetaFile(hdc_emf2);
+ ok(!!hemf2, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ hemf = CloseEnhMetaFile(hdc_emf);
+ ok(!!hemf, "CloseEnhMetaFile failed, error %d\n", GetLastError());
+ DeleteEnhMetaFile(hemf2);
+ DeleteEnhMetaFile(hemf);
+
+ /* Test AlphaBlend with different format of bitmaps */
+ for (test_idx = 0; test_idx < ARRAY_SIZE(tests); ++test_idx)
+ {
+ memset(bmi_buffer, 0, sizeof(bmi_buffer));
+ bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
+ bmi->bmiHeader.biHeight = bitmap_width;
+ bmi->bmiHeader.biWidth = bitmap_height;
+ bmi->bmiHeader.biBitCount = tests[test_idx].bpp;
+ bmi->bmiHeader.biPlanes = 1;
+ bmi->bmiHeader.biCompression = tests[test_idx].compression;
+ bmi->bmiHeader.biClrUsed = tests[test_idx].used_color_count;
+ memcpy(bmi->bmiColors, tests[test_idx].colors, sizeof(RGBQUAD) * tests[test_idx].color_count);
+
+ hbitmap = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, &bits, NULL, 0);
+ ok(!!hbitmap, "Test %d: CreateDIBSection failed, error %d\n", test_idx, GetLastError());
+ hdc_bitmap = CreateCompatibleDC(hdc);
+ ok(!!hdc_bitmap, "Test %d: CreateCompatibleDC failed, error %d\n", test_idx, GetLastError());
+ old_hbitmap = SelectObject(hdc_bitmap, hbitmap);
+
+ SetBkColor(hdc_bitmap, RGB(0xff, 0xff, 0xff));
+ ret = SetGraphicsMode(hdc_bitmap, GM_ADVANCED);
+ ok(ret, "Test %d: SetGraphicsMode failed, error %d\n", test_idx, GetLastError());
+ ret = SetWorldTransform(hdc_bitmap, &xform);
+ ok(ret, "Test %d: SetWorldTransform failed, error %d\n", test_idx, GetLastError());
+ ret = SetMapMode(hdc_bitmap, MM_ANISOTROPIC);
+ ok(ret, "Test %d: SetMapMode failed, error %d\n", test_idx, GetLastError());
+ ret = SetWindowOrgEx(hdc_bitmap, 0, 0, NULL);
+ ok(ret, "Test %d: SetWindowOrgEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetWindowExtEx(hdc_bitmap, 400, 400, NULL);
+ ok(ret, "Test %d: SetWindowExtEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetViewportOrgEx(hdc_bitmap, 0, 0, NULL);
+ ok(ret, "Test %d: SetViewportOrgEx failed, error %d\n", test_idx, GetLastError());
+ ret = SetViewportExtEx(hdc_bitmap, bitmap_width, bitmap_height, NULL);
+ ok(ret, "Test %d: SetViewportExtEx failed, error %d\n", test_idx, GetLastError());
+
+ hdc_emf = CreateEnhMetaFileW(hdc, NULL, NULL, NULL);
+ ok(!!hdc_emf, "Test %d: CreateEnhMetaFileW failed, error %d\n", test_idx, GetLastError());
+
+ ret = BitBlt(hdc_emf, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, WHITENESS);
+ ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
+ ret = BitBlt(hdc_bitmap, 0, 0, bitmap_width, bitmap_height, 0, 0, 0, BLACKNESS);
+ ok(ret, "Test %d: BitBlt failed, error %d\n", test_idx, GetLastError());
+ ret = GdiAlphaBlend(hdc_emf, 0, 0, bitmap_width, bitmap_height, hdc_bitmap, 0, 0, 400, 400, blend);
+ todo_wine
+ ok(ret, "Test %d: GdiAlphaBlend failed, error %d\n", test_idx, GetLastError());
+
+ hemf = CloseEnhMetaFile(hdc_emf);
+ ok(!!hemf, "Test %d: CloseEnhMetaFile failed, %d\n", test_idx, GetLastError());
+
+ sprintf(comment, "test_emf_AlphaBlend() test %d", test_idx);
+ if (ret)
+ ret = compare_emf_bits(hemf, tests[test_idx].bits, tests[test_idx].bits_count, comment, FALSE);
+ if (ret)
+ {
+ dump_emf_bits(hemf, comment);
+ dump_emf_records(hemf, comment);
+ }
+
+ DeleteEnhMetaFile(hemf);
+ SelectObject(hdc_bitmap, old_hbitmap);
+ DeleteDC(hdc_bitmap);
+ DeleteObject(hbitmap);
+ }
+
+ ReleaseDC(0, hdc);
+}
+
START_TEST(metafile)
{
init_function_pointers();
@@ -4323,6 +5033,7 @@ START_TEST(metafile)
test_ExtTextOut();
test_ExtTextOutScale();
test_SaveDC();
+ test_emf_AlphaBlend();
test_emf_BitBlt();
test_emf_DCBrush();
test_emf_ExtTextOut_on_path();
--
2.27.0
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
tools/winedump/emf.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/tools/winedump/emf.c b/tools/winedump/emf.c
index d5630f6812b..2f54f73153b 100644
--- a/tools/winedump/emf.c
+++ b/tools/winedump/emf.c
@@ -325,7 +325,30 @@ static int dump_emfrecord(void)
}
EMRCASE(EMR_BITBLT);
- EMRCASE(EMR_STRETCHBLT);
+
+ case EMR_STRETCHBLT:
+ {
+ const EMRSTRETCHBLT *blt = PRD(offset, sizeof(*blt));
+ const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)((const unsigned char *)blt + blt->offBmiSrc);
+
+ printf("%-20s %08x\n", "EMR_STRETCHBLT", length);
+ printf("bounds (%d,%d - %d,%d) dst %d,%d %dx%d src %d,%d %dx%d rop %#x xform (%f, %f, %f, %f, %f, %f)\n"
+ "bk_color %#x usage %#x bmi_offset %#x bmi_size %#x bits_offset %#x bits_size %#x\n",
+ blt->rclBounds.left, blt->rclBounds.top, blt->rclBounds.right, blt->rclBounds.bottom,
+ blt->xDest, blt->yDest, blt->cxDest, blt->cyDest,
+ blt->xSrc, blt->ySrc, blt->cxSrc, blt->cySrc, blt->dwRop,
+ blt->xformSrc.eM11, blt->xformSrc.eM12, blt->xformSrc.eM21,
+ blt->xformSrc.eM22, blt->xformSrc.eDx, blt->xformSrc.eDy,
+ blt->crBkColorSrc, blt->iUsageSrc, blt->offBmiSrc, blt->cbBmiSrc,
+ blt->offBitsSrc, blt->cbBitsSrc);
+ printf("BITMAPINFOHEADER biSize %#x biWidth %d biHeight %d biPlanes %d biBitCount %d biCompression %#x\n"
+ "biSizeImage %#x biXPelsPerMeter %d biYPelsPerMeter %d biClrUsed %#x biClrImportant %#x\n",
+ bmih->biSize, bmih->biWidth, bmih->biHeight, bmih->biPlanes, bmih->biBitCount,
+ bmih->biCompression, bmih->biSizeImage, bmih->biXPelsPerMeter, bmih->biYPelsPerMeter,
+ bmih->biClrUsed, bmih->biClrImportant);
+ break;
+ }
+
EMRCASE(EMR_MASKBLT);
EMRCASE(EMR_PLGBLT);
EMRCASE(EMR_SETDIBITSTODEVICE);
--
2.27.0
1
0
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
tools/winedump/emf.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/tools/winedump/emf.c b/tools/winedump/emf.c
index d44f7a806a5..d5630f6812b 100644
--- a/tools/winedump/emf.c
+++ b/tools/winedump/emf.c
@@ -397,7 +397,30 @@ static int dump_emfrecord(void)
EMRCASE(EMR_COLORCORRECTPALETTE);
EMRCASE(EMR_SETICMPROFILEA);
EMRCASE(EMR_SETICMPROFILEW);
- EMRCASE(EMR_ALPHABLEND);
+
+ case EMR_ALPHABLEND:
+ {
+ const EMRALPHABLEND *blend = PRD(offset, sizeof(*blend));
+ const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)((const unsigned char *)blend + blend->offBmiSrc);
+
+ printf("%-20s %08x\n", "EMR_ALPHABLEND", length);
+ printf("bounds (%d,%d - %d,%d) dst %d,%d %dx%d src %d,%d %dx%d rop %#x xform (%f, %f, %f, %f, %f, %f)\n"
+ "bk_color %#x usage %#x bmi_offset %#x bmi_size %#x bits_offset %#x bits_size %#x\n",
+ blend->rclBounds.left, blend->rclBounds.top, blend->rclBounds.right, blend->rclBounds.bottom,
+ blend->xDest, blend->yDest, blend->cxDest, blend->cyDest,
+ blend->xSrc, blend->ySrc, blend->cxSrc, blend->cySrc, blend->dwRop,
+ blend->xformSrc.eM11, blend->xformSrc.eM12, blend->xformSrc.eM21,
+ blend->xformSrc.eM22, blend->xformSrc.eDx, blend->xformSrc.eDy,
+ blend->crBkColorSrc, blend->iUsageSrc, blend->offBmiSrc, blend->cbBmiSrc,
+ blend->offBitsSrc, blend->cbBitsSrc);
+ printf("BITMAPINFOHEADER biSize %#x biWidth %d biHeight %d biPlanes %d biBitCount %d biCompression %#x\n"
+ "biSizeImage %#x biXPelsPerMeter %d biYPelsPerMeter %d biClrUsed %#x biClrImportant %#x\n",
+ bmih->biSize, bmih->biWidth, bmih->biHeight, bmih->biPlanes, bmih->biBitCount,
+ bmih->biCompression, bmih->biSizeImage, bmih->biXPelsPerMeter, bmih->biYPelsPerMeter,
+ bmih->biClrUsed, bmih->biClrImportant);
+ break;
+ }
+
EMRCASE(EMR_SETLAYOUT);
EMRCASE(EMR_TRANSPARENTBLT);
EMRCASE(EMR_RESERVED_117);
--
2.27.0
1
0
[PATCH 1/3] ntoskrnl: Remove the device from the root device list in IRP_MN_REMOVE_DEVICE.
by Zebediah Figura April 14, 2021
by Zebediah Figura April 14, 2021
April 14, 2021
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/ntoskrnl.exe/pnp.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/pnp.c b/dlls/ntoskrnl.exe/pnp.c
index 0d9d816e3c0..095344b1073 100644
--- a/dlls/ntoskrnl.exe/pnp.c
+++ b/dlls/ntoskrnl.exe/pnp.c
@@ -955,10 +955,13 @@ static NTSTATUS WINAPI pnp_manager_device_pnp( DEVICE_OBJECT *device, IRP *irp )
break;
case IRP_MN_START_DEVICE:
case IRP_MN_SURPRISE_REMOVAL:
- case IRP_MN_REMOVE_DEVICE:
/* Nothing to do. */
irp->IoStatus.u.Status = STATUS_SUCCESS;
break;
+ case IRP_MN_REMOVE_DEVICE:
+ list_remove( &root_device->entry );
+ irp->IoStatus.u.Status = STATUS_SUCCESS;
+ break;
case IRP_MN_QUERY_CAPABILITIES:
irp->IoStatus.u.Status = STATUS_SUCCESS;
break;
--
2.30.2
2
3
[PATCH vkd3d v3 1/6] vkd3d-shader: Rename HLSL_IR_ASSIGNMENT to HLSL_IR_STORE.
by Zebediah Figura April 14, 2021
by Zebediah Figura April 14, 2021
April 14, 2021
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
libs/vkd3d-shader/hlsl.c | 76 ++++++++++++++++----------------
libs/vkd3d-shader/hlsl.h | 22 ++++-----
libs/vkd3d-shader/hlsl.y | 50 ++++++++++-----------
libs/vkd3d-shader/hlsl_codegen.c | 59 ++++++++++++-------------
4 files changed, 103 insertions(+), 104 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c
index 53b9db36..23003f44 100644
--- a/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d-shader/hlsl.c
@@ -418,28 +418,28 @@ static bool type_is_single_reg(const struct hlsl_type *type)
return type->type == HLSL_CLASS_SCALAR || type->type == HLSL_CLASS_VECTOR;
}
-struct hlsl_ir_assignment *hlsl_new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
+struct hlsl_ir_store *hlsl_new_store(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc)
{
- struct hlsl_ir_assignment *assign;
+ struct hlsl_ir_store *store;
if (!writemask && type_is_single_reg(rhs->data_type))
writemask = (1 << rhs->data_type->dimx) - 1;
- if (!(assign = vkd3d_malloc(sizeof(*assign))))
+ if (!(store = vkd3d_malloc(sizeof(*store))))
return NULL;
- init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc);
- assign->lhs.var = var;
- hlsl_src_from_node(&assign->lhs.offset, offset);
- hlsl_src_from_node(&assign->rhs, rhs);
- assign->writemask = writemask;
- return assign;
+ init_node(&store->node, HLSL_IR_STORE, NULL, loc);
+ store->lhs.var = var;
+ hlsl_src_from_node(&store->lhs.offset, offset);
+ hlsl_src_from_node(&store->rhs, rhs);
+ store->writemask = writemask;
+ return store;
}
-struct hlsl_ir_assignment *hlsl_new_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs)
+struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs)
{
- return hlsl_new_assignment(lhs, NULL, rhs, 0, rhs->loc);
+ return hlsl_new_store(lhs, NULL, rhs, 0, rhs->loc);
}
struct hlsl_ir_constant *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n,
@@ -830,13 +830,13 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type)
{
static const char * const names[] =
{
- "HLSL_IR_ASSIGNMENT",
"HLSL_IR_CONSTANT",
"HLSL_IR_EXPR",
"HLSL_IR_IF",
"HLSL_IR_LOAD",
"HLSL_IR_LOOP",
"HLSL_IR_JUMP",
+ "HLSL_IR_STORE",
"HLSL_IR_SWIZZLE",
};
@@ -909,17 +909,6 @@ static const char *debug_writemask(DWORD writemask)
return vkd3d_dbg_sprintf(".%s", string);
}
-static void dump_ir_assignment(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_assignment *assign)
-{
- vkd3d_string_buffer_printf(buffer, "= (");
- dump_deref(buffer, &assign->lhs);
- if (assign->writemask != VKD3DSP_WRITEMASK_ALL)
- vkd3d_string_buffer_printf(buffer, "%s", debug_writemask(assign->writemask));
- vkd3d_string_buffer_printf(buffer, " ");
- dump_src(buffer, &assign->rhs);
- vkd3d_string_buffer_printf(buffer, ")");
-}
-
static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_constant *constant)
{
struct hlsl_type *type = constant->node.data_type;
@@ -1080,6 +1069,17 @@ static void dump_ir_loop(struct vkd3d_string_buffer *buffer, const struct hlsl_i
vkd3d_string_buffer_printf(buffer, "}\n");
}
+static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store)
+{
+ vkd3d_string_buffer_printf(buffer, "= (");
+ dump_deref(buffer, &store->lhs);
+ if (store->writemask != VKD3DSP_WRITEMASK_ALL)
+ vkd3d_string_buffer_printf(buffer, "%s", debug_writemask(store->writemask));
+ vkd3d_string_buffer_printf(buffer, " ");
+ dump_src(buffer, &store->rhs);
+ vkd3d_string_buffer_printf(buffer, ")");
+}
+
static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_swizzle *swizzle)
{
unsigned int i;
@@ -1111,10 +1111,6 @@ static void dump_instr(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_
switch (instr->type)
{
- case HLSL_IR_ASSIGNMENT:
- dump_ir_assignment(buffer, hlsl_ir_assignment(instr));
- break;
-
case HLSL_IR_CONSTANT:
dump_ir_constant(buffer, hlsl_ir_constant(instr));
break;
@@ -1139,6 +1135,10 @@ static void dump_instr(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_
dump_ir_loop(buffer, hlsl_ir_loop(instr));
break;
+ case HLSL_IR_STORE:
+ dump_ir_store(buffer, hlsl_ir_store(instr));
+ break;
+
case HLSL_IR_SWIZZLE:
dump_ir_swizzle(buffer, hlsl_ir_swizzle(instr));
break;
@@ -1198,13 +1198,6 @@ void hlsl_free_instr_list(struct list *list)
vkd3d_free(list);
}
-static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
-{
- hlsl_src_remove(&assignment->rhs);
- hlsl_src_remove(&assignment->lhs.offset);
- vkd3d_free(assignment);
-}
-
static void free_ir_constant(struct hlsl_ir_constant *constant)
{
vkd3d_free(constant);
@@ -1251,6 +1244,13 @@ static void free_ir_loop(struct hlsl_ir_loop *loop)
vkd3d_free(loop);
}
+static void free_ir_store(struct hlsl_ir_store *store)
+{
+ hlsl_src_remove(&store->rhs);
+ hlsl_src_remove(&store->lhs.offset);
+ vkd3d_free(store);
+}
+
static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
{
hlsl_src_remove(&swizzle->val);
@@ -1261,10 +1261,6 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
{
switch (node->type)
{
- case HLSL_IR_ASSIGNMENT:
- free_ir_assignment(hlsl_ir_assignment(node));
- break;
-
case HLSL_IR_CONSTANT:
free_ir_constant(hlsl_ir_constant(node));
break;
@@ -1289,6 +1285,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node)
free_ir_loop(hlsl_ir_loop(node));
break;
+ case HLSL_IR_STORE:
+ free_ir_store(hlsl_ir_store(node));
+ break;
+
case HLSL_IR_SWIZZLE:
free_ir_swizzle(hlsl_ir_swizzle(node));
break;
diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h
index cf12f63f..c82cd4f5 100644
--- a/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d-shader/hlsl.h
@@ -139,13 +139,13 @@ struct hlsl_struct_field
enum hlsl_ir_node_type
{
- HLSL_IR_ASSIGNMENT = 0,
HLSL_IR_CONSTANT,
HLSL_IR_EXPR,
HLSL_IR_IF,
HLSL_IR_LOAD,
HLSL_IR_LOOP,
HLSL_IR_JUMP,
+ HLSL_IR_STORE,
HLSL_IR_SWIZZLE,
};
@@ -352,7 +352,7 @@ struct hlsl_ir_load
struct hlsl_deref src;
};
-struct hlsl_ir_assignment
+struct hlsl_ir_store
{
struct hlsl_ir_node node;
struct hlsl_deref lhs;
@@ -420,12 +420,6 @@ enum hlsl_error_level
HLSL_LEVEL_NOTE,
};
-static inline struct hlsl_ir_assignment *hlsl_ir_assignment(const struct hlsl_ir_node *node)
-{
- assert(node->type == HLSL_IR_ASSIGNMENT);
- return CONTAINING_RECORD(node, struct hlsl_ir_assignment, node);
-}
-
static inline struct hlsl_ir_constant *hlsl_ir_constant(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_CONSTANT);
@@ -462,6 +456,12 @@ static inline struct hlsl_ir_loop *hlsl_ir_loop(const struct hlsl_ir_node *node)
return CONTAINING_RECORD(node, struct hlsl_ir_loop, node);
}
+static inline struct hlsl_ir_store *hlsl_ir_store(const struct hlsl_ir_node *node)
+{
+ assert(node->type == HLSL_IR_STORE);
+ return CONTAINING_RECORD(node, struct hlsl_ir_store, node);
+}
+
static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node *node)
{
assert(node->type == HLSL_IR_SWIZZLE);
@@ -520,8 +520,6 @@ struct hlsl_ir_var *hlsl_get_var(struct hlsl_scope *scope, const char *name) DEC
struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *basic_type,
unsigned int array_size) DECLSPEC_HIDDEN;
-struct hlsl_ir_assignment *hlsl_new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
- struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
struct hlsl_ir_node *hlsl_new_binary_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1,
struct hlsl_ir_node *arg2) DECLSPEC_HIDDEN;
struct hlsl_ir_expr *hlsl_new_cast(struct hlsl_ir_node *node, struct hlsl_type *type,
@@ -534,8 +532,10 @@ struct hlsl_ir_jump *hlsl_new_jump(enum hlsl_ir_jump_type type, struct vkd3d_sha
struct hlsl_ir_load *hlsl_new_load(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, struct hlsl_type *type,
struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
struct hlsl_ir_loop *hlsl_new_loop(struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
-struct hlsl_ir_assignment *hlsl_new_simple_assignment(struct hlsl_ir_var *lhs,
+struct hlsl_ir_store *hlsl_new_simple_store(struct hlsl_ir_var *lhs,
struct hlsl_ir_node *rhs) DECLSPEC_HIDDEN;
+struct hlsl_ir_store *hlsl_new_store(struct hlsl_ir_var *var, struct hlsl_ir_node *offset,
+ struct hlsl_ir_node *rhs, unsigned int writemask, struct vkd3d_shader_location loc) DECLSPEC_HIDDEN;
struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct list *fields) DECLSPEC_HIDDEN;
struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned int components,
struct hlsl_ir_node *val, struct vkd3d_shader_location *loc) DECLSPEC_HIDDEN;
diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y
index ab7059d3..6216b100 100644
--- a/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d-shader/hlsl.y
@@ -499,14 +499,14 @@ static struct hlsl_ir_jump *add_return(struct hlsl_ctx *ctx, struct list *instrs
if (return_value)
{
- struct hlsl_ir_assignment *assignment;
+ struct hlsl_ir_store *store;
if (!(return_value = add_implicit_conversion(ctx, instrs, return_value, return_type, &loc)))
return NULL;
- if (!(assignment = hlsl_new_simple_assignment(ctx->cur_function->return_var, return_value)))
+ if (!(store = hlsl_new_simple_store(ctx->cur_function->return_var, return_value)))
return NULL;
- list_add_after(&return_value->entry, &assignment->node.entry);
+ list_add_after(&return_value->entry, &store->node.entry);
}
else if (!hlsl_type_is_void(return_type))
{
@@ -543,17 +543,17 @@ static struct hlsl_ir_load *add_load(struct hlsl_ctx *ctx, struct list *instrs,
}
else
{
- struct hlsl_ir_assignment *assign;
+ struct hlsl_ir_store *store;
char name[27];
sprintf(name, "<deref-%p>", var_node);
if (!(var = hlsl_new_synthetic_var(ctx, name, var_node->data_type, var_node->loc)))
return NULL;
- if (!(assign = hlsl_new_simple_assignment(var, var_node)))
+ if (!(store = hlsl_new_simple_store(var, var_node)))
return NULL;
- list_add_tail(instrs, &assign->node.entry);
+ list_add_tail(instrs, &store->node.entry);
}
if (!(load = hlsl_new_load(var, offset, data_type, loc)))
@@ -900,7 +900,7 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node)
FIXME("Unhandled type %s.\n", hlsl_node_type_to_string(node->type));
return 0;
- case HLSL_IR_ASSIGNMENT:
+ case HLSL_IR_STORE:
default:
WARN("Invalid node type %s.\n", hlsl_node_type_to_string(node->type));
return 0;
@@ -1216,7 +1216,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs)
{
struct hlsl_type *lhs_type = lhs->data_type;
- struct hlsl_ir_assignment *assign;
+ struct hlsl_ir_store *store;
struct hlsl_ir_expr *copy;
DWORD writemask = 0;
@@ -1239,7 +1239,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
return NULL;
}
- if (!(assign = vkd3d_malloc(sizeof(*assign))))
+ if (!(store = vkd3d_malloc(sizeof(*store))))
return NULL;
while (lhs->type != HLSL_IR_LOAD)
@@ -1247,7 +1247,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
if (lhs->type == HLSL_IR_EXPR && hlsl_ir_expr(lhs)->op == HLSL_IR_UNOP_CAST)
{
FIXME("Cast on the lhs.\n");
- vkd3d_free(assign);
+ vkd3d_free(store);
return NULL;
}
else if (lhs->type == HLSL_IR_SWIZZLE)
@@ -1261,13 +1261,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
if (!invert_swizzle(&s, &writemask, &width))
{
hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_WRITEMASK, "Invalid writemask.");
- vkd3d_free(assign);
+ vkd3d_free(store);
return NULL;
}
if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc)))
{
- vkd3d_free(assign);
+ vkd3d_free(store);
return NULL;
}
list_add_tail(instrs, &new_swizzle->node.entry);
@@ -1278,17 +1278,17 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
else
{
hlsl_error(ctx, lhs->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_LVALUE, "Invalid lvalue.");
- vkd3d_free(assign);
+ vkd3d_free(store);
return NULL;
}
}
- init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, lhs->loc);
- assign->writemask = writemask;
- assign->lhs.var = hlsl_ir_load(lhs)->src.var;
- hlsl_src_from_node(&assign->lhs.offset, hlsl_ir_load(lhs)->src.offset.node);
- hlsl_src_from_node(&assign->rhs, rhs);
- list_add_tail(instrs, &assign->node.entry);
+ init_node(&store->node, HLSL_IR_STORE, NULL, lhs->loc);
+ store->writemask = writemask;
+ store->lhs.var = hlsl_ir_load(lhs)->src.var;
+ hlsl_src_from_node(&store->lhs.offset, hlsl_ir_load(lhs)->src.offset.node);
+ hlsl_src_from_node(&store->rhs, rhs);
+ list_add_tail(instrs, &store->node.entry);
/* Don't use the instruction itself as a source, as this makes structure
* splitting easier. Instead copy it here. Since we retrieve sources from
@@ -1355,7 +1355,7 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru
LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
{
struct hlsl_ir_node *node = initializer->args[i];
- struct hlsl_ir_assignment *assign;
+ struct hlsl_ir_store *store;
struct hlsl_ir_constant *c;
if (i++ >= initializer->args_count)
@@ -1367,9 +1367,9 @@ static void struct_var_initializer(struct hlsl_ctx *ctx, struct list *list, stru
break;
list_add_tail(list, &c->node.entry);
- if (!(assign = hlsl_new_assignment(var, &c->node, node, 0, node->loc)))
+ if (!(store = hlsl_new_store(var, &c->node, node, 0, node->loc)))
break;
- list_add_tail(list, &assign->node.entry);
+ list_add_tail(list, &store->node.entry);
}
else
FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
@@ -2724,8 +2724,8 @@ postfix_expr:
/* var_modifiers is necessary to avoid shift/reduce conflicts. */
| var_modifiers type '(' initializer_expr_list ')'
{
- struct hlsl_ir_assignment *assignment;
unsigned int i, writemask_offset = 0;
+ struct hlsl_ir_store *store;
static unsigned int counter;
struct hlsl_ir_load *load;
struct hlsl_ir_var *var;
@@ -2788,11 +2788,11 @@ postfix_expr:
ctx->builtin_types.vector[$2->base_type][width - 1], &arg->loc)))
continue;
- if (!(assignment = hlsl_new_assignment(var, NULL, arg,
+ if (!(store = hlsl_new_store(var, NULL, arg,
((1 << width) - 1) << writemask_offset, arg->loc)))
YYABORT;
writemask_offset += width;
- list_add_tail($4.instrs, &assignment->node.entry);
+ list_add_tail($4.instrs, &store->node.entry);
}
vkd3d_free($4.args);
if (!(load = hlsl_new_var_load(var, @2)))
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index dbd591af..0641aa0f 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -27,8 +27,8 @@
static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *var)
{
struct vkd3d_string_buffer *name;
- struct hlsl_ir_assignment *store;
struct hlsl_ir_var *const_var;
+ struct hlsl_ir_store *store;
struct hlsl_ir_load *load;
if (!(name = vkd3d_string_buffer_get(&ctx->string_buffers)))
@@ -55,7 +55,7 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru
}
list_add_head(instrs, &load->node.entry);
- if (!(store = hlsl_new_simple_assignment(var, &load->node)))
+ if (!(store = hlsl_new_simple_store(var, &load->node)))
{
ctx->failed = true;
return;
@@ -67,8 +67,8 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
struct hlsl_type *type, unsigned int field_offset, const char *semantic)
{
struct vkd3d_string_buffer *name;
- struct hlsl_ir_assignment *store;
struct hlsl_ir_constant *offset;
+ struct hlsl_ir_store *store;
struct hlsl_ir_var *varying;
struct hlsl_ir_load *load;
@@ -102,7 +102,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
}
list_add_after(&load->node.entry, &offset->node.entry);
- if (!(store = hlsl_new_assignment(var, &offset->node, &load->node, 0, var->loc)))
+ if (!(store = hlsl_new_store(var, &offset->node, &load->node, 0, var->loc)))
{
ctx->failed = true;
return;
@@ -144,8 +144,8 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
struct hlsl_type *type, unsigned int field_offset, const char *semantic)
{
struct vkd3d_string_buffer *name;
- struct hlsl_ir_assignment *store;
struct hlsl_ir_constant *offset;
+ struct hlsl_ir_store *store;
struct hlsl_ir_var *varying;
struct hlsl_ir_load *load;
@@ -179,7 +179,7 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct
}
list_add_after(&offset->node.entry, &load->node.entry);
- if (!(store = hlsl_new_assignment(varying, NULL, &load->node, 0, var->loc)))
+ if (!(store = hlsl_new_store(varying, NULL, &load->node, 0, var->loc)))
{
ctx->failed = true;
return;
@@ -285,15 +285,15 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
{
const struct hlsl_struct_field *field;
const struct hlsl_ir_load *rhs_load;
- struct hlsl_ir_assignment *assign;
const struct hlsl_ir_node *rhs;
const struct hlsl_type *type;
+ struct hlsl_ir_store *store;
- if (instr->type != HLSL_IR_ASSIGNMENT)
+ if (instr->type != HLSL_IR_STORE)
return false;
- assign = hlsl_ir_assignment(instr);
- rhs = assign->rhs.node;
+ store = hlsl_ir_store(instr);
+ rhs = store->rhs.node;
type = rhs->data_type;
if (type->type != HLSL_CLASS_STRUCT)
return false;
@@ -302,8 +302,8 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
{
+ struct hlsl_ir_store *field_store;
struct hlsl_ir_node *offset, *add;
- struct hlsl_ir_assignment *store;
struct hlsl_ir_load *field_load;
struct hlsl_ir_constant *c;
@@ -333,9 +333,9 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
list_add_before(&instr->entry, &field_load->node.entry);
offset = &c->node;
- if (assign->lhs.offset.node)
+ if (store->lhs.offset.node)
{
- if (!(add = hlsl_new_binary_expr(HLSL_IR_BINOP_ADD, assign->lhs.offset.node, &c->node)))
+ if (!(add = hlsl_new_binary_expr(HLSL_IR_BINOP_ADD, store->lhs.offset.node, &c->node)))
{
ctx->failed = true;
return false;
@@ -344,20 +344,19 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
offset = add;
}
- if (!(store = hlsl_new_assignment(assign->lhs.var, offset, &field_load->node, 0, instr->loc)))
+ if (!(field_store = hlsl_new_store(store->lhs.var, offset, &field_load->node, 0, instr->loc)))
{
ctx->failed = true;
return false;
}
- list_add_before(&instr->entry, &store->node.entry);
+ list_add_before(&instr->entry, &field_store->node.entry);
}
- /* Remove the assignment instruction, so that we can split structs
- * which contain other structs. Although assignment instructions
- * produce a value, we don't allow HLSL_IR_ASSIGNMENT to be used as
- * a source. */
- list_remove(&assign->node.entry);
- hlsl_free_instr(&assign->node);
+ /* Remove the store instruction, so that we can split structs which contain
+ * other structs. Although assignments produce a value, we don't allow
+ * HLSL_IR_STORE to be used as a source. */
+ list_remove(&store->node.entry);
+ hlsl_free_instr(&store->node);
return true;
}
@@ -440,10 +439,10 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
}
break;
- case HLSL_IR_ASSIGNMENT:
+ case HLSL_IR_STORE:
{
- struct hlsl_ir_assignment *assignment = hlsl_ir_assignment(instr);
- struct hlsl_ir_var *var = assignment->lhs.var;
+ struct hlsl_ir_store *store = hlsl_ir_store(instr);
+ struct hlsl_ir_var *var = store->lhs.var;
if (var->last_read < instr->index)
{
@@ -517,16 +516,16 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
{
switch (instr->type)
{
- case HLSL_IR_ASSIGNMENT:
+ case HLSL_IR_STORE:
{
- struct hlsl_ir_assignment *assignment = hlsl_ir_assignment(instr);
+ struct hlsl_ir_store *store = hlsl_ir_store(instr);
- var = assignment->lhs.var;
+ var = store->lhs.var;
if (!var->first_write)
var->first_write = loop_first ? min(instr->index, loop_first) : instr->index;
- assignment->rhs.node->last_read = instr->index;
- if (assignment->lhs.offset.node)
- assignment->lhs.offset.node->last_read = instr->index;
+ store->rhs.node->last_read = instr->index;
+ if (store->lhs.offset.node)
+ store->lhs.offset.node->last_read = instr->index;
break;
}
case HLSL_IR_EXPR:
--
2.31.1
5
20
[PATCH] kernel32/tests: Add a test for special characters in pipe names.
by Zebediah Figura April 14, 2021
by Zebediah Figura April 14, 2021
April 14, 2021
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=28995
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/kernel32/tests/pipe.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index 0ac356c8483..1ed4ecec7e6 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -673,6 +673,14 @@ static void test_CreateNamedPipe(int pipemode)
CloseHandle(hnp);
+ hnp = CreateNamedPipeA("\\\\.\\pipe\\a<>*?|\"/b", PIPE_ACCESS_DUPLEX,
+ PIPE_TYPE_BYTE, 1, 1024, 1024, NMPWAIT_USE_DEFAULT_WAIT, NULL);
+ ok(hnp != INVALID_HANDLE_VALUE, "failed to create pipe, error %u\n", GetLastError());
+ hFile = CreateFileA("\\\\.\\pipe\\a<>*?|\"/b", 0, 0, NULL, OPEN_EXISTING, 0, 0);
+ ok(hFile != INVALID_HANDLE_VALUE, "failed to open pipe, error %u\n", GetLastError());
+ CloseHandle(hFile);
+ CloseHandle(hnp);
+
if (winetest_debug > 1) trace("test_CreateNamedPipe returning\n");
}
--
2.30.2
1
0
April 13, 2021
The Vulkan spec says:
The queueFamilyIndex member of each element of pQueueCreateInfos must be unique
within pQueueCreateInfos, except that two members can share the same
queueFamilyIndex if one is a protected-capable queue and one is not a
protected-capable queue.
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/vulkan.c | 84 ++++++++++++++++++--------------
dlls/winevulkan/vulkan_private.h | 6 ++-
2 files changed, 52 insertions(+), 38 deletions(-)
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index 45beea97240..1a3da60d664 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -316,25 +316,21 @@ static void wine_vk_free_command_buffers(struct VkDevice_T *device,
}
}
-static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
- uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags)
+static void wine_vk_device_get_queues(struct VkDevice_T *device,
+ uint32_t family_index, uint32_t queue_count, VkDeviceQueueCreateFlags flags,
+ struct VkQueue_T* queues)
{
VkDeviceQueueInfo2 queue_info;
- struct VkQueue_T *queues;
unsigned int i;
- if (!(queues = calloc(queue_count, sizeof(*queues))))
- {
- ERR("Failed to allocate memory for queues\n");
- return NULL;
- }
-
for (i = 0; i < queue_count; i++)
{
struct VkQueue_T *queue = &queues[i];
queue->base.loader_magic = VULKAN_ICD_MAGIC_VALUE;
queue->device = device;
+ queue->family_index = family_index;
+ queue->queue_index = i;
queue->flags = flags;
/* The Vulkan spec says:
@@ -358,8 +354,6 @@ static struct VkQueue_T *wine_vk_device_alloc_queues(struct VkDevice_T *device,
WINE_VK_ADD_DISPATCHABLE_MAPPING(device->phys_dev->instance, queue, queue->queue);
}
-
- return queues;
}
static void wine_vk_device_free_create_info(VkDeviceCreateInfo *create_info)
@@ -431,17 +425,19 @@ static VkResult wine_vk_device_convert_create_info(const VkDeviceCreateInfo *src
*/
static void wine_vk_device_free(struct VkDevice_T *device)
{
+ struct VkQueue_T *queue;
+
if (!device)
return;
if (device->queues)
{
unsigned int i;
- for (i = 0; i < device->max_queue_families; i++)
+ for (i = 0; i < device->queue_count; i++)
{
- if (device->queues[i] && device->queues[i]->queue)
- WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, device->queues[i]);
- free(device->queues[i]);
+ queue = &device->queues[i];
+ if (queue && queue->queue)
+ WINE_VK_REMOVE_HANDLE_MAPPING(device->phys_dev->instance, queue);
}
free(device->queues);
device->queues = NULL;
@@ -758,7 +754,7 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
const VkAllocationCallbacks *allocator, VkDevice *device)
{
VkDeviceCreateInfo create_info_host;
- uint32_t max_queue_families;
+ struct VkQueue_T *next_queue;
struct VkDevice_T *object;
unsigned int i;
VkResult res;
@@ -813,17 +809,18 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
/* We need to cache all queues within the device as each requires wrapping since queues are
* dispatchable objects.
*/
- phys_dev->instance->funcs.p_vkGetPhysicalDeviceQueueFamilyProperties(phys_dev->phys_dev,
- &max_queue_families, NULL);
- object->max_queue_families = max_queue_families;
- TRACE("Max queue families: %u.\n", object->max_queue_families);
+ for (i = 0; i < create_info_host.queueCreateInfoCount; i++)
+ {
+ object->queue_count += create_info_host.pQueueCreateInfos[i].queueCount;
+ }
- if (!(object->queues = calloc(max_queue_families, sizeof(*object->queues))))
+ if (!(object->queues = calloc(object->queue_count, sizeof(*object->queues))))
{
res = VK_ERROR_OUT_OF_HOST_MEMORY;
goto fail;
}
+ next_queue = object->queues;
for (i = 0; i < create_info_host.queueCreateInfoCount; i++)
{
uint32_t flags = create_info_host.pQueueCreateInfos[i].flags;
@@ -832,12 +829,8 @@ VkResult WINAPI wine_vkCreateDevice(VkPhysicalDevice phys_dev,
TRACE("Queue family index %u, queue count %u.\n", family_index, queue_count);
- if (!(object->queues[family_index] = wine_vk_device_alloc_queues(object, family_index, queue_count, flags)))
- {
- ERR("Failed to allocate memory for queues.\n");
- res = VK_ERROR_OUT_OF_HOST_MEMORY;
- goto fail;
- }
+ wine_vk_device_get_queues(object, family_index, queue_count, flags, next_queue);
+ next_queue += queue_count;
}
object->quirks = phys_dev->instance->quirks;
@@ -1118,17 +1111,42 @@ void WINAPI wine_vkFreeCommandBuffers(VkDevice device, VkCommandPool pool_handle
wine_vk_free_command_buffers(device, pool, count, buffers);
}
+static VkQueue wine_vk_device_find_queue(VkDevice device, const VkDeviceQueueInfo2 *info)
+{
+ struct VkQueue_T* queue;
+ uint32_t i;
+
+ for (i = 0; i < device->queue_count; i++)
+ {
+ queue = &device->queues[i];
+ if (queue->family_index == info->queueFamilyIndex
+ && queue->queue_index == info->queueIndex
+ && queue->flags == info->flags)
+ {
+ return queue;
+ }
+ }
+
+ return VK_NULL_HANDLE;
+}
+
void WINAPI wine_vkGetDeviceQueue(VkDevice device, uint32_t family_index,
uint32_t queue_index, VkQueue *queue)
{
+ VkDeviceQueueInfo2 queue_info;
TRACE("%p, %u, %u, %p\n", device, family_index, queue_index, queue);
- *queue = &device->queues[family_index][queue_index];
+ queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2;
+ queue_info.pNext = NULL;
+ queue_info.flags = 0;
+ queue_info.queueFamilyIndex = family_index;
+ queue_info.queueIndex = queue_index;
+
+ *queue = wine_vk_device_find_queue(device, &queue_info);
}
void WINAPI wine_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *info, VkQueue *queue)
{
- struct VkQueue_T *matching_queue;
const VkBaseInStructure *chain;
TRACE("%p, %p, %p\n", device, info, queue);
@@ -1136,13 +1154,7 @@ void WINAPI wine_vkGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2 *in
if ((chain = info->pNext))
FIXME("Ignoring a linked structure of type %u.\n", chain->sType);
- matching_queue = &device->queues[info->queueFamilyIndex][info->queueIndex];
- if (matching_queue->flags != info->flags)
- {
- WARN("No matching flags were specified %#x, %#x.\n", matching_queue->flags, info->flags);
- matching_queue = VK_NULL_HANDLE;
- }
- *queue = matching_queue;
+ *queue = wine_vk_device_find_queue(device, info);
}
VkResult WINAPI wine_vkQueueSubmit(VkQueue queue, uint32_t count,
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index 6574d282eea..5b0494334cd 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -89,8 +89,8 @@ struct VkDevice_T
struct VkPhysicalDevice_T *phys_dev; /* parent */
VkDevice device; /* native device */
- struct VkQueue_T **queues;
- uint32_t max_queue_families;
+ struct VkQueue_T* queues;
+ uint32_t queue_count;
unsigned int quirks;
@@ -155,6 +155,8 @@ struct VkQueue_T
struct VkDevice_T *device; /* parent */
VkQueue queue; /* native queue */
+ uint32_t family_index;
+ uint32_t queue_index;
VkDeviceQueueCreateFlags flags;
struct wine_vk_mapping mapping;
--
2.31.1
1
0
[PATCH 3/3] windows.media.devices: Stub DefaultAudio{Capture,Render}DeviceChanged events
by Andrew Eikum April 13, 2021
by Andrew Eikum April 13, 2021
April 13, 2021
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
dlls/windows.media.devices/main.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/dlls/windows.media.devices/main.c b/dlls/windows.media.devices/main.c
index 8d4c63f329a..1254ab87816 100644
--- a/dlls/windows.media.devices/main.c
+++ b/dlls/windows.media.devices/main.c
@@ -309,7 +309,10 @@ static HRESULT WINAPI media_device_statics_add_DefaultAudioCaptureDeviceChanged(
EventRegistrationToken *token)
{
FIXME("iface %p, handler %p token %p stub!\n", iface, handler, token);
- return E_NOTIMPL;
+ if(!token)
+ return E_POINTER;
+ token->value = 1;
+ return S_OK;
}
static HRESULT WINAPI media_device_statics_remove_DefaultAudioCaptureDeviceChanged(
@@ -317,7 +320,7 @@ static HRESULT WINAPI media_device_statics_remove_DefaultAudioCaptureDeviceChang
EventRegistrationToken token)
{
FIXME("iface %p, token %#I64x stub!\n", iface, token.value);
- return E_NOTIMPL;
+ return S_OK;
}
static HRESULT WINAPI media_device_statics_add_DefaultAudioRenderDeviceChanged(
@@ -326,7 +329,10 @@ static HRESULT WINAPI media_device_statics_add_DefaultAudioRenderDeviceChanged(
EventRegistrationToken *token)
{
FIXME("iface %p, handler %p token %p stub!\n", iface, handler, token);
- return E_NOTIMPL;
+ if(!token)
+ return E_POINTER;
+ token->value = 1;
+ return S_OK;
}
static HRESULT WINAPI media_device_statics_remove_DefaultAudioRenderDeviceChanged(
@@ -334,7 +340,7 @@ static HRESULT WINAPI media_device_statics_remove_DefaultAudioRenderDeviceChange
EventRegistrationToken token)
{
FIXME("iface %p, token %#I64x stub!\n", iface, token.value);
- return E_NOTIMPL;
+ return S_OK;
}
static IMediaDeviceStaticsVtbl media_device_statics_vtbl = {
--
2.31.1
1
0
[PATCH 2/3] windows.media.devices: Implement IMediaDeviceStatics::GetDefaultAudio{Capture,Render}Id
by Andrew Eikum April 13, 2021
by Andrew Eikum April 13, 2021
April 13, 2021
Signed-off-by: Andrew Eikum <aeikum(a)codeweavers.com>
---
dlls/windows.media.devices/main.c | 85 +++++++-
dlls/windows.media.devices/tests/devices.c | 223 ++++++++++++++++++++-
2 files changed, 303 insertions(+), 5 deletions(-)
diff --git a/dlls/windows.media.devices/main.c b/dlls/windows.media.devices/main.c
index 9797644d71a..8d4c63f329a 100644
--- a/dlls/windows.media.devices/main.c
+++ b/dlls/windows.media.devices/main.c
@@ -25,9 +25,11 @@
#include "winbase.h"
#include "winstring.h"
#include "wine/debug.h"
+#include "wine/heap.h"
#include "objbase.h"
#include "activation.h"
+#include "mmdeviceapi.h"
#define WIDL_using_Windows_Foundation
#define WIDL_using_Windows_Foundation_Collections
@@ -46,6 +48,16 @@ static const char *debugstr_hstring(HSTRING hstr)
return wine_dbgstr_wn(str, len);
}
+static ERole AudioDeviceRole_to_ERole(AudioDeviceRole role)
+{
+ switch(role){
+ case AudioDeviceRole_Communications:
+ return eCommunications;
+ default:
+ return eMultimedia;
+ }
+}
+
struct windows_media_devices
{
IActivationFactory IActivationFactory_iface;
@@ -151,6 +163,71 @@ static const struct IActivationFactoryVtbl activation_factory_vtbl =
windows_media_devices_ActivateInstance,
};
+static HRESULT get_default_device_id(EDataFlow direction, AudioDeviceRole role, HSTRING *device_id_hstr)
+{
+ HRESULT hr;
+ WCHAR *devid, *s;
+ IMMDevice *dev;
+ IMMDeviceEnumerator *devenum;
+ ERole mmdev_role = AudioDeviceRole_to_ERole(role);
+
+ static const WCHAR id_fmt_pre[] = L"\\\\?\\SWD#MMDEVAPI#";
+ static const WCHAR id_fmt_hash[] = L"#";
+ static const size_t GUID_STR_LEN = 38; /* == strlen("{00000000-0000-0000-0000-000000000000}") */
+
+ *device_id_hstr = NULL;
+
+ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
+ CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&devenum);
+ if (FAILED(hr))
+ {
+ WARN("Failed to create MMDeviceEnumerator: %08x\n", hr);
+ return hr;
+ }
+
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(devenum, direction, mmdev_role, &dev);
+ if (FAILED(hr))
+ {
+ WARN("GetDefaultAudioEndpoint failed: %08x\n", hr);
+ IMMDeviceEnumerator_Release(devenum);
+ return hr;
+ }
+
+ hr = IMMDevice_GetId(dev, &devid);
+ if (FAILED(hr))
+ {
+ WARN("GetId failed: %08x\n", hr);
+ IMMDevice_Release(dev);
+ IMMDeviceEnumerator_Release(devenum);
+ return hr;
+ }
+
+ s = heap_alloc((sizeof(id_fmt_pre) - sizeof(WCHAR)) +
+ (sizeof(id_fmt_hash) - sizeof(WCHAR)) +
+ (wcslen(devid) + GUID_STR_LEN + 1 /* nul */) * sizeof(WCHAR));
+
+ wcscpy(s, id_fmt_pre);
+ wcscat(s, devid);
+ wcscat(s, id_fmt_hash);
+
+ if(direction == eRender)
+ StringFromGUID2(&DEVINTERFACE_AUDIO_RENDER, s + wcslen(s), GUID_STR_LEN + 1);
+ else
+ StringFromGUID2(&DEVINTERFACE_AUDIO_CAPTURE, s + wcslen(s), GUID_STR_LEN + 1);
+
+ hr = WindowsCreateString(s, wcslen(s), device_id_hstr);
+ if (FAILED(hr))
+ WARN("WindowsCreateString failed: %08x\n", hr);
+
+ heap_free(s);
+
+ CoTaskMemFree(devid);
+ IMMDevice_Release(dev);
+ IMMDeviceEnumerator_Release(devenum);
+
+ return hr;
+}
+
static HRESULT WINAPI media_device_statics_QueryInterface(IMediaDeviceStatics *iface,
REFIID riid, void **ppvObject)
{
@@ -215,15 +292,15 @@ static HRESULT WINAPI media_device_statics_GetVideoCaptureSelector(IMediaDeviceS
static HRESULT WINAPI media_device_statics_GetDefaultAudioCaptureId(IMediaDeviceStatics *iface,
AudioDeviceRole role, HSTRING *value)
{
- FIXME("iface %p, role 0x%x, value %p stub!\n", iface, role, value);
- return E_NOTIMPL;
+ TRACE("iface %p, role 0x%x, value %p\n", iface, role, value);
+ return get_default_device_id(eCapture, role, value);
}
static HRESULT WINAPI media_device_statics_GetDefaultAudioRenderId(IMediaDeviceStatics *iface,
AudioDeviceRole role, HSTRING *value)
{
- FIXME("iface %p, role 0x%x, value %p stub!\n", iface, role, value);
- return E_NOTIMPL;
+ TRACE("iface %p, role 0x%x, value %p\n", iface, role, value);
+ return get_default_device_id(eRender, role, value);
}
static HRESULT WINAPI media_device_statics_add_DefaultAudioCaptureDeviceChanged(
diff --git a/dlls/windows.media.devices/tests/devices.c b/dlls/windows.media.devices/tests/devices.c
index 9c3019de773..f3777944848 100644
--- a/dlls/windows.media.devices/tests/devices.c
+++ b/dlls/windows.media.devices/tests/devices.c
@@ -42,6 +42,90 @@ static HRESULT (WINAPI *pRoInitialize)(RO_INIT_TYPE);
static void (WINAPI *pRoUninitialize)(void);
static HRESULT (WINAPI *pWindowsCreateString)(LPCWSTR, UINT32, HSTRING *);
static HRESULT (WINAPI *pWindowsDeleteString)(HSTRING);
+static WCHAR *(WINAPI *pWindowsGetStringRawBuffer)(HSTRING, UINT32 *);
+
+static HRESULT (WINAPI *pActivateAudioInterfaceAsync)(const WCHAR *path,
+ REFIID riid, PROPVARIANT *params,
+ IActivateAudioInterfaceCompletionHandler *done_handler,
+ IActivateAudioInterfaceAsyncOperation **op);
+
+static IMMDeviceEnumerator *g_mmdevenum;
+static WCHAR *g_default_capture_id, *g_default_render_id;
+
+static struct {
+ LONG ref;
+ HANDLE evt;
+ CRITICAL_SECTION lock;
+ IActivateAudioInterfaceAsyncOperation *op;
+ char msg_pfx[128];
+ IUnknown *result_iface;
+ HRESULT result_hr;
+} async_activate_test;
+
+static HRESULT WINAPI async_activate_QueryInterface(
+ IActivateAudioInterfaceCompletionHandler *iface,
+ REFIID riid,
+ void **ppvObject)
+{
+ if (IsEqualIID(riid, &IID_IUnknown) ||
+ IsEqualIID(riid, &IID_IAgileObject) ||
+ IsEqualIID(riid, &IID_IActivateAudioInterfaceCompletionHandler))
+ {
+ *ppvObject = iface;
+ IUnknown_AddRef((IUnknown*)*ppvObject);
+ return S_OK;
+ }
+
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI async_activate_AddRef(
+ IActivateAudioInterfaceCompletionHandler *iface)
+{
+ return InterlockedIncrement(&async_activate_test.ref);
+}
+
+static ULONG WINAPI async_activate_Release(
+ IActivateAudioInterfaceCompletionHandler *iface)
+{
+ ULONG ref = InterlockedDecrement(&async_activate_test.ref);
+ if (ref == 1)
+ SetEvent(async_activate_test.evt);
+ return ref;
+}
+
+static HRESULT WINAPI async_activate_ActivateCompleted(
+ IActivateAudioInterfaceCompletionHandler *iface,
+ IActivateAudioInterfaceAsyncOperation *op)
+{
+ HRESULT hr;
+
+ EnterCriticalSection(&async_activate_test.lock);
+ ok(op == async_activate_test.op,
+ "%s: Got different completion operation\n",
+ async_activate_test.msg_pfx);
+ LeaveCriticalSection(&async_activate_test.lock);
+
+ hr = IActivateAudioInterfaceAsyncOperation_GetActivateResult(op,
+ &async_activate_test.result_hr, &async_activate_test.result_iface);
+ ok(hr == S_OK,
+ "%s: GetActivateResult failed: %08x\n",
+ async_activate_test.msg_pfx, hr);
+
+ return S_OK;
+}
+
+static IActivateAudioInterfaceCompletionHandlerVtbl async_activate_vtbl = {
+ async_activate_QueryInterface,
+ async_activate_AddRef,
+ async_activate_Release,
+ async_activate_ActivateCompleted,
+};
+
+static IActivateAudioInterfaceCompletionHandler async_activate_done = {
+ &async_activate_vtbl
+};
static void test_MediaDeviceStatics(void)
{
@@ -51,8 +135,11 @@ static void test_MediaDeviceStatics(void)
IActivationFactory *factory = NULL;
IInspectable *inspectable = NULL, *tmp_inspectable = NULL;
IAgileObject *agile_object = NULL, *tmp_agile_object = NULL;
+ HANDLE done_evt = CreateEventW(NULL, FALSE, FALSE, NULL);
+ IMMDevice *mmdev;
HSTRING str;
HRESULT hr;
+ DWORD dr;
hr = pWindowsCreateString(media_device_statics_name, wcslen(media_device_statics_name), &str);
ok(hr == S_OK, "WindowsCreateString failed, hr %#x\n", hr);
@@ -85,13 +172,100 @@ static void test_MediaDeviceStatics(void)
IInspectable_Release(inspectable);
IActivationFactory_Release(factory);
+ InitializeCriticalSection(&async_activate_test.lock);
+
+ /* test default capture device creation */
+ hr = IMediaDeviceStatics_GetDefaultAudioCaptureId(media_device_statics, AudioDeviceRole_Default, &str);
+ ok(hr == S_OK, "GetDefaultAudioCaptureId failed: %08x\n", hr);
+ ok((!!g_default_capture_id) == (!!str),
+ "Presence of default capture device doesn't match expected state\n");
+
+ if (g_default_capture_id)
+ {
+ ok(wcsstr(pWindowsGetStringRawBuffer(str, NULL), g_default_capture_id) != NULL,
+ "Expected to find substring of default capture id in %s\n",
+ wine_dbgstr_w(pWindowsGetStringRawBuffer(str, NULL)));
+
+ /* returned id does not work in GetDevice... */
+ hr = IMMDeviceEnumerator_GetDevice(g_mmdevenum, pWindowsGetStringRawBuffer(str, NULL), &mmdev);
+ ok(hr == E_INVALIDARG, "GetDevice gave wrong error: %08x\n", hr);
+
+ /* ...but does work in ActivateAudioInterfaceAsync */
+ async_activate_test.ref = 1;
+ async_activate_test.evt = done_evt;
+ async_activate_test.op = NULL;
+ async_activate_test.result_iface = NULL;
+ async_activate_test.result_hr = 0;
+ strcpy(async_activate_test.msg_pfx, "capture_activate");
+
+ EnterCriticalSection(&async_activate_test.lock);
+ hr = pActivateAudioInterfaceAsync(pWindowsGetStringRawBuffer(str, NULL),
+ &IID_IAudioClient2, NULL, &async_activate_done, &async_activate_test.op);
+ ok(hr == S_OK, "ActivateAudioInterfaceAsync failed: %08x\n", hr);
+ LeaveCriticalSection(&async_activate_test.lock);
+
+ IActivateAudioInterfaceAsyncOperation_Release(async_activate_test.op);
+
+ dr = WaitForSingleObject(async_activate_test.evt, 1000); /* wait for all refs other than our own to be released */
+ ok(dr == WAIT_OBJECT_0, "Timed out waiting for async activate to complete\n");
+ ok(async_activate_test.result_hr == S_OK, "Got unexpected activation result: %08x\n", async_activate_test.result_hr);
+ ok(async_activate_test.result_iface != NULL, "Expected to get WASAPI interface, but got NULL\n");
+ IUnknown_Release(async_activate_test.result_iface);
+
+ pWindowsDeleteString(str);
+ }
+
+ /* test default render device creation */
+ hr = IMediaDeviceStatics_GetDefaultAudioRenderId(media_device_statics, AudioDeviceRole_Default, &str);
+ ok(hr == S_OK, "GetDefaultAudioRenderId failed: %08x\n", hr);
+ ok((!!g_default_render_id) == (!!str),
+ "Presence of default render device doesn't match expected state\n");
+
+ if (g_default_render_id)
+ {
+ ok(wcsstr(pWindowsGetStringRawBuffer(str, NULL), g_default_render_id) != NULL,
+ "Expected to find substring of default render id in %s\n",
+ wine_dbgstr_w(pWindowsGetStringRawBuffer(str, NULL)));
+
+ /* returned id does not work in GetDevice... */
+ hr = IMMDeviceEnumerator_GetDevice(g_mmdevenum, pWindowsGetStringRawBuffer(str, NULL), &mmdev);
+ ok(hr == E_INVALIDARG, "GetDevice gave wrong error: %08x\n", hr);
+
+ /* ...but does work in ActivateAudioInterfaceAsync */
+ async_activate_test.ref = 1;
+ async_activate_test.evt = done_evt;
+ async_activate_test.op = NULL;
+ async_activate_test.result_iface = NULL;
+ async_activate_test.result_hr = 0;
+ strcpy(async_activate_test.msg_pfx, "render_activate");
+
+ EnterCriticalSection(&async_activate_test.lock);
+ hr = pActivateAudioInterfaceAsync(pWindowsGetStringRawBuffer(str, NULL),
+ &IID_IAudioClient2, NULL, &async_activate_done, &async_activate_test.op);
+ ok(hr == S_OK, "ActivateAudioInterfaceAsync failed: %08x\n", hr);
+ LeaveCriticalSection(&async_activate_test.lock);
+
+ IActivateAudioInterfaceAsyncOperation_Release(async_activate_test.op);
+
+ dr = WaitForSingleObject(async_activate_test.evt, 1000); /* wait for all refs other than our own to be released */
+ ok(dr == WAIT_OBJECT_0, "Timed out waiting for async activate to complete\n");
+ ok(async_activate_test.result_hr == S_OK, "Got unexpected activation result: %08x\n", async_activate_test.result_hr);
+ ok(async_activate_test.result_iface != NULL, "Expected to get WASAPI interface, but got NULL\n");
+ IUnknown_Release(async_activate_test.result_iface);
+
+ pWindowsDeleteString(str);
+ }
+
/* cleanup */
+ CloseHandle(done_evt);
+ DeleteCriticalSection(&async_activate_test.lock);
IMediaDeviceStatics_Release(media_device_statics);
}
START_TEST(devices)
{
- HMODULE combase;
+ HMODULE combase, mmdevapi;
+ IMMDevice *mmdev;
HRESULT hr;
if (!(combase = LoadLibraryW(L"combase.dll")))
@@ -112,12 +286,59 @@ START_TEST(devices)
LOAD_FUNCPTR(RoUninitialize);
LOAD_FUNCPTR(WindowsCreateString);
LOAD_FUNCPTR(WindowsDeleteString);
+ LOAD_FUNCPTR(WindowsGetStringRawBuffer);
+#undef LOAD_FUNCPTR
+
+ if (!(mmdevapi = LoadLibraryW(L"mmdevapi.dll")))
+ {
+ win_skip("Failed to load mmdevapi.dll, skipping tests\n");
+ return;
+ }
+
+#define LOAD_FUNCPTR(x) \
+ if (!(p##x = (void*)GetProcAddress(mmdevapi, #x))) \
+ { \
+ win_skip("Failed to find %s in mmdevapi.dll, skipping tests.\n", #x); \
+ return; \
+ }
+
+ LOAD_FUNCPTR(ActivateAudioInterfaceAsync);
#undef LOAD_FUNCPTR
hr = pRoInitialize(RO_INIT_MULTITHREADED);
ok(hr == S_OK, "RoInitialize failed, hr %#x\n", hr);
+ hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL,
+ CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&g_mmdevenum);
+ ok(hr == S_OK, "Couldn't make MMDeviceEnumerator: %08x\n", hr);
+
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(g_mmdevenum, eCapture, eMultimedia, &mmdev);
+ if (hr == S_OK)
+ {
+ hr = IMMDevice_GetId(mmdev, &g_default_capture_id);
+ ok(hr == S_OK, "IMMDevice::GetId(capture) failed: %08x\n", hr);
+
+ IMMDevice_Release(mmdev);
+ }
+ if (hr != S_OK)
+ g_default_capture_id = NULL;
+
+ hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(g_mmdevenum, eRender, eMultimedia, &mmdev);
+ if (hr == S_OK)
+ {
+ hr = IMMDevice_GetId(mmdev, &g_default_render_id);
+ ok(hr == S_OK, "IMMDevice::GetId(render) failed: %08x\n", hr);
+
+ IMMDevice_Release(mmdev);
+ }
+ if (hr != S_OK)
+ g_default_render_id = NULL;
+
test_MediaDeviceStatics();
+ CoTaskMemFree(g_default_capture_id);
+ CoTaskMemFree(g_default_render_id);
+ IMMDeviceEnumerator_Release(g_mmdevenum);
+
pRoUninitialize();
}
--
2.31.1
1
0