Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- 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
June 2022
- 68 participants
- 3274 messages
[PATCH v3 2/4] d2d1/tests: Add tests for system properties attributes.
by Ziqing Hui
From: Ziqing Hui <zhui(a)codeweavers.com>
Signed-off-by: Ziqing Hui <zhui(a)codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/d2d1/tests/d2d1.c | 97 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 332fd02a07f..a43843bb8ca 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -10322,7 +10322,85 @@ static void test_mt_factory(BOOL d3d11)
ID2D1Factory_Release(factory);
}
-static void test_effect(BOOL d3d11)
+#define check_system_properties(effect, is_builtin) check_system_properties_(__LINE__, effect, is_builtin)
+static void check_system_properties_(unsigned int line, ID2D1Effect *effect, BOOL is_builtin)
+{
+ UINT i, value_size, str_size;
+ WCHAR name[32], buffer[256];
+ D2D1_PROPERTY_TYPE type;
+ HRESULT hr;
+
+ static const struct system_property_test
+ {
+ UINT32 index;
+ const WCHAR *name;
+ D2D1_PROPERTY_TYPE type;
+ UINT32 value_size;
+ }
+ system_property_tests[] =
+ {
+ {D2D1_PROPERTY_CLSID, L"CLSID", D2D1_PROPERTY_TYPE_CLSID, sizeof(CLSID)},
+ {D2D1_PROPERTY_DISPLAYNAME, L"DisplayName", D2D1_PROPERTY_TYPE_STRING },
+ {D2D1_PROPERTY_AUTHOR, L"Author", D2D1_PROPERTY_TYPE_STRING },
+ {D2D1_PROPERTY_CATEGORY, L"Category", D2D1_PROPERTY_TYPE_STRING },
+ {D2D1_PROPERTY_DESCRIPTION, L"Description", D2D1_PROPERTY_TYPE_STRING },
+ {D2D1_PROPERTY_INPUTS, L"Inputs", D2D1_PROPERTY_TYPE_ARRAY, sizeof(UINT32)},
+ {D2D1_PROPERTY_CACHED, L"Cached", D2D1_PROPERTY_TYPE_BOOL, sizeof(BOOL)},
+ {D2D1_PROPERTY_PRECISION, L"Precision", D2D1_PROPERTY_TYPE_ENUM, sizeof(UINT32)},
+ {D2D1_PROPERTY_MIN_INPUTS, L"MinInputs", D2D1_PROPERTY_TYPE_UINT32, sizeof(UINT32)},
+ {D2D1_PROPERTY_MAX_INPUTS, L"MaxInputs", D2D1_PROPERTY_TYPE_UINT32, sizeof(UINT32)},
+ };
+
+ hr = ID2D1Effect_GetPropertyName(effect, 0xdeadbeef, name, sizeof(name));
+ ok_(__FILE__, line)(hr == D2DERR_INVALID_PROPERTY, "GetPropertyName() got unexpected hr %#lx for 0xdeadbeef.\n", hr);
+ type = ID2D1Effect_GetType(effect, 0xdeadbeef);
+ ok_(__FILE__, line)(type == D2D1_PROPERTY_TYPE_UNKNOWN, "Got unexpected property type %#x for 0xdeadbeef.\n", type);
+ value_size = ID2D1Effect_GetValueSize(effect, 0xdeadbeef);
+ ok_(__FILE__, line)(value_size == 0, "Got unexpected value size %u for 0xdeadbeef.\n", value_size);
+
+ for (i = 0; i < ARRAY_SIZE(system_property_tests); ++i)
+ {
+ const struct system_property_test *test = &system_property_tests[i];
+ winetest_push_context("Property %u", i);
+
+ name[0] = 0;
+ hr = ID2D1Effect_GetPropertyName(effect, test->index, name, sizeof(name));
+ todo_wine_if((is_builtin && (test->type == D2D1_PROPERTY_TYPE_ARRAY || test->type == D2D1_PROPERTY_TYPE_STRING)))
+ {
+ ok_(__FILE__, line)(hr == S_OK, "Failed to get property name, hr %#lx\n", hr);
+ ok_(__FILE__, line)(!wcscmp(name, test->name), "Got unexpected property name %s, expected %s.\n",
+ debugstr_w(name), debugstr_w(test->name));
+ }
+
+ type = D2D1_PROPERTY_TYPE_UNKNOWN;
+ type = ID2D1Effect_GetType(effect, test->index);
+ todo_wine_if((is_builtin && (test->type == D2D1_PROPERTY_TYPE_ARRAY || test->type == D2D1_PROPERTY_TYPE_STRING)))
+ ok_(__FILE__, line)(type == test->type, "Got unexpected property type %#x, expected %#x.\n",
+ type, test->type);
+
+ value_size = 0;
+ value_size = ID2D1Effect_GetValueSize(effect, test->index);
+ if (test->value_size != 0)
+ {
+ todo_wine_if(is_builtin && test->type == D2D1_PROPERTY_TYPE_ARRAY)
+ ok_(__FILE__, line)(value_size == test->value_size, "Got unexpected value size %u, expected %u.\n",
+ value_size, test->value_size);
+ }
+ else if (test->type == D2D1_PROPERTY_TYPE_STRING)
+ {
+ hr = ID2D1Effect_GetValue(effect, test->index, D2D1_PROPERTY_TYPE_STRING, (BYTE *)buffer, sizeof(buffer));
+ todo_wine_if(is_builtin)
+ ok_(__FILE__, line)(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
+ str_size = (wcslen((WCHAR *)buffer) + 1) * sizeof(WCHAR);
+ todo_wine_if(is_builtin || buffer[0] == 0)
+ ok_(__FILE__, line)(value_size == str_size, "Got unexpected value size %u, expected %u.\n",
+ value_size, str_size);
+ }
+ winetest_pop_context();
+ }
+}
+
+static void test_builtin_effect(BOOL d3d11)
{
unsigned int i, j, min_inputs, max_inputs, str_size, input_count;
D2D1_BITMAP_PROPERTIES bitmap_desc;
@@ -10384,6 +10462,7 @@ static void test_effect(BOOL d3d11)
hr = ID2D1DeviceContext_CreateEffect(context, test->clsid, &effect);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ /* Test output image pointer */
hr = ID2D1Effect_QueryInterface(effect, &IID_ID2D1Image, (void **)&image_a);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
ID2D1Effect_GetOutput(effect, &image_b);
@@ -10391,6 +10470,7 @@ static void test_effect(BOOL d3d11)
ID2D1Image_Release(image_b);
ID2D1Image_Release(image_a);
+ /* Test GetValue() */
hr = ID2D1Effect_GetValue(effect, 0xdeadbeef, D2D1_PROPERTY_TYPE_CLSID, (BYTE *)&clsid, sizeof(clsid));
ok(hr == D2DERR_INVALID_PROPERTY, "Got unexpected hr %#lx.\n", hr);
@@ -10447,10 +10527,12 @@ static void test_effect(BOOL d3d11)
ok(max_inputs == test->max_inputs, "Got unexpected max inputs %u, expected %u.\n",
max_inputs, test->max_inputs);
+ /* Test default input count */
input_count = ID2D1Effect_GetInputCount(effect);
ok(input_count == test->default_input_count, "Got unexpected input count %u, expected %u.\n",
input_count, test->default_input_count);
+ /* Test SetInputCount() */
input_count = (test->max_inputs < 16 ? test->max_inputs : 16);
for (j = 0; j < input_count + 4; ++j)
{
@@ -10463,6 +10545,7 @@ static void test_effect(BOOL d3d11)
winetest_pop_context();
}
+ /* Test GetInput() before any input is set */
input_count = ID2D1Effect_GetInputCount(effect);
for (j = 0; j < input_count + 4; ++j)
{
@@ -10472,6 +10555,7 @@ static void test_effect(BOOL d3d11)
winetest_pop_context();
}
+ /* Test GetInput() after an input is set */
set_size_u(&size, 1, 1);
bitmap_desc.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
bitmap_desc.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
@@ -10498,6 +10582,7 @@ static void test_effect(BOOL d3d11)
winetest_pop_context();
}
+ /* Test setting inputs with out-of-bounds index */
for (j = input_count; j < input_count + 4; ++j)
{
winetest_push_context("Input %u", j);
@@ -11053,6 +11138,8 @@ static void test_effect_properties(BOOL d3d11)
hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_system_properties(effect, FALSE);
+
hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_CLSID,
D2D1_PROPERTY_TYPE_CLSID, (BYTE *)&clsid, sizeof(clsid));
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
@@ -11315,6 +11402,8 @@ static void test_effect_2d_affine(BOOL d3d11)
hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D12DAffineTransform, &effect);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_system_properties(effect, TRUE);
+
for (i = 0; i < ARRAY_SIZE(effect_2d_affine_tests); ++i)
{
const struct effect_2d_affine_test *test = &effect_2d_affine_tests[i];
@@ -11425,6 +11514,8 @@ static void test_effect_crop(BOOL d3d11)
hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Crop, &effect);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_system_properties(effect, TRUE);
+
for (i = 0; i < ARRAY_SIZE(crop_effect_tests); ++i)
{
const struct crop_effect_test *test = &crop_effect_tests[i];
@@ -11498,6 +11589,8 @@ static void test_effect_grayscale(BOOL d3d11)
hr = ID2D1DeviceContext_CreateEffect(context, &CLSID_D2D1Grayscale, &effect);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ check_system_properties(effect, TRUE);
+
for (i = 0; i < ARRAY_SIZE(test_pixels); ++i)
{
DWORD pixel = test_pixels[i];
@@ -12351,7 +12444,7 @@ START_TEST(d2d1)
queue_test(test_effect_register);
queue_test(test_effect_context);
queue_test(test_effect_properties);
- queue_test(test_effect);
+ queue_test(test_builtin_effect);
queue_test(test_effect_2d_affine);
queue_test(test_effect_crop);
queue_test(test_effect_grayscale);
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/347
June 30, 2022
[PATCH v3 1/4] d2d1/effect: Initial implementation of subproperties.
by Nikolay Sivov
From: Nikolay Sivov <nsivov(a)codeweavers.com>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/d2d1/d2d1_private.h | 8 +
dlls/d2d1/effect.c | 359 +++++++++++++++++++++++++++++++--------
dlls/d2d1/factory.c | 51 +++++-
dlls/d2d1/tests/d2d1.c | 57 ++++++-
4 files changed, 405 insertions(+), 70 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index 7e74f5dd959..db6787c2f86 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -617,10 +617,14 @@ struct d2d_effect_property
UINT32 size;
PD2D1_PROPERTY_SET_FUNCTION set_function;
PD2D1_PROPERTY_GET_FUNCTION get_function;
+ struct d2d_effect_properties *subproperties;
};
struct d2d_effect_properties
{
+ ID2D1Properties ID2D1Properties_iface;
+ struct d2d_effect *effect;
+
struct d2d_effect_property *properties;
size_t offset;
size_t size;
@@ -673,6 +677,10 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec
ID2D1Effect **effect) DECLSPEC_HIDDEN;
HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCHAR *name,
UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) DECLSPEC_HIDDEN;
+HRESULT d2d_effect_subproperties_add(struct d2d_effect_properties *props, const WCHAR *name,
+ UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value) DECLSPEC_HIDDEN;
+struct d2d_effect_property * d2d_effect_properties_get_property_by_name(
+ const struct d2d_effect_properties *properties, const WCHAR *name) DECLSPEC_HIDDEN;
void d2d_effect_properties_cleanup(struct d2d_effect_properties *props) DECLSPEC_HIDDEN;
static inline BOOL d2d_array_reserve(void **elements, size_t *capacity, size_t count, size_t size)
diff --git a/dlls/d2d1/effect.c b/dlls/d2d1/effect.c
index 7abee71e6d9..5daf16fd838 100644
--- a/dlls/d2d1/effect.c
+++ b/dlls/d2d1/effect.c
@@ -229,8 +229,8 @@ static const struct d2d_effect_info builtin_effects[] =
{&CLSID_D2D1Grayscale, 1, 1, 1},
};
-HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCHAR *name,
- UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value)
+static HRESULT d2d_effect_properties_internal_add(struct d2d_effect_properties *props,
+ const WCHAR *name, UINT32 index, BOOL subprop, D2D1_PROPERTY_TYPE type, const WCHAR *value)
{
static const UINT32 sizes[] =
{
@@ -246,7 +246,7 @@ HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCH
0, /* FIXME: D2D1_PROPERTY_TYPE_BLOB */
sizeof(void *), /* D2D1_PROPERTY_TYPE_IUNKNOWN */
sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ENUM */
- 0, /* FIXME: D2D1_PROPERTY_TYPE_ARRAY */
+ sizeof(UINT32), /* D2D1_PROPERTY_TYPE_ARRAY */
sizeof(CLSID), /* D2D1_PROPERTY_TYPE_CLSID */
6 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_3X2 */
12 * sizeof(float), /* D2D1_PROPERTY_TYPE_MATRIX_4X3 */
@@ -258,7 +258,7 @@ HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCH
assert(type >= D2D1_PROPERTY_TYPE_STRING && type <= D2D1_PROPERTY_TYPE_COLOR_CONTEXT);
- if (type == D2D1_PROPERTY_TYPE_BLOB || type == D2D1_PROPERTY_TYPE_ARRAY)
+ if (type == D2D1_PROPERTY_TYPE_BLOB)
{
FIXME("Ignoring property %s of type %u.\n", wine_dbgstr_w(name), type);
return S_OK;
@@ -279,21 +279,24 @@ HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCH
props->data.count += sizes[type];
p = &props->properties[props->count++];
+ memset(p, 0, sizeof(*p));
p->index = index;
if (p->index < 0x80000000)
{
props->custom_count++;
- /* FIXME: this should probably be controller by subproperty */
+ /* FIXME: this should probably be controlled by subproperty */
p->readonly = FALSE;
}
+ else if (subprop)
+ p->readonly = TRUE;
else
p->readonly = index != D2D1_PROPERTY_CACHED && index != D2D1_PROPERTY_PRECISION;
p->name = wcsdup(name);
p->type = type;
- if (p->type == D2D1_PROPERTY_TYPE_STRING)
+ if (p->type == D2D1_PROPERTY_TYPE_STRING && value)
{
- p->data.ptr = value ? wcsdup(value) : NULL;
- p->size = value ? (wcslen(value) + 1) * sizeof(WCHAR) : 0;
+ p->data.ptr = wcsdup(value);
+ p->size = (wcslen(value) + 1) * sizeof(WCHAR);
}
else
{
@@ -337,15 +340,26 @@ HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCH
else if (p->size)
memset(props->data.ptr + p->data.offset, 0, p->size);
}
- p->set_function = NULL;
- p->get_function = NULL;
return S_OK;
}
+HRESULT d2d_effect_properties_add(struct d2d_effect_properties *props, const WCHAR *name,
+ UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value)
+{
+ return d2d_effect_properties_internal_add(props, name, index, FALSE, type, value);
+}
+
+HRESULT d2d_effect_subproperties_add(struct d2d_effect_properties *props, const WCHAR *name,
+ UINT32 index, D2D1_PROPERTY_TYPE type, const WCHAR *value)
+{
+ return d2d_effect_properties_internal_add(props, name, index, TRUE, type, value);
+}
+
static HRESULT d2d_effect_duplicate_properties(struct d2d_effect_properties *dst,
const struct d2d_effect_properties *src)
{
+ HRESULT hr;
size_t i;
memset(dst, 0, sizeof(*dst));
@@ -372,6 +386,14 @@ static HRESULT d2d_effect_duplicate_properties(struct d2d_effect_properties *dst
d->name = wcsdup(s->name);
if (d->type == D2D1_PROPERTY_TYPE_STRING)
d->data.ptr = wcsdup((WCHAR *)s->data.ptr);
+
+ if (s->subproperties)
+ {
+ if (!(d->subproperties = calloc(1, sizeof(*d->subproperties))))
+ return E_OUTOFMEMORY;
+ if (FAILED(hr = d2d_effect_duplicate_properties(d->subproperties, s->subproperties)))
+ return hr;
+ }
}
return S_OK;
@@ -391,7 +413,7 @@ static struct d2d_effect_property * d2d_effect_properties_get_property_by_index(
return NULL;
}
-static struct d2d_effect_property * d2d_effect_properties_get_property_by_name(
+struct d2d_effect_property * d2d_effect_properties_get_property_by_name(
const struct d2d_effect_properties *properties, const WCHAR *name)
{
unsigned int i;
@@ -405,9 +427,10 @@ static struct d2d_effect_property * d2d_effect_properties_get_property_by_name(
return NULL;
}
-static UINT32 d2d_effect_properties_get_value_size(const struct d2d_effect *effect,
- const struct d2d_effect_properties *properties, UINT32 index)
+static UINT32 d2d_effect_properties_get_value_size(const struct d2d_effect_properties *properties,
+ UINT32 index)
{
+ struct d2d_effect *effect = properties->effect;
struct d2d_effect_property *prop;
UINT32 size;
@@ -432,10 +455,10 @@ static HRESULT d2d_effect_return_string(const WCHAR *str, WCHAR *buffer, UINT32
return S_OK;
}
-static HRESULT d2d_effect_property_get_value(const struct d2d_effect *effect,
- const struct d2d_effect_properties *properties, const struct d2d_effect_property *prop,
- D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 size)
+static HRESULT d2d_effect_property_get_value(const struct d2d_effect_properties *properties,
+ const struct d2d_effect_property *prop, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 size)
{
+ struct d2d_effect *effect = properties->effect;
UINT32 actual_size;
if (type != D2D1_PROPERTY_TYPE_UNKNOWN && prop->type != type) return E_INVALIDARG;
@@ -446,7 +469,6 @@ static HRESULT d2d_effect_property_get_value(const struct d2d_effect *effect,
switch (prop->type)
{
- case D2D1_PROPERTY_TYPE_ARRAY:
case D2D1_PROPERTY_TYPE_BLOB:
FIXME("Unimplemented for type %u.\n", prop->type);
return E_NOTIMPL;
@@ -460,10 +482,10 @@ static HRESULT d2d_effect_property_get_value(const struct d2d_effect *effect,
return S_OK;
}
-static HRESULT d2d_effect_property_set_value(const struct d2d_effect *effect,
- struct d2d_effect_properties *properties, struct d2d_effect_property *prop,
- D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 size)
+static HRESULT d2d_effect_property_set_value(struct d2d_effect_properties *properties,
+ struct d2d_effect_property *prop, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 size)
{
+ struct d2d_effect *effect = properties->effect;
if (prop->readonly) return E_INVALIDARG;
if (type != D2D1_PROPERTY_TYPE_UNKNOWN && prop->type != type) return E_INVALIDARG;
if (prop->get_function && !prop->set_function) return E_INVALIDARG;
@@ -499,6 +521,11 @@ void d2d_effect_properties_cleanup(struct d2d_effect_properties *props)
free(p->name);
if (p->type == D2D1_PROPERTY_TYPE_STRING)
free(p->data.ptr);
+ if (p->subproperties)
+ {
+ d2d_effect_properties_cleanup(p->subproperties);
+ free(p->subproperties);
+ }
}
free(props->properties);
free(props->data.ptr);
@@ -967,118 +994,91 @@ static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyCount(ID2D1Effect *iface)
TRACE("iface %p.\n", iface);
- return effect->properties.custom_count;
+ return ID2D1Properties_GetPropertyCount(&effect->properties.ID2D1Properties_iface);
}
static HRESULT STDMETHODCALLTYPE d2d_effect_GetPropertyName(ID2D1Effect *iface, UINT32 index,
WCHAR *name, UINT32 name_count)
{
struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- struct d2d_effect_property *prop;
TRACE("iface %p, index %u, name %p, name_count %u.\n", iface, index, name, name_count);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index)))
- return D2DERR_INVALID_PROPERTY;
-
- return d2d_effect_return_string(prop->name, name, name_count);
+ return ID2D1Properties_GetPropertyName(&effect->properties.ID2D1Properties_iface,
+ index, name, name_count);
}
static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyNameLength(ID2D1Effect *iface, UINT32 index)
{
struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- struct d2d_effect_property *prop;
TRACE("iface %p, index %u.\n", iface, index);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index)))
- return D2DERR_INVALID_PROPERTY;
-
- return wcslen(prop->name) + 1;
+ return ID2D1Properties_GetPropertyNameLength(&effect->properties.ID2D1Properties_iface, index);
}
static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_GetType(ID2D1Effect *iface, UINT32 index)
{
struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- struct d2d_effect_property *prop;
TRACE("iface %p, index %#x.\n", iface, index);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index)))
- return D2D1_PROPERTY_TYPE_UNKNOWN;
-
- return prop->type;
+ return ID2D1Properties_GetType(&effect->properties.ID2D1Properties_iface, index);
}
static UINT32 STDMETHODCALLTYPE d2d_effect_GetPropertyIndex(ID2D1Effect *iface, const WCHAR *name)
{
struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- struct d2d_effect_property *prop;
TRACE("iface %p, name %s.\n", iface, debugstr_w(name));
- if (!(prop = d2d_effect_properties_get_property_by_name(&effect->properties, name)))
- return D2D1_INVALID_PROPERTY_INDEX;
-
- return prop->index;
+ return ID2D1Properties_GetPropertyIndex(&effect->properties.ID2D1Properties_iface, name);
}
static HRESULT STDMETHODCALLTYPE d2d_effect_SetValueByName(ID2D1Effect *iface, const WCHAR *name,
D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size)
{
struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- struct d2d_effect_property *prop;
TRACE("iface %p, name %s, type %u, value %p, value_size %u.\n", iface, debugstr_w(name),
type, value, value_size);
- if (!(prop = d2d_effect_properties_get_property_by_name(&effect->properties, name)))
- return D2DERR_INVALID_PROPERTY;
-
- return d2d_effect_property_set_value(effect, &effect->properties, prop, type, value, value_size);
+ return ID2D1Properties_SetValueByName(&effect->properties.ID2D1Properties_iface, name,
+ type, value, value_size);
}
static HRESULT STDMETHODCALLTYPE d2d_effect_SetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type,
const BYTE *value, UINT32 value_size)
{
struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- struct d2d_effect_property *prop;
TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index)))
- return D2DERR_INVALID_PROPERTY;
-
- return d2d_effect_property_set_value(effect, &effect->properties, prop, type, value, value_size);
+ return ID2D1Properties_SetValue(&effect->properties.ID2D1Properties_iface, index, type,
+ value, value_size);
}
static HRESULT STDMETHODCALLTYPE d2d_effect_GetValueByName(ID2D1Effect *iface, const WCHAR *name,
D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size)
{
struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- struct d2d_effect_property *prop;
TRACE("iface %p, name %s, type %#x, value %p, value_size %u.\n", iface, debugstr_w(name), type,
value, value_size);
- if (!(prop = d2d_effect_properties_get_property_by_name(&effect->properties, name)))
- return D2DERR_INVALID_PROPERTY;
-
- return d2d_effect_property_get_value(effect, &effect->properties, prop, type, value, value_size);
+ return ID2D1Properties_GetValueByName(&effect->properties.ID2D1Properties_iface, name, type,
+ value, value_size);
}
static HRESULT STDMETHODCALLTYPE d2d_effect_GetValue(ID2D1Effect *iface, UINT32 index, D2D1_PROPERTY_TYPE type,
BYTE *value, UINT32 value_size)
{
struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- struct d2d_effect_property *prop;
TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size);
- if (!(prop = d2d_effect_properties_get_property_by_index(&effect->properties, index)))
- return D2DERR_INVALID_PROPERTY;
-
- return d2d_effect_property_get_value(effect, &effect->properties, prop, type, value, value_size);
+ return ID2D1Properties_GetValue(&effect->properties.ID2D1Properties_iface, index, type,
+ value, value_size);
}
static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT32 index)
@@ -1087,14 +1087,17 @@ static UINT32 STDMETHODCALLTYPE d2d_effect_GetValueSize(ID2D1Effect *iface, UINT
TRACE("iface %p, index %#x.\n", iface, index);
- return d2d_effect_properties_get_value_size(effect, &effect->properties, index);
+ return ID2D1Properties_GetValueSize(&effect->properties.ID2D1Properties_iface, index);
}
-static HRESULT STDMETHODCALLTYPE d2d_effect_GetSubProperties(ID2D1Effect *iface, UINT32 index, ID2D1Properties **props)
+static HRESULT STDMETHODCALLTYPE d2d_effect_GetSubProperties(ID2D1Effect *iface, UINT32 index,
+ ID2D1Properties **props)
{
- FIXME("iface %p, index %u, props %p stub!\n", iface, index, props);
+ struct d2d_effect *effect = impl_from_ID2D1Effect(iface);
- return E_NOTIMPL;
+ TRACE("iface %p, index %u, props %p.\n", iface, index, props);
+
+ return ID2D1Properties_GetSubProperties(&effect->properties.ID2D1Properties_iface, index, props);
}
static void STDMETHODCALLTYPE d2d_effect_SetInput(ID2D1Effect *iface, UINT32 index, ID2D1Image *input, BOOL invalidate)
@@ -1255,17 +1258,234 @@ static const ID2D1ImageVtbl d2d_effect_image_vtbl =
d2d_effect_image_GetFactory,
};
+static inline struct d2d_effect_properties *impl_from_ID2D1Properties(ID2D1Properties *iface)
+{
+ return CONTAINING_RECORD(iface, struct d2d_effect_properties, ID2D1Properties_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_properties_QueryInterface(ID2D1Properties *iface,
+ REFIID riid, void **obj)
+{
+ if (IsEqualGUID(riid, &IID_ID2D1Properties) ||
+ IsEqualGUID(riid, &IID_IUnknown))
+ {
+ *obj = iface;
+ ID2D1Properties_AddRef(iface);
+ return S_OK;
+ }
+
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE d2d_effect_properties_AddRef(ID2D1Properties *iface)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ return ID2D1Effect_AddRef(&properties->effect->ID2D1Effect_iface);
+}
+
+static ULONG STDMETHODCALLTYPE d2d_effect_properties_Release(ID2D1Properties *iface)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ return ID2D1Effect_Release(&properties->effect->ID2D1Effect_iface);
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyCount(ID2D1Properties *iface)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+
+ TRACE("iface %p.\n", iface);
+
+ return properties->custom_count;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetPropertyName(ID2D1Properties *iface,
+ UINT32 index, WCHAR *name, UINT32 name_count)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, index %u, name %p, name_count %u.\n", iface, index, name, name_count);
+
+ if (!(prop = d2d_effect_properties_get_property_by_index(properties, index)))
+ return D2DERR_INVALID_PROPERTY;
+
+ return d2d_effect_return_string(prop->name, name, name_count);
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyNameLength(ID2D1Properties *iface,
+ UINT32 index)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, index %u.\n", iface, index);
+
+ if (!(prop = d2d_effect_properties_get_property_by_index(properties, index)))
+ return D2DERR_INVALID_PROPERTY;
+
+ return wcslen(prop->name) + 1;
+}
+
+static D2D1_PROPERTY_TYPE STDMETHODCALLTYPE d2d_effect_properties_GetType(ID2D1Properties *iface,
+ UINT32 index)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, index %#x.\n", iface, index);
+
+ if (!(prop = d2d_effect_properties_get_property_by_index(properties, index)))
+ return D2D1_PROPERTY_TYPE_UNKNOWN;
+
+ return prop->type;
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetPropertyIndex(ID2D1Properties *iface,
+ const WCHAR *name)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, name %s.\n", iface, debugstr_w(name));
+
+ if (!(prop = d2d_effect_properties_get_property_by_name(properties, name)))
+ return D2D1_INVALID_PROPERTY_INDEX;
+
+ return prop->index;
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_properties_SetValueByName(ID2D1Properties *iface,
+ const WCHAR *name, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, name %s, type %u, value %p, value_size %u.\n", iface, debugstr_w(name),
+ type, value, value_size);
+
+ if (!(prop = d2d_effect_properties_get_property_by_name(properties, name)))
+ return D2DERR_INVALID_PROPERTY;
+
+ return d2d_effect_property_set_value(properties, prop, type, value, value_size);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_properties_SetValue(ID2D1Properties *iface,
+ UINT32 index, D2D1_PROPERTY_TYPE type, const BYTE *value, UINT32 value_size)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size);
+
+ if (!(prop = d2d_effect_properties_get_property_by_index(properties, index)))
+ return D2DERR_INVALID_PROPERTY;
+
+ return d2d_effect_property_set_value(properties, prop, type, value, value_size);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetValueByName(ID2D1Properties *iface,
+ const WCHAR *name, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, name %s, type %#x, value %p, value_size %u.\n", iface, debugstr_w(name), type,
+ value, value_size);
+
+ if (!(prop = d2d_effect_properties_get_property_by_name(properties, name)))
+ return D2DERR_INVALID_PROPERTY;
+
+ return d2d_effect_property_get_value(properties, prop, type, value, value_size);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetValue(ID2D1Properties *iface,
+ UINT32 index, D2D1_PROPERTY_TYPE type, BYTE *value, UINT32 value_size)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, index %#x, type %u, value %p, value_size %u.\n", iface, index, type, value, value_size);
+
+ if (!(prop = d2d_effect_properties_get_property_by_index(properties, index)))
+ return D2DERR_INVALID_PROPERTY;
+
+ return d2d_effect_property_get_value(properties, prop, type, value, value_size);
+}
+
+static UINT32 STDMETHODCALLTYPE d2d_effect_properties_GetValueSize(ID2D1Properties *iface,
+ UINT32 index)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+
+ TRACE("iface %p, index %#x.\n", iface, index);
+
+ return d2d_effect_properties_get_value_size(properties, index);
+}
+
+static HRESULT STDMETHODCALLTYPE d2d_effect_properties_GetSubProperties(ID2D1Properties *iface,
+ UINT32 index, ID2D1Properties **props)
+{
+ struct d2d_effect_properties *properties = impl_from_ID2D1Properties(iface);
+ struct d2d_effect_property *prop;
+
+ TRACE("iface %p, index %u, props %p.\n", iface, index, props);
+
+ if (!(prop = d2d_effect_properties_get_property_by_index(properties, index)))
+ return D2DERR_INVALID_PROPERTY;
+
+ if (!prop->subproperties) return D2DERR_NO_SUBPROPERTIES;
+
+ *props = &prop->subproperties->ID2D1Properties_iface;
+ ID2D1Properties_AddRef(*props);
+ return S_OK;
+}
+
+static const ID2D1PropertiesVtbl d2d_effect_properties_vtbl =
+{
+ d2d_effect_properties_QueryInterface,
+ d2d_effect_properties_AddRef,
+ d2d_effect_properties_Release,
+ d2d_effect_properties_GetPropertyCount,
+ d2d_effect_properties_GetPropertyName,
+ d2d_effect_properties_GetPropertyNameLength,
+ d2d_effect_properties_GetType,
+ d2d_effect_properties_GetPropertyIndex,
+ d2d_effect_properties_SetValueByName,
+ d2d_effect_properties_SetValue,
+ d2d_effect_properties_GetValueByName,
+ d2d_effect_properties_GetValue,
+ d2d_effect_properties_GetValueSize,
+ d2d_effect_properties_GetSubProperties,
+};
+
+static void d2d_effect_init_properties_vtbls(struct d2d_effect *effect)
+{
+ unsigned int i;
+
+ effect->properties.ID2D1Properties_iface.lpVtbl = &d2d_effect_properties_vtbl;
+ effect->properties.effect = effect;
+
+ for (i = 0; i < effect->properties.count; ++i)
+ {
+ struct d2d_effect_property *prop = &effect->properties.properties[i];
+ if (!prop->subproperties) continue;
+ prop->subproperties->ID2D1Properties_iface.lpVtbl = &d2d_effect_properties_vtbl;
+ prop->subproperties->effect = effect;
+ }
+}
+
HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effect_id,
ID2D1Effect **effect)
{
const struct d2d_effect_info *builtin = NULL;
struct d2d_effect_context *effect_context;
const struct d2d_effect_registration *reg;
+ unsigned int i, default_input_count;
struct d2d_transform_graph *graph;
PD2D1_EFFECT_FACTORY factory;
struct d2d_effect *object;
WCHAR clsidW[39];
- unsigned int i;
HRESULT hr;
if (!(reg = d2d_factory_get_registered_effect(context->factory, effect_id)))
@@ -1323,7 +1543,7 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec
d2d_effect_properties_add(&object->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS,
D2D1_PROPERTY_TYPE_UINT32, max_inputs);
- d2d_effect_SetInputCount(&object->ID2D1Effect_iface, builtin->default_input_count);
+ default_input_count = builtin->default_input_count;
factory = builtin_factory_stub;
}
@@ -1335,7 +1555,7 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec
d2d_effect_properties_add(&object->properties, L"MaxInputs", D2D1_PROPERTY_MAX_INPUTS,
D2D1_PROPERTY_TYPE_UINT32, L"1" /* FIXME */);
- d2d_effect_SetInputCount(&object->ID2D1Effect_iface, 1);
+ default_input_count = 1;
factory = reg->factory;
}
@@ -1343,6 +1563,9 @@ HRESULT d2d_effect_create(struct d2d_device_context *context, const CLSID *effec
d2d_effect_properties_add(&object->properties, L"CLSID", D2D1_PROPERTY_CLSID, D2D1_PROPERTY_TYPE_CLSID, clsidW);
d2d_effect_properties_add(&object->properties, L"Cached", D2D1_PROPERTY_CACHED, D2D1_PROPERTY_TYPE_BOOL, L"false");
d2d_effect_properties_add(&object->properties, L"Precision", D2D1_PROPERTY_PRECISION, D2D1_PROPERTY_TYPE_ENUM, L"0");
+ d2d_effect_init_properties_vtbls(object);
+
+ d2d_effect_SetInputCount(&object->ID2D1Effect_iface, default_input_count);
if (FAILED(hr = factory((IUnknown **)&object->impl)))
{
diff --git a/dlls/d2d1/factory.c b/dlls/d2d1/factory.c
index 911d809b58b..699b8c05669 100644
--- a/dlls/d2d1/factory.c
+++ b/dlls/d2d1/factory.c
@@ -782,6 +782,55 @@ static HRESULT parse_effect_property(IXmlReader *reader, struct d2d_effect_regis
return hr;
}
+static HRESULT parse_effect_inputs(IXmlReader *reader, struct d2d_effect_registration *effect)
+{
+ struct d2d_effect_properties *subproperties;
+ unsigned int depth, input_count = 0;
+ struct d2d_effect_property *inputs;
+ XmlNodeType node_type;
+ WCHAR nameW[16];
+ WCHAR *name;
+ HRESULT hr;
+
+ if (FAILED(hr = d2d_effect_properties_add(&effect->properties, L"Inputs",
+ D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY, NULL)))
+ return hr;
+
+ if (!(inputs = d2d_effect_properties_get_property_by_name(&effect->properties, L"Inputs")))
+ return E_FAIL;
+ if (!(inputs->subproperties = calloc(1, sizeof(*inputs->subproperties))))
+ return E_OUTOFMEMORY;
+ subproperties = inputs->subproperties;
+
+ d2d_effect_subproperties_add(subproperties, L"IsReadOnly", D2D1_SUBPROPERTY_ISREADONLY,
+ D2D1_PROPERTY_TYPE_BOOL, L"true");
+ d2d_effect_subproperties_add(subproperties, L"DisplayName", D2D1_SUBPROPERTY_DISPLAYNAME,
+ D2D1_PROPERTY_TYPE_STRING, L"Inputs");
+
+ if (IXmlReader_IsEmptyElement(reader)) return S_OK;
+
+ while (parse_effect_get_next_xml_node(reader, XmlNodeType_None, L"Input", &depth) == S_OK)
+ {
+ if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr;
+ if (node_type == XmlNodeType_EndElement) continue;
+ if (node_type != XmlNodeType_Element) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
+
+ if (FAILED(hr = parse_effect_get_attribute(reader, L"name", &name))) return hr;
+
+ swprintf(nameW, ARRAY_SIZE(nameW), L"%lu", input_count);
+ d2d_effect_subproperties_add(subproperties, nameW, input_count, D2D1_PROPERTY_TYPE_STRING, name);
+ input_count++;
+
+ free(name);
+ }
+ *(UINT32 *)(effect->properties.data.ptr + inputs->data.offset) = input_count;
+
+ if (FAILED(hr = IXmlReader_GetNodeType(reader, &node_type))) return hr;
+ if (node_type != XmlNodeType_EndElement) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
+
+ return S_OK;
+}
+
static HRESULT parse_effect_xml(IXmlReader *reader, struct d2d_effect_registration *effect)
{
const WCHAR *node_name;
@@ -808,7 +857,7 @@ static HRESULT parse_effect_xml(IXmlReader *reader, struct d2d_effect_registrati
if (!wcscmp(node_name, L"Property"))
hr = parse_effect_property(reader, effect);
else if (!wcscmp(node_name, L"Inputs"))
- hr = parse_effect_skip_element(reader, depth);
+ hr = parse_effect_inputs(reader, effect);
else
{
WARN("Unexpected element %s.\n", debugstr_w(node_name));
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 960d4480747..332fd02a07f 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -10934,12 +10934,15 @@ static void test_effect_context(BOOL d3d11)
static void test_effect_properties(BOOL d3d11)
{
- UINT32 i, min_inputs, max_inputs, integer, index;
+ UINT32 i, min_inputs, max_inputs, integer, index, size;
ID2D1EffectContext *effect_context;
D2D1_BUFFER_PRECISION precision;
+ ID2D1Properties *subproperties;
+ D2D1_PROPERTY_TYPE prop_type;
struct d2d1_test_context ctx;
ID2D1Factory1 *factory;
ID2D1Effect *effect;
+ UINT32 count, data;
WCHAR buffer[128];
CLSID clsid;
BOOL cached;
@@ -10984,6 +10987,58 @@ static void test_effect_properties(BOOL d3d11)
return;
}
+ /* Inputs array */
+ hr = ID2D1Factory1_RegisterEffectFromString(factory, &CLSID_TestEffect, effect_xml_a,
+ NULL, 0, effect_impl_create);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ hr = ID2D1DeviceContext_CreateEffect(ctx.context, &CLSID_TestEffect, &effect);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ size = ID2D1Effect_GetValueSize(effect, D2D1_PROPERTY_INPUTS);
+ ok(size == 4, "Unexpected size %u.\n", size);
+ prop_type = ID2D1Effect_GetType(effect, D2D1_PROPERTY_INPUTS);
+ ok(prop_type == D2D1_PROPERTY_TYPE_ARRAY, "Unexpected type %u.\n", prop_type);
+ hr = ID2D1Effect_GetPropertyName(effect, D2D1_PROPERTY_INPUTS, buffer, ARRAY_SIZE(buffer));
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ok(!wcscmp(buffer, L"Inputs"), "Unexpected name %s.\n", wine_dbgstr_w(buffer));
+
+ /* Value is the number of elements. */
+ data = 123;
+ hr = ID2D1Effect_GetValue(effect, D2D1_PROPERTY_INPUTS, D2D1_PROPERTY_TYPE_ARRAY,
+ (BYTE *)&data, sizeof(data));
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ok(data == 1, "Unexpected data %u.\n", data);
+
+ hr = ID2D1Effect_GetSubProperties(effect, D2D1_PROPERTY_INPUTS, &subproperties);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ count = ID2D1Properties_GetPropertyCount(subproperties);
+ ok(count == 1, "Unexpected count %u.\n", count);
+
+ hr = ID2D1Properties_GetPropertyName(subproperties, 0, buffer, ARRAY_SIZE(buffer));
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ok(!wcscmp(buffer, L"0"), "Unexpected name %s.\n", wine_dbgstr_w(buffer));
+ hr = ID2D1Properties_GetValue(subproperties, 0, D2D1_PROPERTY_TYPE_STRING,
+ (BYTE *)buffer, sizeof(buffer));
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ok(!wcscmp(buffer, L"Source"), "Unexpected value %s.\n", wine_dbgstr_w(buffer));
+
+ hr = ID2D1Properties_GetValue(subproperties, D2D1_SUBPROPERTY_ISREADONLY, D2D1_PROPERTY_TYPE_BOOL,
+ (BYTE *)&data, sizeof(data));
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ok(data == TRUE, "Unexpected value %u.\n", data);
+ hr = ID2D1Properties_GetPropertyName(subproperties, D2D1_SUBPROPERTY_ISREADONLY,
+ buffer, ARRAY_SIZE(buffer));
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ok(!wcscmp(buffer, L"IsReadOnly"), "Unexpected name %s.\n", wine_dbgstr_w(buffer));
+
+ ID2D1Properties_Release(subproperties);
+ ID2D1Effect_Release(effect);
+
+ hr = ID2D1Factory1_UnregisterEffect(factory, &CLSID_TestEffect);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
/* Test system properties */
for (i = 0; i < ARRAY_SIZE(system_property_tests); ++i)
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/347
June 30, 2022
[PATCH v3 0/4] MR347: d2d1/effect: Initial implementation of subproperties.
by Nikolay Sivov (@nsivov)
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
--
v3: d2d1/tests: Test value size checking for custom properties.
d2d1/tests: Add tests for GetPropertyCount().
d2d1/tests: Add tests for system properties attributes.
d2d1/effect: Initial implementation of subproperties.
https://gitlab.winehq.org/wine/wine/-/merge_requests/347
June 30, 2022
Re: [PATCH v3 0/2] MR89: Use +threadname channel for thread names. - approved
by Alexandre Julliard (@julliard)
This merge request was approved by Alexandre Julliard.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/89
June 30, 2022
Re: [PATCH v3 0/4] MR345: evr: Release buffer after adding it to sample. - approved
by Alexandre Julliard (@julliard)
This merge request was approved by Alexandre Julliard.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/345
June 30, 2022
Re: [PATCH v4 0/6] MR336: light.msstyles: Add Vista+ tab parts. - approved
by Alexandre Julliard (@julliard)
This merge request was approved by Alexandre Julliard.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/336
June 30, 2022
Re: [PATCH v4 0/4] MR322: winex11.drv: Preparation for nulldrv display modes. - approved
by Alexandre Julliard (@julliard)
This merge request was approved by Alexandre Julliard.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/322
June 30, 2022
Re: [PATCH v5 0/4] MR313: win32u: Finish moving raw input APIs. - approved
by Alexandre Julliard (@julliard)
This merge request was approved by Alexandre Julliard.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/313
June 30, 2022
Re: [PATCH v3 0/2] MR337: winepulse: Return device-specific values for GetMixFormat and GetDevicePeriod
by Huw Davies (@huw)
I’m still not convinced we need two more unix calls, but I’m looking at this on a phone while out this week, but perhaps I’ll be more persuaded when I see the changes properly next week.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/337#note_3067
June 30, 2022
[PATCH 3/3] loader/wine.inf: Add runas shell execute verb.
by Paul Gofman
From: Paul Gofman <pgofman(a)codeweavers.com>
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/shell32/tests/shlexec.c | 24 ++++++++++++++++++++++++
loader/wine.inf.in | 1 +
2 files changed, 25 insertions(+)
diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c
index 4af4d735b68..5096eef380f 100644
--- a/dlls/shell32/tests/shlexec.c
+++ b/dlls/shell32/tests/shlexec.c
@@ -54,6 +54,7 @@ static DLLVERSIONINFO dllver;
static BOOL skip_shlexec_tests = FALSE;
static BOOL skip_noassoc_tests = FALSE;
static HANDLE dde_ready_event;
+static BOOL is_elevated;
/***
@@ -2257,6 +2258,19 @@ static void test_exes(void)
skip("Could not create associtation.\n");
}
+ if (is_elevated)
+ {
+ rc = shell_execute_ex(SEE_MASK_NOZONECHECKS | SEE_MASK_CLASSNAME | SEE_MASK_FLAG_NO_UI, "runas", argv0, params,
+ NULL, ".exe");
+ okShell(rc > 32, "returned %Iu\n", rc);
+ okChildInt("argcA", 4);
+ okChildString("argvA3", "Exec");
+ }
+ else
+ {
+ skip("No admin privileges, skipping runas test.\n");
+ }
+
if (! skip_noassoc_tests)
{
sprintf(filename, "%s\\test file.noassoc", tmpdir);
@@ -2698,6 +2712,9 @@ static void init_test(void)
lnk_desc_t desc;
DWORD rc;
HRESULT r;
+ TOKEN_ELEVATION elevation;
+ HANDLE token;
+ BOOL ret;
hdll=GetModuleHandleA("shell32.dll");
pDllGetVersion=(void*)GetProcAddress(hdll, "DllGetVersion");
@@ -2822,6 +2839,13 @@ static void init_test(void)
/* Set an environment variable to see if it is inherited */
SetEnvironmentVariableA("ShlexecVar", "Present");
+
+ ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
+ ok(ret, "OpenProcessToken failed.\n");
+ ret = GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &rc);
+ ok(ret, "GetTokenInformation failed.\n");
+ is_elevated = elevation.TokenIsElevated;
+ CloseHandle(token);
}
static void cleanup_test(void)
diff --git a/loader/wine.inf.in b/loader/wine.inf.in
index 58283e271de..e7b435ed0f0 100644
--- a/loader/wine.inf.in
+++ b/loader/wine.inf.in
@@ -272,6 +272,7 @@ HKCR,DirectShow,,16
HKCR,exefile,,2,"Application"
HKCR,exefile\DefaultIcon,,2,"%1"
HKCR,exefile\shell\open\command,,2,"""%1"" %*"
+HKCR,exefile\shell\runas\command,,2,"""%1"" %*"
HKCR,folder\shell\open\ddeexec,,2,"[ViewFolder("%l", %I, %S)]"
HKCR,folder\shell\open\ddeexec,"NoActivateHandler",2,""
HKCR,folder\shell\open\ddeexec\application,,2,"Folders"
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/353
June 30, 2022