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
December 2019
- 73 participants
- 1394 messages
Re: [PATCH] ddraw/tests: Skip test_colorkey_precision() test on WARP.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 2, 2019
Re: [PATCH] dxgi/tests: Fix a typo in ok() message.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 2, 2019
Re: [PATCH v2 5/6] ddraw: Retrieve render state from the primary stateblock.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 2, 2019
Re: [PATCH v2 4/6] d3d8: Use wined3d_stateblock_get_state() in d3d8_device_GetRenderState().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 2, 2019
Re: [PATCH v2 3/6] d3d9: Use wined3d_stateblock_get_state() in d3d9_device_GetRenderState().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 2, 2019
[PATCH] testbot: Validate VM names and add UntaintName().
by Francois Gouget
This prevents discrepencies between the VM creation interface and
LibvirtTool's validation of VM names.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/LibvirtTool.pl | 23 +++++++++++++----------
testbot/lib/WineTestBot/VMs.pm | 17 +++++++++++++++++
2 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/testbot/bin/LibvirtTool.pl b/testbot/bin/LibvirtTool.pl
index bc45533d2..e5dc8372e 100755
--- a/testbot/bin/LibvirtTool.pl
+++ b/testbot/bin/LibvirtTool.pl
@@ -118,20 +118,23 @@ if (!defined $Usage)
Error "you must specify the VM name\n";
$Usage = 2;
}
- elsif ($VMKey =~ /^([a-zA-Z0-9_]+)$/)
+ else
{
- $VMKey = $1; # untaint
- $VM = CreateVMs()->GetItem($VMKey);
- if (!defined $VM)
+ $VMKey = WineTestBot::VM::UntaintName($VMKey);
+ if (!defined $VMKey)
{
- Error "VM $VMKey does not exist\n";
+ Error "'$VMKey' is not a valid VM name\n";
$Usage = 2;
}
- }
- else
- {
- Error "'$VMKey' is not a valid VM name\n";
- $Usage = 2;
+ else
+ {
+ $VM = CreateVMs()->GetItem($VMKey);
+ if (!defined $VM)
+ {
+ Error "VM $VMKey does not exist\n";
+ $Usage = 2;
+ }
+ }
}
}
if (defined $Usage)
diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm
index 279b7bccd..2f4b70362 100644
--- a/testbot/lib/WineTestBot/VMs.pm
+++ b/testbot/lib/WineTestBot/VMs.pm
@@ -320,10 +320,27 @@ my $_SupportedMissions = {
"wine" => { "win32" => 1, "wow32" => 1, "wow64" => 1 },
};
+sub UntaintName($)
+{
+ my ($VMName) = @_;
+
+ return undef if (!defined $VMName);
+ $VMName =~ /^([a-zA-Z0-9_]+)$/;
+ return $1;
+}
+
sub Validate($)
{
my ($self) = @_;
+ if (!defined $self->Name)
+ {
+ return ("Name", "The name must be set");
+ }
+ if (!defined UntaintName($self->Name))
+ {
+ return ("Name", "The name '". $self->Name ."' contains invalid characters");
+ }
if ($self->Type !~ /^(?:win32|win64|wine)$/ and
$self->Role =~ /^(?:extra|winetest)$/)
{
--
2.20.1
Dec. 2, 2019
[PATCH 3/3] dwrite: Update to IDWriteFactory7 stub.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/main.c | 528 +++++++++++++++++++++------------------
dlls/dwrite/tests/font.c | 11 +-
2 files changed, 301 insertions(+), 238 deletions(-)
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 7b97d77bd1..033a664dcf 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -34,8 +34,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
-static IDWriteFactory5 *shared_factory;
-static void release_shared_factory(IDWriteFactory5*);
+static IDWriteFactory7 *shared_factory;
+static void release_shared_factory(IDWriteFactory7 *factory);
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
{
@@ -549,8 +549,8 @@ struct fileloader
struct dwritefactory
{
- IDWriteFactory5 IDWriteFactory5_iface;
- LONG ref;
+ IDWriteFactory7 IDWriteFactory7_iface;
+ LONG refcount;
IDWriteFontCollection1 *system_collection;
IDWriteFontCollection1 *eudc_collection;
@@ -566,9 +566,9 @@ struct dwritefactory
CRITICAL_SECTION cs;
};
-static inline struct dwritefactory *impl_from_IDWriteFactory5(IDWriteFactory5 *iface)
+static inline struct dwritefactory *impl_from_IDWriteFactory7(IDWriteFactory7 *iface)
{
- return CONTAINING_RECORD(iface, struct dwritefactory, IDWriteFactory5_iface);
+ return CONTAINING_RECORD(iface, struct dwritefactory, IDWriteFactory7_iface);
}
static void release_fontface_cache(struct list *fontfaces)
@@ -620,11 +620,11 @@ static void release_dwritefactory(struct dwritefactory *factory)
heap_free(factory);
}
-static void release_shared_factory(IDWriteFactory5 *iface)
+static void release_shared_factory(IDWriteFactory7 *iface)
{
struct dwritefactory *factory;
if (!iface) return;
- factory = impl_from_IDWriteFactory5(iface);
+ factory = impl_from_IDWriteFactory7(iface);
release_dwritefactory(factory);
}
@@ -667,7 +667,8 @@ static IDWriteFontCollection1 *factory_get_system_collection(struct dwritefactor
return factory->system_collection;
}
- if (FAILED(hr = get_system_fontcollection(&factory->IDWriteFactory5_iface, &collection))) {
+ if (FAILED(hr = get_system_fontcollection((IDWriteFactory5 *)&factory->IDWriteFactory7_iface, &collection)))
+ {
WARN("Failed to create system font collection, hr %#x.\n", hr);
return NULL;
}
@@ -678,13 +679,13 @@ static IDWriteFontCollection1 *factory_get_system_collection(struct dwritefactor
return factory->system_collection;
}
-static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory5 *iface, REFIID riid, void **obj)
+static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory7 *iface, REFIID riid, void **obj)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
- TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
-
- if (IsEqualIID(riid, &IID_IDWriteFactory5) ||
+ if (IsEqualIID(riid, &IID_IDWriteFactory7) ||
+ IsEqualIID(riid, &IID_IDWriteFactory6) ||
+ IsEqualIID(riid, &IID_IDWriteFactory5) ||
IsEqualIID(riid, &IID_IDWriteFactory4) ||
IsEqualIID(riid, &IID_IDWriteFactory3) ||
IsEqualIID(riid, &IID_IDWriteFactory2) ||
@@ -693,7 +694,7 @@ static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory5 *iface, REFII
IsEqualIID(riid, &IID_IUnknown))
{
*obj = iface;
- IDWriteFactory5_AddRef(iface);
+ IDWriteFactory7_AddRef(iface);
return S_OK;
}
@@ -702,75 +703,77 @@ static HRESULT WINAPI dwritefactory_QueryInterface(IDWriteFactory5 *iface, REFII
return E_NOINTERFACE;
}
-static ULONG WINAPI dwritefactory_AddRef(IDWriteFactory5 *iface)
+static ULONG WINAPI dwritefactory_AddRef(IDWriteFactory7 *iface)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
- TRACE("(%p)->(%d)\n", This, ref);
- return ref;
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
+ ULONG refcount = InterlockedIncrement(&factory->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
}
-static ULONG WINAPI dwritefactory_Release(IDWriteFactory5 *iface)
+static ULONG WINAPI dwritefactory_Release(IDWriteFactory7 *iface)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
+ ULONG refcount = InterlockedDecrement(&factory->refcount);
- TRACE("(%p)->(%d)\n", This, ref);
+ TRACE("%p, refcount %u.\n", iface, refcount);
- if (!ref)
- release_dwritefactory(This);
+ if (!refcount)
+ release_dwritefactory(factory);
- return ref;
+ return refcount;
}
-static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory5 *iface,
+static HRESULT WINAPI dwritefactory_GetSystemFontCollection(IDWriteFactory7 *iface,
IDWriteFontCollection **collection, BOOL check_for_updates)
{
- return IDWriteFactory5_GetSystemFontCollection(iface, FALSE, (IDWriteFontCollection1 **)collection,
+ return IDWriteFactory5_GetSystemFontCollection((IDWriteFactory5 *)iface, FALSE, (IDWriteFontCollection1 **)collection,
check_for_updates);
}
-static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory5 *iface,
+static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory7 *iface,
IDWriteFontCollectionLoader *loader, void const *key, UINT32 key_size, IDWriteFontCollection **collection)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
IDWriteFontFileEnumerator *enumerator;
struct collectionloader *found;
HRESULT hr;
- TRACE("(%p)->(%p %p %u %p)\n", This, loader, key, key_size, collection);
+ TRACE("%p, %p, %p, %u, %p.\n", iface, loader, key, key_size, collection);
*collection = NULL;
if (!loader)
return E_INVALIDARG;
- found = factory_get_collection_loader(This, loader);
+ found = factory_get_collection_loader(factory, loader);
if (!found)
return E_INVALIDARG;
- hr = IDWriteFontCollectionLoader_CreateEnumeratorFromKey(found->loader, (IDWriteFactory*)iface,
+ hr = IDWriteFontCollectionLoader_CreateEnumeratorFromKey(found->loader, (IDWriteFactory *)iface,
key, key_size, &enumerator);
if (FAILED(hr))
return hr;
- hr = create_font_collection(iface, enumerator, FALSE, (IDWriteFontCollection3 **)collection);
+ hr = create_font_collection((IDWriteFactory5 *)iface, enumerator, FALSE, (IDWriteFontCollection3 **)collection);
IDWriteFontFileEnumerator_Release(enumerator);
return hr;
}
-static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory5 *iface,
+static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory7 *iface,
IDWriteFontCollectionLoader *loader)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
struct collectionloader *entry;
- TRACE("(%p)->(%p)\n", This, loader);
+ TRACE("%p, %p.\n", iface, loader);
if (!loader)
return E_INVALIDARG;
- if (factory_get_collection_loader(This, loader))
+ if (factory_get_collection_loader(factory, loader))
return DWRITE_E_ALREADYREGISTERED;
entry = heap_alloc(sizeof(*entry));
@@ -779,23 +782,23 @@ static HRESULT WINAPI dwritefactory_RegisterFontCollectionLoader(IDWriteFactory5
entry->loader = loader;
IDWriteFontCollectionLoader_AddRef(loader);
- list_add_tail(&This->collection_loaders, &entry->entry);
+ list_add_tail(&factory->collection_loaders, &entry->entry);
return S_OK;
}
-static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory5 *iface,
+static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactory7 *iface,
IDWriteFontCollectionLoader *loader)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
struct collectionloader *found;
- TRACE("(%p)->(%p)\n", This, loader);
+ TRACE("%p, %p.\n", iface, loader);
if (!loader)
return E_INVALIDARG;
- found = factory_get_collection_loader(This, loader);
+ found = factory_get_collection_loader(factory, loader);
if (!found)
return E_INVALIDARG;
@@ -806,15 +809,15 @@ static HRESULT WINAPI dwritefactory_UnregisterFontCollectionLoader(IDWriteFactor
return S_OK;
}
-static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory5 *iface,
+static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory7 *iface,
WCHAR const *path, FILETIME const *writetime, IDWriteFontFile **font_file)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
UINT32 key_size;
HRESULT hr;
void *key;
- TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(path), writetime, font_file);
+ TRACE("%p, %s, %p, %p.\n", iface, debugstr_w(path), writetime, font_file);
*font_file = NULL;
@@ -823,22 +826,22 @@ static HRESULT WINAPI dwritefactory_CreateFontFileReference(IDWriteFactory5 *ifa
if (FAILED(hr))
return hr;
- hr = create_font_file(This->localfontfileloader, key, key_size, font_file);
+ hr = create_font_file(factory->localfontfileloader, key, key_size, font_file);
heap_free(key);
return hr;
}
-static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory5 *iface,
+static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory7 *iface,
void const *reference_key, UINT32 key_size, IDWriteFontFileLoader *loader, IDWriteFontFile **font_file)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
- TRACE("(%p)->(%p %u %p %p)\n", This, reference_key, key_size, loader, font_file);
+ TRACE("%p, %p, %u, %p, %p.\n", iface, reference_key, key_size, loader, font_file);
*font_file = NULL;
- if (!loader || !(factory_get_file_loader(This, loader) || This->localfontfileloader == loader))
+ if (!loader || !(factory_get_file_loader(factory, loader) || factory->localfontfileloader == loader))
return E_INVALIDARG;
return create_font_file(loader, reference_key, key_size, font_file);
@@ -846,20 +849,20 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory
void factory_lock(IDWriteFactory5 *iface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
EnterCriticalSection(&factory->cs);
}
void factory_unlock(IDWriteFactory5 *iface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
LeaveCriticalSection(&factory->cs);
}
HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * const *font_files, UINT32 index,
DWRITE_FONT_SIMULATIONS simulations, struct list **cached_list, REFIID riid, void **obj)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
struct fontfacecached *cached;
IDWriteFontFileLoader *loader;
struct list *fontfaces;
@@ -935,7 +938,7 @@ HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * co
struct fontfacecached *factory_cache_fontface(IDWriteFactory5 *iface, struct list *fontfaces,
IDWriteFontFace5 *fontface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
struct fontfacecached *cached;
/* new cache entry */
@@ -951,11 +954,10 @@ struct fontfacecached *factory_cache_fontface(IDWriteFactory5 *iface, struct lis
return cached;
}
-static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory5 *iface, DWRITE_FONT_FACE_TYPE req_facetype,
+static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory7 *iface, DWRITE_FONT_FACE_TYPE req_facetype,
UINT32 files_number, IDWriteFontFile* const* font_files, UINT32 index, DWRITE_FONT_SIMULATIONS simulations,
IDWriteFontFace **fontface)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
DWRITE_FONT_FILE_TYPE file_type;
DWRITE_FONT_FACE_TYPE face_type;
IDWriteFontFileStream *stream;
@@ -965,7 +967,7 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory5 *iface, DWRIT
UINT32 face_count;
HRESULT hr;
- TRACE("(%p)->(%d %u %p %u 0x%x %p)\n", This, req_facetype, files_number, font_files, index,
+ TRACE("%p, %d, %u, %p, %u, %#x, %p.\n", iface, req_facetype, files_number, font_files, index,
simulations, fontface);
*fontface = NULL;
@@ -999,12 +1001,12 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory5 *iface, DWRIT
goto failed;
}
- hr = factory_get_cached_fontface(iface, font_files, index, simulations, &fontfaces,
+ hr = factory_get_cached_fontface((IDWriteFactory5 *)iface, font_files, index, simulations, &fontfaces,
&IID_IDWriteFontFace, (void **)fontface);
if (hr != S_FALSE)
goto failed;
- desc.factory = iface;
+ desc.factory = (IDWriteFactory5 *)iface;
desc.face_type = req_facetype;
desc.files = font_files;
desc.stream = stream;
@@ -1019,71 +1021,68 @@ failed:
return hr;
}
-static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory5 *iface, IDWriteRenderingParams **params)
+static HRESULT WINAPI dwritefactory_CreateRenderingParams(IDWriteFactory7 *iface, IDWriteRenderingParams **params)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
HMONITOR monitor;
POINT pt;
- TRACE("(%p)->(%p)\n", This, params);
+ TRACE("%p, %p.\n", iface, params);
pt.x = pt.y = 0;
monitor = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
- return IDWriteFactory5_CreateMonitorRenderingParams(iface, monitor, params);
+ return IDWriteFactory7_CreateMonitorRenderingParams(iface, monitor, params);
}
-static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory5 *iface, HMONITOR monitor,
+static HRESULT WINAPI dwritefactory_CreateMonitorRenderingParams(IDWriteFactory7 *iface, HMONITOR monitor,
IDWriteRenderingParams **params)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
IDWriteRenderingParams3 *params3;
static int fixme_once = 0;
HRESULT hr;
- TRACE("(%p)->(%p %p)\n", This, monitor, params);
+ TRACE("%p, %p, %p.\n", iface, monitor, params);
if (!fixme_once++)
FIXME("(%p): monitor setting ignored\n", monitor);
/* FIXME: use actual per-monitor gamma factor */
- hr = IDWriteFactory5_CreateCustomRenderingParams(iface, 2.0f, 0.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT,
+ hr = IDWriteFactory7_CreateCustomRenderingParams(iface, 2.0f, 0.0f, 1.0f, 0.0f, DWRITE_PIXEL_GEOMETRY_FLAT,
DWRITE_RENDERING_MODE1_DEFAULT, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3);
*params = (IDWriteRenderingParams*)params3;
return hr;
}
-static HRESULT WINAPI dwritefactory_CreateCustomRenderingParams(IDWriteFactory5 *iface, FLOAT gamma,
+static HRESULT WINAPI dwritefactory_CreateCustomRenderingParams(IDWriteFactory7 *iface, FLOAT gamma,
FLOAT enhancedContrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode,
IDWriteRenderingParams **params)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
IDWriteRenderingParams3 *params3;
HRESULT hr;
- TRACE("(%p)->(%f %f %f %d %d %p)\n", This, gamma, enhancedContrast, cleartype_level, geometry, mode, params);
+ TRACE("%p, %.8e, %.8e, %.8e, %d, %d, %p.\n", iface, gamma, enhancedContrast, cleartype_level, geometry, mode, params);
if ((UINT32)mode > DWRITE_RENDERING_MODE_OUTLINE) {
*params = NULL;
return E_INVALIDARG;
}
- hr = IDWriteFactory5_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0f, cleartype_level, geometry,
+ hr = IDWriteFactory7_CreateCustomRenderingParams(iface, gamma, enhancedContrast, 1.0f, cleartype_level, geometry,
(DWRITE_RENDERING_MODE1)mode, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3);
*params = (IDWriteRenderingParams*)params3;
return hr;
}
-static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory5 *iface, IDWriteFontFileLoader *loader)
+static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory7 *iface, IDWriteFontFileLoader *loader)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
struct fileloader *entry;
- TRACE("(%p)->(%p)\n", This, loader);
+ TRACE("%p, %p.\n", iface, loader);
if (!loader)
return E_INVALIDARG;
- if (factory_get_file_loader(This, loader))
+ if (factory_get_file_loader(factory, loader))
return DWRITE_E_ALREADYREGISTERED;
entry = heap_alloc(sizeof(*entry));
@@ -1093,22 +1092,22 @@ static HRESULT WINAPI dwritefactory_RegisterFontFileLoader(IDWriteFactory5 *ifac
entry->loader = loader;
list_init(&entry->fontfaces);
IDWriteFontFileLoader_AddRef(loader);
- list_add_tail(&This->file_loaders, &entry->entry);
+ list_add_tail(&factory->file_loaders, &entry->entry);
return S_OK;
}
-static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory5 *iface, IDWriteFontFileLoader *loader)
+static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory7 *iface, IDWriteFontFileLoader *loader)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
struct fileloader *found;
- TRACE("(%p)->(%p)\n", This, loader);
+ TRACE("%p, %p.\n", iface, loader);
if (!loader)
return E_INVALIDARG;
- found = factory_get_file_loader(This, loader);
+ found = factory_get_file_loader(factory, loader);
if (!found)
return E_INVALIDARG;
@@ -1116,20 +1115,20 @@ static HRESULT WINAPI dwritefactory_UnregisterFontFileLoader(IDWriteFactory5 *if
return S_OK;
}
-static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory5 *iface, WCHAR const* family_name,
+static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory7 *iface, WCHAR const* family_name,
IDWriteFontCollection *collection, DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style,
DWRITE_FONT_STRETCH stretch, FLOAT size, WCHAR const *locale, IDWriteTextFormat **format)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
HRESULT hr;
- TRACE("(%p)->(%s %p %d %d %d %f %s %p)\n", This, debugstr_w(family_name), collection, weight, style, stretch,
+ TRACE("%p, %s, %p, %d, %d, %d, %.8e, %s, %p.\n", iface, debugstr_w(family_name), collection, weight, style, stretch,
size, debugstr_w(locale), format);
if (collection)
IDWriteFontCollection_AddRef(collection);
else {
- collection = (IDWriteFontCollection *)factory_get_system_collection(This);
+ collection = (IDWriteFontCollection *)factory_get_system_collection(factory);
if (!collection) {
*format = NULL;
return E_FAIL;
@@ -1141,39 +1140,38 @@ static HRESULT WINAPI dwritefactory_CreateTextFormat(IDWriteFactory5 *iface, WCH
return hr;
}
-static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory5 *iface, IDWriteTypography **typography)
+static HRESULT WINAPI dwritefactory_CreateTypography(IDWriteFactory7 *iface, IDWriteTypography **typography)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
- TRACE("(%p)->(%p)\n", This, typography);
+ TRACE("%p, %p.\n", iface, typography);
+
return create_typography(typography);
}
-static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory5 *iface, IDWriteGdiInterop **gdi_interop)
+static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory7 *iface, IDWriteGdiInterop **gdi_interop)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
HRESULT hr = S_OK;
- TRACE("(%p)->(%p)\n", This, gdi_interop);
+ TRACE("%p, %p.\n", iface, gdi_interop);
- if (This->gdiinterop)
- IDWriteGdiInterop1_AddRef(This->gdiinterop);
+ if (factory->gdiinterop)
+ IDWriteGdiInterop1_AddRef(factory->gdiinterop);
else
- hr = create_gdiinterop(iface, &This->gdiinterop);
+ hr = create_gdiinterop((IDWriteFactory5 *)iface, &factory->gdiinterop);
- *gdi_interop = (IDWriteGdiInterop *)This->gdiinterop;
+ *gdi_interop = (IDWriteGdiInterop *)factory->gdiinterop;
return hr;
}
-static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory5 *iface, WCHAR const* string,
+static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory7 *iface, WCHAR const* string,
UINT32 length, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, IDWriteTextLayout **layout)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
struct textlayout_desc desc;
- TRACE("(%p)->(%s:%u %p %f %f %p)\n", This, debugstr_wn(string, length), length, format, max_width, max_height, layout);
+ TRACE("%p, %s:%u, %p, %.8e, %.8e, %p.\n", iface, debugstr_wn(string, length), length, format, max_width, max_height, layout);
- desc.factory = iface;
+ desc.factory = (IDWriteFactory5 *)iface;
desc.string = string;
desc.length = length;
desc.format = format;
@@ -1186,17 +1184,16 @@ static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory5 *iface, WCH
return create_textlayout(&desc, layout);
}
-static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory5 *iface, WCHAR const* string,
+static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory7 *iface, WCHAR const* string,
UINT32 length, IDWriteTextFormat *format, FLOAT max_width, FLOAT max_height, FLOAT pixels_per_dip,
DWRITE_MATRIX const* transform, BOOL use_gdi_natural, IDWriteTextLayout **layout)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
struct textlayout_desc desc;
- TRACE("(%p)->(%s:%u %p %f %f %f %p %d %p)\n", This, debugstr_wn(string, length), length, format, max_width,
- max_height, pixels_per_dip, transform, use_gdi_natural, layout);
+ TRACE("%p, %s:%u, %p, %.8e, %.8e, %.8e, %p, %d, %p.\n", iface, debugstr_wn(string, length), length, format,
+ max_width, max_height, pixels_per_dip, transform, use_gdi_natural, layout);
- desc.factory = iface;
+ desc.factory = (IDWriteFactory5 *)iface;
desc.string = string;
desc.length = length;
desc.format = format;
@@ -1209,31 +1206,29 @@ static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory
return create_textlayout(&desc, layout);
}
-static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory5 *iface, IDWriteTextFormat *format,
+static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory7 *iface, IDWriteTextFormat *format,
IDWriteInlineObject **trimming_sign)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
- TRACE("(%p)->(%p %p)\n", This, format, trimming_sign);
- return create_trimmingsign(iface, format, trimming_sign);
+ TRACE("%p, %p, %p.\n", iface, format, trimming_sign);
+
+ return create_trimmingsign((IDWriteFactory5 *)iface, format, trimming_sign);
}
-static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory5 *iface, IDWriteTextAnalyzer **analyzer)
+static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory7 *iface, IDWriteTextAnalyzer **analyzer)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- TRACE("(%p)->(%p)\n", This, analyzer);
+ TRACE("%p, %p.\n", iface, analyzer);
*analyzer = get_text_analyzer();
return S_OK;
}
-static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory5 *iface,
+static HRESULT WINAPI dwritefactory_CreateNumberSubstitution(IDWriteFactory7 *iface,
DWRITE_NUMBER_SUBSTITUTION_METHOD method, WCHAR const* locale, BOOL ignore_user_override,
IDWriteNumberSubstitution **substitution)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
- TRACE("(%p)->(%d %s %d %p)\n", This, method, debugstr_w(locale), ignore_user_override, substitution);
+ TRACE("%p, %d, %s, %d, %p.\n", iface, method, debugstr_w(locale), ignore_user_override, substitution);
+
return create_numbersubstitution(method, locale, ignore_user_override, substitution);
}
@@ -1249,15 +1244,14 @@ static inline void dwrite_matrix_multiply(DWRITE_MATRIX *a, const DWRITE_MATRIX
a->dy = tmp.dy * b->m12 + tmp.dy * b->m22 + b->dx;
}
-static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, DWRITE_GLYPH_RUN const *run,
+static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory7 *iface, DWRITE_GLYPH_RUN const *run,
FLOAT ppdip, DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE rendering_mode,
DWRITE_MEASURING_MODE measuring_mode, FLOAT originX, FLOAT originY, IDWriteGlyphRunAnalysis **analysis)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
struct glyphrunanalysis_desc desc;
DWRITE_MATRIX m, scale = { 0 };
- TRACE("(%p)->(%p %.2f %p %d %d %.2f %.2f %p)\n", This, run, ppdip, transform, rendering_mode,
+ TRACE("%p, %p, %.8e, %p, %d, %d, %.8e, %.8e, %p.\n", iface, run, ppdip, transform, rendering_mode,
measuring_mode, originX, originY, analysis);
if (ppdip <= 0.0f) {
@@ -1280,46 +1274,46 @@ static HRESULT WINAPI dwritefactory_CreateGlyphRunAnalysis(IDWriteFactory5 *ifac
return create_glyphrunanalysis(&desc, analysis);
}
-static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory5 *iface, IDWriteFontCollection **collection,
+static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory7 *iface, IDWriteFontCollection **collection,
BOOL check_for_updates)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
HRESULT hr = S_OK;
- TRACE("(%p)->(%p %d)\n", This, collection, check_for_updates);
+ TRACE("%p, %p, %d.\n", iface, collection, check_for_updates);
if (check_for_updates)
FIXME("checking for eudc updates not implemented\n");
- if (This->eudc_collection)
- IDWriteFontCollection1_AddRef(This->eudc_collection);
+ if (factory->eudc_collection)
+ IDWriteFontCollection1_AddRef(factory->eudc_collection);
else {
IDWriteFontCollection3 *eudc_collection;
- if (FAILED(hr = get_eudc_fontcollection(iface, &eudc_collection))) {
+ if (FAILED(hr = get_eudc_fontcollection((IDWriteFactory5 *)iface, &eudc_collection)))
+ {
*collection = NULL;
WARN("Failed to get EUDC collection, hr %#x.\n", hr);
return hr;
}
- if (InterlockedCompareExchangePointer((void **)&This->eudc_collection, eudc_collection, NULL))
+ if (InterlockedCompareExchangePointer((void **)&factory->eudc_collection, eudc_collection, NULL))
IDWriteFontCollection3_Release(eudc_collection);
}
- *collection = (IDWriteFontCollection *)This->eudc_collection;
+ *collection = (IDWriteFontCollection *)factory->eudc_collection;
return hr;
}
-static HRESULT WINAPI dwritefactory1_CreateCustomRenderingParams(IDWriteFactory5 *iface, FLOAT gamma,
+static HRESULT WINAPI dwritefactory1_CreateCustomRenderingParams(IDWriteFactory7 *iface, FLOAT gamma,
FLOAT enhcontrast, FLOAT enhcontrast_grayscale, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry,
DWRITE_RENDERING_MODE mode, IDWriteRenderingParams1** params)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
IDWriteRenderingParams3 *params3;
HRESULT hr;
- TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %p)\n", This, gamma, enhcontrast, enhcontrast_grayscale,
+ TRACE("%p, %.8e, %.8e, %.8e, %.8e, %d, %d, %p.\n", iface, gamma, enhcontrast, enhcontrast_grayscale,
cleartype_level, geometry, mode, params);
if ((UINT32)mode > DWRITE_RENDERING_MODE_OUTLINE) {
@@ -1327,15 +1321,15 @@ static HRESULT WINAPI dwritefactory1_CreateCustomRenderingParams(IDWriteFactory5
return E_INVALIDARG;
}
- hr = IDWriteFactory5_CreateCustomRenderingParams(iface, gamma, enhcontrast, enhcontrast_grayscale,
+ hr = IDWriteFactory7_CreateCustomRenderingParams(iface, gamma, enhcontrast, enhcontrast_grayscale,
cleartype_level, geometry, (DWRITE_RENDERING_MODE1)mode, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3);
*params = (IDWriteRenderingParams1*)params3;
return hr;
}
-static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory5 *iface, IDWriteFontFallback **fallback)
+static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory7 *iface, IDWriteFontFallback **fallback)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
TRACE("%p, %p.\n", iface, fallback);
@@ -1343,7 +1337,7 @@ static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory5 *ifac
if (!factory->fallback)
{
- HRESULT hr = create_system_fontfallback(iface, &factory->fallback);
+ HRESULT hr = create_system_fontfallback((IDWriteFactory5 *)iface, &factory->fallback);
if (FAILED(hr))
return hr;
}
@@ -1353,35 +1347,32 @@ static HRESULT WINAPI dwritefactory2_GetSystemFontFallback(IDWriteFactory5 *ifac
return S_OK;
}
-static HRESULT WINAPI dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory5 *iface,
+static HRESULT WINAPI dwritefactory2_CreateFontFallbackBuilder(IDWriteFactory7 *iface,
IDWriteFontFallbackBuilder **fallbackbuilder)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ TRACE("%p, %p.\n", iface, fallbackbuilder);
- TRACE("(%p)->(%p)\n", This, fallbackbuilder);
-
- return create_fontfallback_builder(iface, fallbackbuilder);
+ return create_fontfallback_builder((IDWriteFactory5 *)iface, fallbackbuilder);
}
-static HRESULT WINAPI dwritefactory2_TranslateColorGlyphRun(IDWriteFactory5 *iface, FLOAT originX, FLOAT originY,
+static HRESULT WINAPI dwritefactory2_TranslateColorGlyphRun(IDWriteFactory7 *iface, FLOAT originX, FLOAT originY,
const DWRITE_GLYPH_RUN *run, const DWRITE_GLYPH_RUN_DESCRIPTION *rundescr, DWRITE_MEASURING_MODE mode,
const DWRITE_MATRIX *transform, UINT32 palette, IDWriteColorGlyphRunEnumerator **colorlayers)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
- TRACE("(%p)->(%.2f %.2f %p %p %d %p %u %p)\n", This, originX, originY, run, rundescr, mode,
+ TRACE("%p, %.8e, %.8e, %p, %p, %d, %p, %u, %p.\n", iface, originX, originY, run, rundescr, mode,
transform, palette, colorlayers);
+
return create_colorglyphenum(originX, originY, run, rundescr, mode, transform, palette, colorlayers);
}
-static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory5 *iface, FLOAT gamma, FLOAT contrast,
+static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory7 *iface, FLOAT gamma, FLOAT contrast,
FLOAT grayscalecontrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY geometry, DWRITE_RENDERING_MODE mode,
DWRITE_GRID_FIT_MODE gridfit, IDWriteRenderingParams2 **params)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
IDWriteRenderingParams3 *params3;
HRESULT hr;
- TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This, gamma, contrast, grayscalecontrast, cleartype_level,
+ TRACE("%p, %.8e, %.8e, %.8e, %.8e, %d, %d, %d, %p.\n", iface, gamma, contrast, grayscalecontrast, cleartype_level,
geometry, mode, gridfit, params);
if ((UINT32)mode > DWRITE_RENDERING_MODE_OUTLINE) {
@@ -1389,7 +1380,7 @@ static HRESULT WINAPI dwritefactory2_CreateCustomRenderingParams(IDWriteFactory5
return E_INVALIDARG;
}
- hr = IDWriteFactory5_CreateCustomRenderingParams(iface, gamma, contrast, grayscalecontrast,
+ hr = IDWriteFactory7_CreateCustomRenderingParams(iface, gamma, contrast, grayscalecontrast,
cleartype_level, geometry, (DWRITE_RENDERING_MODE1)mode, DWRITE_GRID_FIT_MODE_DEFAULT, ¶ms3);
*params = (IDWriteRenderingParams2*)params3;
return hr;
@@ -1412,112 +1403,97 @@ static HRESULT factory_create_glyphrun_analysis(const DWRITE_GLYPH_RUN *run, con
return create_glyphrunanalysis(&desc, analysis);
}
-static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, const DWRITE_GLYPH_RUN *run,
+static HRESULT WINAPI dwritefactory2_CreateGlyphRunAnalysis(IDWriteFactory7 *iface, const DWRITE_GLYPH_RUN *run,
const DWRITE_MATRIX *transform, DWRITE_RENDERING_MODE rendering_mode, DWRITE_MEASURING_MODE measuring_mode,
DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY,
IDWriteGlyphRunAnalysis **analysis)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode,
+ TRACE("%p, %p, %p, %d, %d, %d, %d, %.8e, %.8e, %p.\n", iface, run, transform, rendering_mode, measuring_mode,
gridfit_mode, aa_mode, originX, originY, analysis);
return factory_create_glyphrun_analysis(run, transform, (DWRITE_RENDERING_MODE1)rendering_mode, measuring_mode,
gridfit_mode, aa_mode, originX, originY, analysis);
}
-static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory5 *iface, DWRITE_GLYPH_RUN const *run,
+static HRESULT WINAPI dwritefactory3_CreateGlyphRunAnalysis(IDWriteFactory7 *iface, DWRITE_GLYPH_RUN const *run,
DWRITE_MATRIX const *transform, DWRITE_RENDERING_MODE1 rendering_mode, DWRITE_MEASURING_MODE measuring_mode,
DWRITE_GRID_FIT_MODE gridfit_mode, DWRITE_TEXT_ANTIALIAS_MODE aa_mode, FLOAT originX, FLOAT originY,
IDWriteGlyphRunAnalysis **analysis)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- TRACE("(%p)->(%p %p %d %d %d %d %.2f %.2f %p)\n", This, run, transform, rendering_mode, measuring_mode,
+ TRACE("%p, %p, %p, %d, %d, %d, %d, %.8e, %.8e, %p.\n", iface, run, transform, rendering_mode, measuring_mode,
gridfit_mode, aa_mode, originX, originY, analysis);
return factory_create_glyphrun_analysis(run, transform, rendering_mode, measuring_mode, gridfit_mode,
aa_mode, originX, originY, analysis);
}
-static HRESULT WINAPI dwritefactory3_CreateCustomRenderingParams(IDWriteFactory5 *iface, FLOAT gamma, FLOAT contrast,
+static HRESULT WINAPI dwritefactory3_CreateCustomRenderingParams(IDWriteFactory7 *iface, FLOAT gamma, FLOAT contrast,
FLOAT grayscale_contrast, FLOAT cleartype_level, DWRITE_PIXEL_GEOMETRY pixel_geometry,
DWRITE_RENDERING_MODE1 rendering_mode, DWRITE_GRID_FIT_MODE gridfit_mode, IDWriteRenderingParams3 **params)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- TRACE("(%p)->(%.2f %.2f %.2f %.2f %d %d %d %p)\n", This, gamma, contrast, grayscale_contrast, cleartype_level,
+ TRACE("%p, %.8e, %.8e, %.8e, %.8e, %d, %d, %d, %p.\n", iface, gamma, contrast, grayscale_contrast, cleartype_level,
pixel_geometry, rendering_mode, gridfit_mode, params);
return create_renderingparams(gamma, contrast, grayscale_contrast, cleartype_level, pixel_geometry, rendering_mode,
gridfit_mode, params);
}
-static HRESULT WINAPI dwritefactory3_CreateFontFaceReference_(IDWriteFactory5 *iface, IDWriteFontFile *file,
+static HRESULT WINAPI dwritefactory3_CreateFontFaceReference_(IDWriteFactory7 *iface, IDWriteFontFile *file,
UINT32 index, DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **reference)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- TRACE("(%p)->(%p %u %x %p)\n", This, file, index, simulations, reference);
+ TRACE("%p, %p, %u, %x, %p.\n", iface, file, index, simulations, reference);
- return create_fontfacereference(iface, file, index, simulations, reference);
+ return create_fontfacereference((IDWriteFactory5 *)iface, file, index, simulations, reference);
}
-static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory5 *iface, WCHAR const *path,
+static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory7 *iface, WCHAR const *path,
FILETIME const *writetime, UINT32 index, DWRITE_FONT_SIMULATIONS simulations,
IDWriteFontFaceReference **reference)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
IDWriteFontFile *file;
HRESULT hr;
- TRACE("(%p)->(%s %p %u %x, %p)\n", This, debugstr_w(path), writetime, index, simulations, reference);
+ TRACE("%p, %s, %p, %u, %#x, %p.\n", iface, debugstr_w(path), writetime, index, simulations, reference);
- hr = IDWriteFactory5_CreateFontFileReference(iface, path, writetime, &file);
+ hr = IDWriteFactory5_CreateFontFileReference((IDWriteFactory5 *)iface, path, writetime, &file);
if (FAILED(hr)) {
*reference = NULL;
return hr;
}
- hr = IDWriteFactory5_CreateFontFaceReference_(iface, file, index, simulations, reference);
+ hr = IDWriteFactory5_CreateFontFaceReference_((IDWriteFactory5 *)iface, file, index, simulations, reference);
IDWriteFontFile_Release(file);
return hr;
}
-static HRESULT WINAPI dwritefactory3_GetSystemFontSet(IDWriteFactory5 *iface, IDWriteFontSet **fontset)
+static HRESULT WINAPI dwritefactory3_GetSystemFontSet(IDWriteFactory7 *iface, IDWriteFontSet **fontset)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- FIXME("(%p)->(%p): stub\n", This, fontset);
+ FIXME("%p, %p: stub\n", iface, fontset);
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefactory3_CreateFontSetBuilder(IDWriteFactory5 *iface, IDWriteFontSetBuilder **builder)
+static HRESULT WINAPI dwritefactory3_CreateFontSetBuilder(IDWriteFactory7 *iface, IDWriteFontSetBuilder **builder)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- FIXME("(%p)->(%p): stub\n", This, builder);
+ FIXME("%p, %p: stub\n", iface, builder);
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory5 *iface, IDWriteFontSet *fontset,
+static HRESULT WINAPI dwritefactory3_CreateFontCollectionFromFontSet(IDWriteFactory7 *iface, IDWriteFontSet *fontset,
IDWriteFontCollection1 **collection)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- FIXME("(%p)->(%p %p): stub\n", This, fontset, collection);
+ FIXME("%p, %p, %p: stub\n", iface, fontset, collection);
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory5 *iface, BOOL include_downloadable,
+static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable,
IDWriteFontCollection1 **collection, BOOL check_for_updates)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
- TRACE("(%p)->(%d %p %d)\n", This, include_downloadable, collection, check_for_updates);
+ TRACE("%p, %d, %p, %d.\n", iface, include_downloadable, collection, check_for_updates);
if (include_downloadable)
FIXME("remote fonts are not supported\n");
@@ -1525,28 +1501,24 @@ static HRESULT WINAPI dwritefactory3_GetSystemFontCollection(IDWriteFactory5 *if
if (check_for_updates)
FIXME("checking for system font updates not implemented\n");
- *collection = factory_get_system_collection(This);
+ *collection = factory_get_system_collection(factory);
return *collection ? S_OK : E_FAIL;
}
-static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory5 *iface, IDWriteFontDownloadQueue **queue)
+static HRESULT WINAPI dwritefactory3_GetFontDownloadQueue(IDWriteFactory7 *iface, IDWriteFontDownloadQueue **queue)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- FIXME("(%p)->(%p): stub\n", This, queue);
+ FIXME("%p, %p: stub\n", iface, queue);
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory5 *iface, D2D1_POINT_2F baseline_origin,
+static HRESULT WINAPI dwritefactory4_TranslateColorGlyphRun(IDWriteFactory7 *iface, D2D1_POINT_2F baseline_origin,
DWRITE_GLYPH_RUN const *run, DWRITE_GLYPH_RUN_DESCRIPTION const *run_desc,
DWRITE_GLYPH_IMAGE_FORMATS desired_formats, DWRITE_MEASURING_MODE measuring_mode, DWRITE_MATRIX const *transform,
UINT32 palette, IDWriteColorGlyphRunEnumerator1 **layers)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- FIXME("(%p)->(%p %p %u %d %p %u %p): stub\n", This, run, run_desc, desired_formats, measuring_mode,
+ FIXME("%p, %p, %p, %u, %d, %p, %u, %p: stub\n", iface, run, run_desc, desired_formats, measuring_mode,
transform, palette, layers);
return E_NOTIMPL;
@@ -1626,76 +1598,138 @@ static HRESULT compute_glyph_origins(DWRITE_GLYPH_RUN const *run, DWRITE_MEASURI
return S_OK;
}
-static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins_(IDWriteFactory5 *iface, DWRITE_GLYPH_RUN const *run,
+static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins_(IDWriteFactory7 *iface, DWRITE_GLYPH_RUN const *run,
D2D1_POINT_2F baseline_origin, D2D1_POINT_2F *origins)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- TRACE("(%p)->(%p (%f,%f) %p)\n", This, run, baseline_origin.x, baseline_origin.y, origins);
+ TRACE("%p, %p, {%.8e,%.8e}, %p.\n", iface, run, baseline_origin.x, baseline_origin.y, origins);
return compute_glyph_origins(run, DWRITE_MEASURING_MODE_NATURAL, baseline_origin, NULL, origins);
}
-static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins(IDWriteFactory5 *iface, DWRITE_GLYPH_RUN const *run,
+static HRESULT WINAPI dwritefactory4_ComputeGlyphOrigins(IDWriteFactory7 *iface, DWRITE_GLYPH_RUN const *run,
DWRITE_MEASURING_MODE measuring_mode, D2D1_POINT_2F baseline_origin, DWRITE_MATRIX const *transform,
D2D1_POINT_2F *origins)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
-
- TRACE("(%p)->(%p %d (%f,%f) %p %p)\n", This, run, measuring_mode, baseline_origin.x, baseline_origin.y,
+ TRACE("%p, %p, %d, {%.8e,%.8e}, %p, %p.\n", iface, run, measuring_mode, baseline_origin.x, baseline_origin.y,
transform, origins);
return compute_glyph_origins(run, measuring_mode, baseline_origin, transform, origins);
}
-static HRESULT WINAPI dwritefactory5_CreateFontSetBuilder(IDWriteFactory5 *iface, IDWriteFontSetBuilder1 **builder)
+static HRESULT WINAPI dwritefactory5_CreateFontSetBuilder(IDWriteFactory7 *iface, IDWriteFontSetBuilder1 **builder)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ FIXME("%p, %p: stub\n", iface, builder);
+
+ return E_NOTIMPL;
+}
- FIXME("(%p)->(%p): stub\n", This, builder);
+static HRESULT WINAPI dwritefactory5_CreateInMemoryFontFileLoader(IDWriteFactory7 *iface, IDWriteFontFileLoader **loader)
+{
+ TRACE("%p, %p.\n", iface, loader);
+
+ return create_inmemory_fileloader(loader);
+}
+
+static HRESULT WINAPI dwritefactory5_CreateHttpFontFileLoader(IDWriteFactory7 *iface, WCHAR const *referrer_url,
+ WCHAR const *extra_headers, IDWriteRemoteFontFileLoader **loader)
+{
+ FIXME("%p, %s, %s, %p: stub\n", iface, debugstr_w(referrer_url), wine_dbgstr_w(extra_headers), loader);
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefactory5_CreateInMemoryFontFileLoader(IDWriteFactory5 *iface, IDWriteFontFileLoader **loader)
+static DWRITE_CONTAINER_TYPE WINAPI dwritefactory5_AnalyzeContainerType(IDWriteFactory7 *iface, void const *data,
+ UINT32 data_size)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ TRACE("%p, %p, %u.\n", iface, data, data_size);
- TRACE("(%p)->(%p)\n", This, loader);
+ return opentype_analyze_container_type(data, data_size);
+}
- return create_inmemory_fileloader(loader);
+static HRESULT WINAPI dwritefactory5_UnpackFontFile(IDWriteFactory7 *iface, DWRITE_CONTAINER_TYPE container_type, void const *data,
+ UINT32 data_size, IDWriteFontFileStream **stream)
+{
+ FIXME("%p, %d, %p, %u, %p: stub\n", iface, container_type, data, data_size, stream);
+
+ return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefactory5_CreateHttpFontFileLoader(IDWriteFactory5 *iface, WCHAR const *referrer_url, WCHAR const *extra_headers,
- IDWriteRemoteFontFileLoader **loader)
+static HRESULT WINAPI dwritefactory6_CreateFontFaceReference(IDWriteFactory7 *iface, IDWriteFontFile *file,
+ UINT32 face_index, DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values,
+ UINT32 num_axis, IDWriteFontFaceReference1 **ref)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ FIXME("%p, %p, %u, %#x, %p, %u, %p.\n", iface, file, face_index, simulations, axis_values, num_axis, ref);
- FIXME("(%p)->(%s %s %p): stub\n", This, debugstr_w(referrer_url), wine_dbgstr_w(extra_headers), loader);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI dwritefactory6_CreateFontResource(IDWriteFactory7 *iface, IDWriteFontFile *file,
+ UINT32 face_index, IDWriteFontResource **resource)
+{
+ FIXME("%p, %p, %u, %p.\n", iface, file, face_index, resource);
return E_NOTIMPL;
}
-static DWRITE_CONTAINER_TYPE WINAPI dwritefactory5_AnalyzeContainerType(IDWriteFactory5 *iface, void const *data, UINT32 data_size)
+static HRESULT WINAPI dwritefactory6_GetSystemFontSet(IDWriteFactory7 *iface, BOOL include_downloadable,
+ IDWriteFontSet1 **fontset)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ FIXME("%p, %d, %p.\n", iface, include_downloadable, fontset);
- TRACE("(%p)->(%p %u)\n", This, data, data_size);
+ return E_NOTIMPL;
+}
- return opentype_analyze_container_type(data, data_size);
+static HRESULT WINAPI dwritefactory6_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable,
+ DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection2 **collection)
+{
+ FIXME("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection);
+
+ return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefactory5_UnpackFontFile(IDWriteFactory5 *iface, DWRITE_CONTAINER_TYPE container_type, void const *data,
- UINT32 data_size, IDWriteFontFileStream **stream)
+static HRESULT WINAPI dwritefactory6_CreateFontCollectionFromFontSet(IDWriteFactory7 *iface, IDWriteFontSet *fontset,
+ DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection2 **collection)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
+ FIXME("%p, %p, %d, %p.\n", iface, fontset, family_model, collection);
- FIXME("(%p)->(%d %p %u %p): stub\n", This, container_type, data, data_size, stream);
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI dwritefactory6_CreateFontSetBuilder(IDWriteFactory7 *iface, IDWriteFontSetBuilder2 **builder)
+{
+ FIXME("%p, %p.\n", iface, builder);
return E_NOTIMPL;
}
-static const struct IDWriteFactory5Vtbl dwritefactoryvtbl = {
+static HRESULT WINAPI dwritefactory6_CreateTextFormat(IDWriteFactory7 *iface, const WCHAR *familyname,
+ IDWriteFontCollection *collection, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_axis,
+ FLOAT fontsize, const WCHAR *localename, IDWriteTextFormat3 **format)
+{
+ FIXME("%p, %s, %p, %p, %u, %.8e, %s, %p.\n", iface, debugstr_w(familyname), collection, axis_values, num_axis,
+ fontsize, debugstr_w(localename), format);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI dwritefactory7_GetSystemFontSet(IDWriteFactory7 *iface, BOOL include_downloadable,
+ IDWriteFontSet2 **fontset)
+{
+ FIXME("%p, %d, %p.\n", iface, include_downloadable, fontset);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI dwritefactory7_GetSystemFontCollection(IDWriteFactory7 *iface, BOOL include_downloadable,
+ DWRITE_FONT_FAMILY_MODEL family_model, IDWriteFontCollection3 **collection)
+{
+ FIXME("%p, %d, %d, %p.\n", iface, include_downloadable, family_model, collection);
+
+ return E_NOTIMPL;
+}
+
+static const struct IDWriteFactory7Vtbl dwritefactoryvtbl =
+{
dwritefactory_QueryInterface,
dwritefactory_AddRef,
dwritefactory_Release,
@@ -1744,23 +1778,33 @@ static const struct IDWriteFactory5Vtbl dwritefactoryvtbl = {
dwritefactory5_CreateHttpFontFileLoader,
dwritefactory5_AnalyzeContainerType,
dwritefactory5_UnpackFontFile,
+ dwritefactory6_CreateFontFaceReference,
+ dwritefactory6_CreateFontResource,
+ dwritefactory6_GetSystemFontSet,
+ dwritefactory6_GetSystemFontCollection,
+ dwritefactory6_CreateFontCollectionFromFontSet,
+ dwritefactory6_CreateFontSetBuilder,
+ dwritefactory6_CreateTextFormat,
+ dwritefactory7_GetSystemFontSet,
+ dwritefactory7_GetSystemFontCollection,
};
-static ULONG WINAPI shareddwritefactory_AddRef(IDWriteFactory5 *iface)
+static ULONG WINAPI shareddwritefactory_AddRef(IDWriteFactory7 *iface)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
- TRACE("(%p)\n", This);
+ TRACE("%p.\n", iface);
+
return 2;
}
-static ULONG WINAPI shareddwritefactory_Release(IDWriteFactory5 *iface)
+static ULONG WINAPI shareddwritefactory_Release(IDWriteFactory7 *iface)
{
- struct dwritefactory *This = impl_from_IDWriteFactory5(iface);
- TRACE("(%p)\n", This);
+ TRACE("%p.\n", iface);
+
return 1;
}
-static const struct IDWriteFactory5Vtbl shareddwritefactoryvtbl = {
+static const struct IDWriteFactory7Vtbl shareddwritefactoryvtbl =
+{
dwritefactory_QueryInterface,
shareddwritefactory_AddRef,
shareddwritefactory_Release,
@@ -1809,13 +1853,22 @@ static const struct IDWriteFactory5Vtbl shareddwritefactoryvtbl = {
dwritefactory5_CreateHttpFontFileLoader,
dwritefactory5_AnalyzeContainerType,
dwritefactory5_UnpackFontFile,
+ dwritefactory6_CreateFontFaceReference,
+ dwritefactory6_CreateFontResource,
+ dwritefactory6_GetSystemFontSet,
+ dwritefactory6_GetSystemFontCollection,
+ dwritefactory6_CreateFontCollectionFromFontSet,
+ dwritefactory6_CreateFontSetBuilder,
+ dwritefactory6_CreateTextFormat,
+ dwritefactory7_GetSystemFontSet,
+ dwritefactory7_GetSystemFontCollection,
};
static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYPE type)
{
- factory->IDWriteFactory5_iface.lpVtbl = type == DWRITE_FACTORY_TYPE_SHARED ?
+ factory->IDWriteFactory7_iface.lpVtbl = type == DWRITE_FACTORY_TYPE_SHARED ?
&shareddwritefactoryvtbl : &dwritefactoryvtbl;
- factory->ref = 1;
+ factory->refcount = 1;
factory->localfontfileloader = get_local_fontfile_loader();
factory->system_collection = NULL;
factory->eudc_collection = NULL;
@@ -1832,7 +1885,7 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP
void factory_detach_fontcollection(IDWriteFactory5 *iface, IDWriteFontCollection3 *collection)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
InterlockedCompareExchangePointer((void **)&factory->system_collection, NULL, collection);
InterlockedCompareExchangePointer((void **)&factory->eudc_collection, NULL, collection);
IDWriteFactory5_Release(iface);
@@ -1840,7 +1893,7 @@ void factory_detach_fontcollection(IDWriteFactory5 *iface, IDWriteFontCollection
void factory_detach_gdiinterop(IDWriteFactory5 *iface, IDWriteGdiInterop1 *interop)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory5(iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
factory->gdiinterop = NULL;
IDWriteFactory5_Release(iface);
}
@@ -1855,7 +1908,7 @@ HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnkno
*ret = NULL;
if (type == DWRITE_FACTORY_TYPE_SHARED && shared_factory)
- return IDWriteFactory5_QueryInterface(shared_factory, riid, (void**)ret);
+ return IDWriteFactory7_QueryInterface(shared_factory, riid, (void**)ret);
factory = heap_alloc(sizeof(struct dwritefactory));
if (!factory) return E_OUTOFMEMORY;
@@ -1863,12 +1916,13 @@ HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnkno
init_dwritefactory(factory, type);
if (type == DWRITE_FACTORY_TYPE_SHARED)
- if (InterlockedCompareExchangePointer((void**)&shared_factory, &factory->IDWriteFactory5_iface, NULL)) {
- release_shared_factory(&factory->IDWriteFactory5_iface);
- return IDWriteFactory5_QueryInterface(shared_factory, riid, (void**)ret);
+ if (InterlockedCompareExchangePointer((void **)&shared_factory, &factory->IDWriteFactory7_iface, NULL))
+ {
+ release_shared_factory(&factory->IDWriteFactory7_iface);
+ return IDWriteFactory7_QueryInterface(shared_factory, riid, (void**)ret);
}
- hr = IDWriteFactory5_QueryInterface(&factory->IDWriteFactory5_iface, riid, (void**)ret);
- IDWriteFactory5_Release(&factory->IDWriteFactory5_iface);
+ hr = IDWriteFactory7_QueryInterface(&factory->IDWriteFactory7_iface, riid, (void**)ret);
+ IDWriteFactory7_Release(&factory->IDWriteFactory7_iface);
return hr;
}
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index d565eee331..58f2af6e7a 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9248,7 +9248,7 @@ static void test_font_resource(void)
if (!(factory = create_factory_iid(&IID_IDWriteFactory6)))
{
- skip("IDWriteFactory6 is not supported.\n");
+ win_skip("IDWriteFactory6 is not supported.\n");
return;
}
@@ -9259,8 +9259,17 @@ static void test_font_resource(void)
ok(hr == S_OK, "Failed to get file object, hr %#x.\n", hr);
hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource);
+todo_wine
ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
+ if (FAILED(hr))
+ {
+ IDWriteFactory6_Release(factory);
+ IDWriteFontFile_Release(fontfile);
+ IDWriteFontFace_Release(fontface);
+ return;
+ }
+
hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource2);
ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
ok(resource != resource2, "Unexpected instance.\n");
--
2.24.0
Dec. 2, 2019
[PATCH 2/3] dwrite/tests: Add some tests for IDWriteFontResource.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/tests/font.c | 76 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 3cd41efc91..d565eee331 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9234,6 +9234,81 @@ todo_wine
ok(ref == 0, "factory not released, %u\n", ref);
}
+static void test_font_resource(void)
+{
+ IDWriteFontFaceReference1 *reference, *reference2;
+ IDWriteFontResource *resource, *resource2;
+ IDWriteFontFile *fontfile, *fontfile2;
+ IDWriteFontFace5 *fontface5;
+ IDWriteFontFace *fontface;
+ IDWriteFactory6 *factory;
+ UINT32 count, index;
+ HRESULT hr;
+ ULONG ref;
+
+ if (!(factory = create_factory_iid(&IID_IDWriteFactory6)))
+ {
+ skip("IDWriteFactory6 is not supported.\n");
+ return;
+ }
+
+ fontface = create_fontface((IDWriteFactory *)factory);
+
+ count = 1;
+ hr = IDWriteFontFace_GetFiles(fontface, &count, &fontfile);
+ ok(hr == S_OK, "Failed to get file object, hr %#x.\n", hr);
+
+ hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource);
+ ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
+
+ hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource2);
+ ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
+ ok(resource != resource2, "Unexpected instance.\n");
+ IDWriteFontResource_Release(resource2);
+
+ hr = IDWriteFontResource_GetFontFile(resource, &fontfile2);
+ ok(hr == S_OK, "Failed to get font file, hr %#x.\n", hr);
+ ok(fontfile2 == fontfile, "Unexpected file instance.\n");
+ IDWriteFontFile_Release(fontfile2);
+
+ index = IDWriteFontResource_GetFontFaceIndex(resource);
+ ok(!index, "Unexpected index %u.\n", index);
+
+ hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, NULL, 0, &reference);
+ ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
+
+ hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, NULL, 0, &reference2);
+ ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
+ ok(reference != reference2, "Unexpected reference instance.\n");
+ IDWriteFontFaceReference1_Release(reference2);
+ IDWriteFontFaceReference1_Release(reference);
+
+ hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace5, (void **)&fontface5);
+ ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
+
+ hr = IDWriteFontFace5_GetFontResource(fontface5, &resource2);
+ ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
+ ok(resource != resource2, "Unexpected resource instance.\n");
+ IDWriteFontResource_Release(resource);
+
+ hr = IDWriteFontFace5_GetFontResource(fontface5, &resource);
+ ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
+ ok(resource != resource2, "Unexpected resource instance.\n");
+ EXPECT_REF(resource, 1);
+
+ IDWriteFontResource_Release(resource);
+ IDWriteFontResource_Release(resource2);
+
+ IDWriteFontFace5_Release(fontface5);
+
+ IDWriteFontResource_Release(resource);
+ IDWriteFontFile_Release(fontfile);
+
+ IDWriteFontFace_Release(fontface);
+ ref = IDWriteFactory6_Release(factory);
+ ok(ref == 0, "Factory wasn't released, %u.\n", ref);
+}
+
START_TEST(font)
{
IDWriteFactory *factory;
@@ -9301,6 +9376,7 @@ START_TEST(font)
test_localfontfileloader();
test_AnalyzeContainerType();
test_fontsetbuilder();
+ test_font_resource();
IDWriteFactory_Release(factory);
}
--
2.24.0
Dec. 2, 2019
[PATCH 1/3] dwrite: Update to IDWriteFontFace5.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 40 +-
dlls/dwrite/font.c | 732 +++++++++++++++++++----------------
dlls/dwrite/freetype.c | 40 +-
dlls/dwrite/main.c | 15 +-
dlls/dwrite/opentype.c | 24 +-
5 files changed, 470 insertions(+), 381 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index d3d74e0709..7898403dd9 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -175,7 +175,7 @@ struct dwrite_fonttable
struct fontfacecached
{
struct list entry;
- IDWriteFontFace4 *fontface;
+ IDWriteFontFace5 *fontface;
};
#define GLYPH_BLOCK_SHIFT 8
@@ -185,8 +185,8 @@ struct fontfacecached
struct dwrite_fontface
{
- IDWriteFontFace4 IDWriteFontFace4_iface;
- LONG ref;
+ IDWriteFontFace5 IDWriteFontFace5_iface;
+ LONG refcount;
IDWriteFontFileStream *stream;
IDWriteFontFile **files;
@@ -244,7 +244,8 @@ extern IDWriteTextAnalyzer *get_text_analyzer(void) DECLSPEC_HIDDEN;
extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
extern void init_local_fontfile_loader(void) DECLSPEC_HIDDEN;
extern IDWriteFontFileLoader *get_local_fontfile_loader(void) DECLSPEC_HIDDEN;
-extern HRESULT create_fontface(const struct fontface_desc*,struct list*,IDWriteFontFace4**) DECLSPEC_HIDDEN;
+extern HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list,
+ IDWriteFontFace5 **fontface) DECLSPEC_HIDDEN;
extern HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system,
IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN;
extern HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc*,IDWriteGlyphRunAnalysis**) DECLSPEC_HIDDEN;
@@ -267,13 +268,14 @@ extern HRESULT factory_get_cached_fontface(IDWriteFactory5*,IDWriteFontFile*cons
struct list**,REFIID,void**) DECLSPEC_HIDDEN;
extern void factory_detach_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection3 *collection) DECLSPEC_HIDDEN;
extern void factory_detach_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1*) DECLSPEC_HIDDEN;
-extern struct fontfacecached *factory_cache_fontface(IDWriteFactory5*,struct list*,IDWriteFontFace4*) DECLSPEC_HIDDEN;
+extern struct fontfacecached *factory_cache_fontface(IDWriteFactory5 *factory, struct list *fontfaces,
+ IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
extern void get_logfont_from_font(IDWriteFont*,LOGFONTW*) DECLSPEC_HIDDEN;
extern void get_logfont_from_fontface(IDWriteFontFace*,LOGFONTW*) DECLSPEC_HIDDEN;
extern HRESULT get_fontsig_from_font(IDWriteFont*,FONTSIGNATURE*) DECLSPEC_HIDDEN;
extern HRESULT get_fontsig_from_fontface(IDWriteFontFace*,FONTSIGNATURE*) DECLSPEC_HIDDEN;
extern HRESULT create_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1**) DECLSPEC_HIDDEN;
-extern void fontface_detach_from_cache(IDWriteFontFace4*) DECLSPEC_HIDDEN;
+extern void fontface_detach_from_cache(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN;
@@ -300,7 +302,7 @@ struct file_stream_desc {
UINT32 face_index;
};
-extern const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag,
+extern const void* get_fontface_table(IDWriteFontFace5 *fontface, UINT32 tag,
struct dwrite_fonttable *table) DECLSPEC_HIDDEN;
extern HRESULT opentype_analyze_font(IDWriteFontFileStream*,BOOL*,DWRITE_FONT_FILE_TYPE*,DWRITE_FONT_FACE_TYPE*,UINT32*) DECLSPEC_HIDDEN;
@@ -321,8 +323,8 @@ extern unsigned int opentype_get_cpal_palettecount(const struct dwrite_fonttable
extern unsigned int opentype_get_cpal_paletteentrycount(const struct dwrite_fonttable *table) DECLSPEC_HIDDEN;
extern HRESULT opentype_get_cpal_entries(const struct dwrite_fonttable *table, unsigned int palette,
unsigned int first_entry_index, unsigned int entry_count, DWRITE_COLOR_F *entries) DECLSPEC_HIDDEN;
-extern BOOL opentype_has_vertical_variants(IDWriteFontFace4*) DECLSPEC_HIDDEN;
-extern UINT32 opentype_get_glyph_image_formats(IDWriteFontFace4*) DECLSPEC_HIDDEN;
+extern BOOL opentype_has_vertical_variants(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
+extern UINT32 opentype_get_glyph_image_formats(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
extern DWRITE_CONTAINER_TYPE opentype_analyze_container_type(void const *, UINT32) DECLSPEC_HIDDEN;
struct dwrite_colorglyph {
@@ -373,19 +375,21 @@ extern void release_freetype(void) DECLSPEC_HIDDEN;
extern HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph,
DWRITE_GLYPH_METRICS *metrics) DECLSPEC_HIDDEN;
-extern void freetype_notify_cacheremove(IDWriteFontFace4*) DECLSPEC_HIDDEN;
-extern BOOL freetype_is_monospaced(IDWriteFontFace4*) DECLSPEC_HIDDEN;
-extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emsize, UINT16 const *glyphs,
+extern void freetype_notify_cacheremove(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
+extern BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
+extern HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emsize, UINT16 const *glyphs,
float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl,
IDWriteGeometrySink *sink) DECLSPEC_HIDDEN;
-extern UINT16 freetype_get_glyphcount(IDWriteFontFace4*) DECLSPEC_HIDDEN;
-extern void freetype_get_glyphs(IDWriteFontFace4*,INT,UINT32 const*,UINT32,UINT16*) DECLSPEC_HIDDEN;
-extern BOOL freetype_has_kerning_pairs(IDWriteFontFace4*) DECLSPEC_HIDDEN;
-extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4*,UINT16,UINT16) DECLSPEC_HIDDEN;
+extern UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
+extern void freetype_get_glyphs(IDWriteFontFace5 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count,
+ UINT16 *glyphs) DECLSPEC_HIDDEN;
+extern BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
+extern INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace5 *fontface, UINT16 left, UINT16 right) DECLSPEC_HIDDEN;
extern void freetype_get_glyph_bbox(struct dwrite_glyphbitmap *bitmap_desc) DECLSPEC_HIDDEN;
extern BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap*) DECLSPEC_HIDDEN;
-extern INT freetype_get_charmap_index(IDWriteFontFace4*,BOOL*) DECLSPEC_HIDDEN;
-extern INT32 freetype_get_glyph_advance(IDWriteFontFace4*,FLOAT,UINT16,DWRITE_MEASURING_MODE,BOOL*) DECLSPEC_HIDDEN;
+extern INT freetype_get_charmap_index(IDWriteFontFace5 *fontface, BOOL *is_symbol) DECLSPEC_HIDDEN;
+extern INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emsize, UINT16 index,
+ DWRITE_MEASURING_MODE measuring_mode, BOOL *has_contours) DECLSPEC_HIDDEN;
extern void freetype_get_design_glyph_bbox(IDWriteFontFace4*,UINT16,UINT16,RECT*) DECLSPEC_HIDDEN;
/* Glyph shaping */
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 306f431d65..1bf88d6b17 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -185,7 +185,7 @@ struct dwrite_colorglyphenum
FLOAT origin_x; /* original run origin */
FLOAT origin_y;
- IDWriteFontFace4 *fontface; /* for convenience */
+ IDWriteFontFace5 *fontface; /* for convenience */
DWRITE_COLOR_GLYPH_RUN1 colorrun; /* returned with GetCurrentRun() */
DWRITE_GLYPH_RUN run; /* base run */
UINT32 palette; /* palette index to get layer color from */
@@ -239,7 +239,7 @@ static void dwrite_grab_font_table(void *context, UINT32 table, const BYTE **dat
struct dwrite_fontface *fontface = context;
BOOL exists = FALSE;
- if (FAILED(IDWriteFontFace4_TryGetFontTable(&fontface->IDWriteFontFace4_iface, table, (const void **)data,
+ if (FAILED(IDWriteFontFace5_TryGetFontTable(&fontface->IDWriteFontFace5_iface, table, (const void **)data,
size, data_context, &exists)) || !exists)
{
*data = NULL;
@@ -251,7 +251,7 @@ static void dwrite_grab_font_table(void *context, UINT32 table, const BYTE **dat
static void dwrite_release_font_table(void *context, void *data_context)
{
struct dwrite_fontface *fontface = context;
- IDWriteFontFace4_ReleaseFontTable(&fontface->IDWriteFontFace4_iface, data_context);
+ IDWriteFontFace5_ReleaseFontTable(&fontface->IDWriteFontFace5_iface, data_context);
}
static UINT16 dwrite_get_font_upem(void *context)
@@ -275,9 +275,9 @@ struct scriptshaping_cache *fontface_get_shaping_cache(struct dwrite_fontface *f
return fontface->shaping_cache = create_scriptshaping_cache(fontface, &dwrite_font_ops);
}
-static inline struct dwrite_fontface *impl_from_IDWriteFontFace4(IDWriteFontFace4 *iface)
+static inline struct dwrite_fontface *impl_from_IDWriteFontFace5(IDWriteFontFace5 *iface)
{
- return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace4_iface);
+ return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace5_iface);
}
static inline struct dwrite_font *impl_from_IDWriteFont3(IDWriteFont3 *iface)
@@ -350,7 +350,7 @@ static HRESULT set_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16
return S_OK;
}
-const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag, struct dwrite_fonttable *table)
+const void* get_fontface_table(IDWriteFontFace5 *fontface, UINT32 tag, struct dwrite_fonttable *table)
{
HRESULT hr;
@@ -358,7 +358,7 @@ const void* get_fontface_table(IDWriteFontFace4 *fontface, UINT32 tag, struct dw
return table->data;
table->exists = FALSE;
- hr = IDWriteFontFace4_TryGetFontTable(fontface, tag, (const void**)&table->data, &table->size, &table->context,
+ hr = IDWriteFontFace5_TryGetFontTable(fontface, tag, (const void **)&table->data, &table->size, &table->context,
&table->exists);
if (FAILED(hr) || !table->exists) {
TRACE("Font does not have %s table\n", debugstr_tag(tag));
@@ -388,25 +388,25 @@ static FLOAT get_font_prop_vec_dotproduct(const struct dwrite_font_propvec *left
static const struct dwrite_fonttable *get_fontface_vdmx(struct dwrite_fontface *fontface)
{
- get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_VDMX_TAG, &fontface->vdmx);
+ get_fontface_table(&fontface->IDWriteFontFace5_iface, MS_VDMX_TAG, &fontface->vdmx);
return &fontface->vdmx;
}
static const struct dwrite_fonttable *get_fontface_gasp(struct dwrite_fontface *fontface)
{
- get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_GASP_TAG, &fontface->gasp);
+ get_fontface_table(&fontface->IDWriteFontFace5_iface, MS_GASP_TAG, &fontface->gasp);
return &fontface->gasp;
}
static const struct dwrite_fonttable *get_fontface_cpal(struct dwrite_fontface *fontface)
{
- get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_CPAL_TAG, &fontface->cpal);
+ get_fontface_table(&fontface->IDWriteFontFace5_iface, MS_CPAL_TAG, &fontface->cpal);
return &fontface->cpal;
}
static const void* get_fontface_colr(struct dwrite_fontface *fontface)
{
- return get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_COLR_TAG, &fontface->colr);
+ return get_fontface_table(&fontface->IDWriteFontFace5_iface, MS_COLR_TAG, &fontface->colr);
}
static void addref_font_data(struct dwrite_font_data *data)
@@ -447,17 +447,17 @@ static void release_fontfamily_data(struct dwrite_fontfamily_data *data)
heap_free(data);
}
-void fontface_detach_from_cache(IDWriteFontFace4 *iface)
+void fontface_detach_from_cache(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *fontface = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
fontface->cached = NULL;
}
-static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace4 *iface, REFIID riid, void **obj)
+static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace5 *iface, REFIID riid, void **obj)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
- TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), obj);
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IDWriteFontFace4) ||
IsEqualIID(riid, &IID_IDWriteFontFace3) ||
@@ -467,8 +467,9 @@ static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace4 *iface, REF
IsEqualIID(riid, &IID_IUnknown))
{
*obj = iface;
- if (InterlockedIncrement(&This->ref) == 1) {
- InterlockedDecrement(&This->ref);
+ if (InterlockedIncrement(&fontface->refcount) == 1)
+ {
+ InterlockedDecrement(&fontface->refcount);
*obj = NULL;
return E_FAIL;
}
@@ -481,131 +482,148 @@ static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace4 *iface, REF
return E_NOINTERFACE;
}
-static ULONG WINAPI dwritefontface_AddRef(IDWriteFontFace4 *iface)
+static ULONG WINAPI dwritefontface_AddRef(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
- TRACE("(%p)->(%d)\n", This, ref);
- return ref;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+ ULONG refcount = InterlockedIncrement(&fontface->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
}
-static ULONG WINAPI dwritefontface_Release(IDWriteFontFace4 *iface)
+static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+ ULONG refcount = InterlockedDecrement(&fontface->refcount);
- TRACE("(%p)->(%d)\n", This, ref);
+ TRACE("%p, refcount %u.\n", iface, refcount);
- if (!ref) {
+ if (!refcount)
+ {
UINT32 i;
- if (This->cached) {
- factory_lock(This->factory);
- list_remove(&This->cached->entry);
- factory_unlock(This->factory);
- heap_free(This->cached);
+ if (fontface->cached)
+ {
+ factory_lock(fontface->factory);
+ list_remove(&fontface->cached->entry);
+ factory_unlock(fontface->factory);
+ heap_free(fontface->cached);
}
- release_scriptshaping_cache(This->shaping_cache);
- if (This->cmap.context)
- IDWriteFontFace4_ReleaseFontTable(iface, This->cmap.context);
- if (This->vdmx.context)
- IDWriteFontFace4_ReleaseFontTable(iface, This->vdmx.context);
- if (This->gasp.context)
- IDWriteFontFace4_ReleaseFontTable(iface, This->gasp.context);
- if (This->cpal.context)
- IDWriteFontFace4_ReleaseFontTable(iface, This->cpal.context);
- if (This->colr.context)
- IDWriteFontFace4_ReleaseFontTable(iface, This->colr.context);
- for (i = 0; i < This->file_count; i++) {
- if (This->files[i])
- IDWriteFontFile_Release(This->files[i]);
+ release_scriptshaping_cache(fontface->shaping_cache);
+ if (fontface->cmap.context)
+ IDWriteFontFace5_ReleaseFontTable(iface, fontface->cmap.context);
+ if (fontface->vdmx.context)
+ IDWriteFontFace5_ReleaseFontTable(iface, fontface->vdmx.context);
+ if (fontface->gasp.context)
+ IDWriteFontFace5_ReleaseFontTable(iface, fontface->gasp.context);
+ if (fontface->cpal.context)
+ IDWriteFontFace5_ReleaseFontTable(iface, fontface->cpal.context);
+ if (fontface->colr.context)
+ IDWriteFontFace5_ReleaseFontTable(iface, fontface->colr.context);
+ for (i = 0; i < fontface->file_count; i++)
+ {
+ if (fontface->files[i])
+ IDWriteFontFile_Release(fontface->files[i]);
}
- if (This->stream)
- IDWriteFontFileStream_Release(This->stream);
- heap_free(This->files);
+ if (fontface->stream)
+ IDWriteFontFileStream_Release(fontface->stream);
+ heap_free(fontface->files);
- for (i = 0; i < ARRAY_SIZE(This->glyphs); i++)
- heap_free(This->glyphs[i]);
+ for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++)
+ heap_free(fontface->glyphs[i]);
freetype_notify_cacheremove(iface);
- IDWriteFactory5_Release(This->factory);
- heap_free(This);
+ IDWriteFactory5_Release(fontface->factory);
+ heap_free(fontface);
}
- return ref;
+ return refcount;
}
-static DWRITE_FONT_FACE_TYPE WINAPI dwritefontface_GetType(IDWriteFontFace4 *iface)
+static DWRITE_FONT_FACE_TYPE WINAPI dwritefontface_GetType(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return This->type;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return fontface->type;
}
-static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace4 *iface, UINT32 *number_of_files,
+static HRESULT WINAPI dwritefontface_GetFiles(IDWriteFontFace5 *iface, UINT32 *number_of_files,
IDWriteFontFile **fontfiles)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
int i;
- TRACE("(%p)->(%p %p)\n", This, number_of_files, fontfiles);
+ TRACE("%p, %p, %p.\n", iface, number_of_files, fontfiles);
+
if (fontfiles == NULL)
{
- *number_of_files = This->file_count;
+ *number_of_files = fontface->file_count;
return S_OK;
}
- if (*number_of_files < This->file_count)
+
+ if (*number_of_files < fontface->file_count)
return E_INVALIDARG;
- for (i = 0; i < This->file_count; i++)
+ for (i = 0; i < fontface->file_count; i++)
{
- IDWriteFontFile_AddRef(This->files[i]);
- fontfiles[i] = This->files[i];
+ IDWriteFontFile_AddRef(fontface->files[i]);
+ fontfiles[i] = fontface->files[i];
}
return S_OK;
}
-static UINT32 WINAPI dwritefontface_GetIndex(IDWriteFontFace4 *iface)
+static UINT32 WINAPI dwritefontface_GetIndex(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return This->index;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return fontface->index;
}
-static DWRITE_FONT_SIMULATIONS WINAPI dwritefontface_GetSimulations(IDWriteFontFace4 *iface)
+static DWRITE_FONT_SIMULATIONS WINAPI dwritefontface_GetSimulations(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return This->simulations;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return fontface->simulations;
}
-static BOOL WINAPI dwritefontface_IsSymbolFont(IDWriteFontFace4 *iface)
+static BOOL WINAPI dwritefontface_IsSymbolFont(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return !!(This->flags & FONTFACE_IS_SYMBOL);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return !!(fontface->flags & FONTFACE_IS_SYMBOL);
}
-static void WINAPI dwritefontface_GetMetrics(IDWriteFontFace4 *iface, DWRITE_FONT_METRICS *metrics)
+static void WINAPI dwritefontface_GetMetrics(IDWriteFontFace5 *iface, DWRITE_FONT_METRICS *metrics)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)->(%p)\n", This, metrics);
- memcpy(metrics, &This->metrics, sizeof(*metrics));
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p, %p.\n", iface, metrics);
+
+ memcpy(metrics, &fontface->metrics, sizeof(*metrics));
}
-static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace4 *iface)
+static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
+ TRACE("%p.\n", iface);
+
return freetype_get_glyphcount(iface);
}
-static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace4 *iface,
+static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *iface,
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways)
{
- struct dwrite_fontface *fontface = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
unsigned int i;
HRESULT hr;
@@ -644,50 +662,48 @@ static HRESULT fontface_get_glyphs(struct dwrite_fontface *fontface, UINT32 cons
return E_INVALIDARG;
}
- freetype_get_glyphs(&fontface->IDWriteFontFace4_iface, fontface->charmap, codepoints, count, glyphs);
+ freetype_get_glyphs(&fontface->IDWriteFontFace5_iface, fontface->charmap, codepoints, count, glyphs);
return S_OK;
}
-static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace4 *iface, UINT32 const *codepoints,
+static HRESULT WINAPI dwritefontface_GetGlyphIndices(IDWriteFontFace5 *iface, UINT32 const *codepoints,
UINT32 count, UINT16 *glyphs)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
- TRACE("(%p)->(%p %u %p)\n", This, codepoints, count, glyphs);
+ TRACE("%p, %p, %u, %p.\n", iface, codepoints, count, glyphs);
- return fontface_get_glyphs(This, codepoints, count, glyphs);
+ return fontface_get_glyphs(fontface, codepoints, count, glyphs);
}
-static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace4 *iface, UINT32 table_tag,
+static HRESULT WINAPI dwritefontface_TryGetFontTable(IDWriteFontFace5 *iface, UINT32 table_tag,
const void **table_data, UINT32 *table_size, void **context, BOOL *exists)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
struct file_stream_desc stream_desc;
- TRACE("(%p)->(%s %p %p %p %p)\n", This, debugstr_tag(table_tag), table_data, table_size, context, exists);
+ TRACE("%p, %s, %p, %p, %p, %p.\n", iface, debugstr_tag(table_tag), table_data, table_size, context, exists);
- stream_desc.stream = This->stream;
- stream_desc.face_type = This->type;
- stream_desc.face_index = This->index;
+ stream_desc.stream = fontface->stream;
+ stream_desc.face_type = fontface->type;
+ stream_desc.face_index = fontface->index;
return opentype_get_font_table(&stream_desc, table_tag, table_data, context, table_size, exists);
}
-static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace4 *iface, void *table_context)
+static void WINAPI dwritefontface_ReleaseFontTable(IDWriteFontFace5 *iface, void *table_context)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
- TRACE("(%p)->(%p)\n", This, table_context);
+ TRACE("%p, %p.\n", iface, table_context);
- IDWriteFontFileStream_ReleaseFileFragment(This->stream, table_context);
+ IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, table_context);
}
-static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace4 *iface, FLOAT emSize,
+static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface, FLOAT emSize,
UINT16 const *glyphs, FLOAT const* advances, DWRITE_GLYPH_OFFSET const *offsets,
UINT32 count, BOOL is_sideways, BOOL is_rtl, IDWriteGeometrySink *sink)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
-
- TRACE("(%p)->(%.2f %p %p %p %u %d %d %p)\n", This, emSize, glyphs, advances, offsets,
+ TRACE("%p, %.8e, %p, %p, %p, %u, %d, %d, %p.\n", iface, emSize, glyphs, advances, offsets,
count, is_sideways, is_rtl, sink);
if (!glyphs || !sink)
@@ -727,14 +743,14 @@ static DWRITE_RENDERING_MODE fontface_renderingmode_from_measuringmode(DWRITE_ME
return mode;
}
-static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace4 *iface, FLOAT emSize,
+static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace5 *iface, FLOAT emSize,
FLOAT ppdip, DWRITE_MEASURING_MODE measuring, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE *mode)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
unsigned int flags;
FLOAT ppem;
- TRACE("(%p)->(%.2f %.2f %d %p %p)\n", This, emSize, ppdip, measuring, params, mode);
+ TRACE("%p, %.8e, %.8e, %d, %p, %p.\n", iface, emSize, ppdip, measuring, params, mode);
if (!params) {
*mode = DWRITE_RENDERING_MODE_DEFAULT;
@@ -752,16 +768,16 @@ static HRESULT WINAPI dwritefontface_GetRecommendedRenderingMode(IDWriteFontFace
return S_OK;
}
- flags = opentype_get_gasp_flags(get_fontface_gasp(This), ppem);
+ flags = opentype_get_gasp_flags(get_fontface_gasp(fontface), ppem);
*mode = fontface_renderingmode_from_measuringmode(measuring, ppem, flags);
return S_OK;
}
-static HRESULT WINAPI dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace4 *iface, FLOAT emSize, FLOAT pixels_per_dip,
+static HRESULT WINAPI dwritefontface_GetGdiCompatibleMetrics(IDWriteFontFace5 *iface, FLOAT emSize, FLOAT pixels_per_dip,
DWRITE_MATRIX const *transform, DWRITE_FONT_METRICS *metrics)
{
DWRITE_FONT_METRICS1 metrics1;
- HRESULT hr = IDWriteFontFace4_GetGdiCompatibleMetrics(iface, emSize, pixels_per_dip, transform, &metrics1);
+ HRESULT hr = IDWriteFontFace5_GetGdiCompatibleMetrics(iface, emSize, pixels_per_dip, transform, &metrics1);
memcpy(metrics, &metrics1, sizeof(*metrics));
return hr;
}
@@ -779,25 +795,25 @@ static UINT32 fontface_get_horz_metric_adjustment(const struct dwrite_fontface *
return (fontface->metrics.designUnitsPerEm + 49) / 50;
}
-static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace4 *iface, FLOAT emSize, FLOAT ppdip,
+static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFace5 *iface, FLOAT emSize, FLOAT ppdip,
DWRITE_MATRIX const *m, BOOL use_gdi_natural, UINT16 const *glyphs, UINT32 glyph_count,
DWRITE_GLYPH_METRICS *metrics, BOOL is_sideways)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- UINT32 adjustment = fontface_get_horz_metric_adjustment(This);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+ UINT32 adjustment = fontface_get_horz_metric_adjustment(fontface);
DWRITE_MEASURING_MODE mode;
FLOAT scale, size;
HRESULT hr;
UINT32 i;
- TRACE("(%p)->(%.2f %.2f %p %d %p %u %p %d)\n", This, emSize, ppdip, m, use_gdi_natural, glyphs,
+ TRACE("%p, %.8e, %.8e, %p, %d, %p, %u, %p, %d.\n", iface, emSize, ppdip, m, use_gdi_natural, glyphs,
glyph_count, metrics, is_sideways);
if (m && memcmp(m, &identity, sizeof(*m)))
FIXME("transform is not supported, %s\n", debugstr_matrix(m));
size = emSize * ppdip;
- scale = size / This->metrics.designUnitsPerEm;
+ scale = size / fontface->metrics.designUnitsPerEm;
mode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC;
for (i = 0; i < glyph_count; i++) {
@@ -805,15 +821,15 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac
DWRITE_GLYPH_METRICS design;
BOOL has_contours;
- hr = IDWriteFontFace4_GetDesignGlyphMetrics(iface, glyphs + i, 1, &design, is_sideways);
+ hr = IDWriteFontFace5_GetDesignGlyphMetrics(iface, glyphs + i, 1, &design, is_sideways);
if (FAILED(hr))
return hr;
ret->advanceWidth = freetype_get_glyph_advance(iface, size, glyphs[i], mode, &has_contours);
if (has_contours)
- ret->advanceWidth = round_metric(ret->advanceWidth * This->metrics.designUnitsPerEm / size + adjustment);
+ ret->advanceWidth = round_metric(ret->advanceWidth * fontface->metrics.designUnitsPerEm / size + adjustment);
else
- ret->advanceWidth = round_metric(ret->advanceWidth * This->metrics.designUnitsPerEm / size);
+ ret->advanceWidth = round_metric(ret->advanceWidth * fontface->metrics.designUnitsPerEm / size);
#define SCALE_METRIC(x) ret->x = round_metric(round_metric((design.x) * scale) / scale)
SCALE_METRIC(leftSideBearing);
@@ -828,22 +844,24 @@ static HRESULT WINAPI dwritefontface_GetGdiCompatibleGlyphMetrics(IDWriteFontFac
return S_OK;
}
-static void WINAPI dwritefontface1_GetMetrics(IDWriteFontFace4 *iface, DWRITE_FONT_METRICS1 *metrics)
+static void WINAPI dwritefontface1_GetMetrics(IDWriteFontFace5 *iface, DWRITE_FONT_METRICS1 *metrics)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)->(%p)\n", This, metrics);
- *metrics = This->metrics;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p, %p.\n", iface, metrics);
+
+ *metrics = fontface->metrics;
}
-static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace4 *iface, FLOAT em_size, FLOAT pixels_per_dip,
- const DWRITE_MATRIX *m, DWRITE_FONT_METRICS1 *metrics)
+static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace5 *iface, FLOAT em_size,
+ FLOAT pixels_per_dip, const DWRITE_MATRIX *m, DWRITE_FONT_METRICS1 *metrics)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- const DWRITE_FONT_METRICS1 *design = &This->metrics;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+ const DWRITE_FONT_METRICS1 *design = &fontface->metrics;
UINT16 ascent, descent;
FLOAT scale;
- TRACE("(%p)->(%.2f %.2f %p %p)\n", This, em_size, pixels_per_dip, m, metrics);
+ TRACE("%p, %.8e, %.8e, %p, %p.\n", iface, em_size, pixels_per_dip, m, metrics);
if (em_size <= 0.0f || pixels_per_dip <= 0.0f) {
memset(metrics, 0, sizeof(*metrics));
@@ -855,7 +873,8 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace4 *
em_size *= fabs(m->m22);
scale = em_size / design->designUnitsPerEm;
- if (!opentype_get_vdmx_size(get_fontface_vdmx(This), em_size, &ascent, &descent)) {
+ if (!opentype_get_vdmx_size(get_fontface_vdmx(fontface), em_size, &ascent, &descent))
+ {
ascent = round_metric(design->ascent * scale);
descent = round_metric(design->descent * scale);
}
@@ -891,33 +910,37 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleMetrics(IDWriteFontFace4 *
return S_OK;
}
-static void WINAPI dwritefontface1_GetCaretMetrics(IDWriteFontFace4 *iface, DWRITE_CARET_METRICS *metrics)
+static void WINAPI dwritefontface1_GetCaretMetrics(IDWriteFontFace5 *iface, DWRITE_CARET_METRICS *metrics)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)->(%p)\n", This, metrics);
- *metrics = This->caret;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p, %p.\n", iface, metrics);
+
+ *metrics = fontface->caret;
}
-static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace4 *iface, UINT32 max_count,
+static HRESULT WINAPI dwritefontface1_GetUnicodeRanges(IDWriteFontFace5 *iface, UINT32 max_count,
DWRITE_UNICODE_RANGE *ranges, UINT32 *count)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
- TRACE("(%p)->(%u %p %p)\n", This, max_count, ranges, count);
+ TRACE("%p, %u, %p, %p.\n", iface, max_count, ranges, count);
*count = 0;
if (max_count && !ranges)
return E_INVALIDARG;
- get_fontface_table(iface, MS_CMAP_TAG, &This->cmap);
- return opentype_cmap_get_unicode_ranges(&This->cmap, max_count, ranges, count);
+ get_fontface_table(iface, MS_CMAP_TAG, &fontface->cmap);
+ return opentype_cmap_get_unicode_ranges(&fontface->cmap, max_count, ranges, count);
}
-static BOOL WINAPI dwritefontface1_IsMonospacedFont(IDWriteFontFace4 *iface)
+static BOOL WINAPI dwritefontface1_IsMonospacedFont(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return !!(This->flags & FONTFACE_IS_MONOSPACED);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return !!(fontface->flags & FONTFACE_IS_MONOSPACED);
}
static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_MEASURING_MODE measuring_mode,
@@ -933,7 +956,7 @@ static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_
switch (measuring_mode)
{
case DWRITE_MEASURING_MODE_NATURAL:
- advance = freetype_get_glyph_advance(&fontface->IDWriteFontFace4_iface, fontface->metrics.designUnitsPerEm,
+ advance = freetype_get_glyph_advance(&fontface->IDWriteFontFace5_iface, fontface->metrics.designUnitsPerEm,
glyph, measuring_mode, &has_contours);
if (has_contours)
advance += adjustment;
@@ -948,7 +971,7 @@ static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_
if (transform && memcmp(transform, &identity, sizeof(*transform)))
FIXME("Transform is not supported.\n");
- advance = freetype_get_glyph_advance(&fontface->IDWriteFontFace4_iface, emsize, glyph, measuring_mode,
+ advance = freetype_get_glyph_advance(&fontface->IDWriteFontFace5_iface, emsize, glyph, measuring_mode,
&has_contours);
if (has_contours)
advance = round_metric(advance * fontface->metrics.designUnitsPerEm / emsize + adjustment);
@@ -962,35 +985,35 @@ static int fontface_get_design_advance(struct dwrite_fontface *fontface, DWRITE_
}
}
-static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace4 *iface,
+static HRESULT WINAPI dwritefontface1_GetDesignGlyphAdvances(IDWriteFontFace5 *iface,
UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances, BOOL is_sideways)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
unsigned int i;
- TRACE("(%p)->(%u %p %p %d)\n", This, glyph_count, glyphs, advances, is_sideways);
+ TRACE("%p, %u, %p, %p, %d.\n", iface, glyph_count, glyphs, advances, is_sideways);
if (is_sideways)
FIXME("sideways mode not supported\n");
for (i = 0; i < glyph_count; ++i)
{
- advances[i] = fontface_get_design_advance(This, DWRITE_MEASURING_MODE_NATURAL, This->metrics.designUnitsPerEm,
- 1.0f, NULL, glyphs[i], is_sideways);
+ advances[i] = fontface_get_design_advance(fontface, DWRITE_MEASURING_MODE_NATURAL,
+ fontface->metrics.designUnitsPerEm, 1.0f, NULL, glyphs[i], is_sideways);
}
return S_OK;
}
-static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace4 *iface,
+static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontFace5 *iface,
float em_size, float ppdip, const DWRITE_MATRIX *transform, BOOL use_gdi_natural,
BOOL is_sideways, UINT32 glyph_count, UINT16 const *glyphs, INT32 *advances)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
DWRITE_MEASURING_MODE measuring_mode;
UINT32 i;
- TRACE("(%p)->(%.2f %.2f %p %d %d %u %p %p)\n", This, em_size, ppdip, transform,
+ TRACE("%p, %.8e, %.8e, %p, %d, %d, %u, %p, %p.\n", iface, em_size, ppdip, transform,
use_gdi_natural, is_sideways, glyph_count, glyphs, advances);
if (em_size < 0.0f || ppdip <= 0.0f) {
@@ -1006,20 +1029,20 @@ static HRESULT WINAPI dwritefontface1_GetGdiCompatibleGlyphAdvances(IDWriteFontF
measuring_mode = use_gdi_natural ? DWRITE_MEASURING_MODE_GDI_NATURAL : DWRITE_MEASURING_MODE_GDI_CLASSIC;
for (i = 0; i < glyph_count; ++i)
{
- advances[i] = fontface_get_design_advance(This, measuring_mode, em_size, ppdip, transform,
+ advances[i] = fontface_get_design_advance(fontface, measuring_mode, em_size, ppdip, transform,
glyphs[i], is_sideways);
}
return S_OK;
}
-static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace4 *iface, UINT32 count,
+static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace5 *iface, UINT32 count,
const UINT16 *indices, INT32 *adjustments)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
UINT32 i;
- TRACE("(%p)->(%u %p %p)\n", This, count, indices, adjustments);
+ TRACE("%p, %u, %p, %p.\n", iface, count, indices, adjustments);
if (!(indices || adjustments) || !count)
return E_INVALIDARG;
@@ -1029,7 +1052,8 @@ static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace4
return E_INVALIDARG;
}
- if (!(This->flags & FONTFACE_HAS_KERNING_PAIRS)) {
+ if (!(fontface->flags & FONTFACE_HAS_KERNING_PAIRS))
+ {
memset(adjustments, 0, count*sizeof(INT32));
return S_OK;
}
@@ -1041,76 +1065,88 @@ static HRESULT WINAPI dwritefontface1_GetKerningPairAdjustments(IDWriteFontFace4
return S_OK;
}
-static BOOL WINAPI dwritefontface1_HasKerningPairs(IDWriteFontFace4 *iface)
+static BOOL WINAPI dwritefontface1_HasKerningPairs(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return !!(This->flags & FONTFACE_HAS_KERNING_PAIRS);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return !!(fontface->flags & FONTFACE_HAS_KERNING_PAIRS);
}
-static HRESULT WINAPI dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace4 *iface,
+static HRESULT WINAPI dwritefontface1_GetRecommendedRenderingMode(IDWriteFontFace5 *iface,
FLOAT font_emsize, FLOAT dpiX, FLOAT dpiY, const DWRITE_MATRIX *transform, BOOL is_sideways,
DWRITE_OUTLINE_THRESHOLD threshold, DWRITE_MEASURING_MODE measuring_mode, DWRITE_RENDERING_MODE *rendering_mode)
{
DWRITE_GRID_FIT_MODE gridfitmode;
- return IDWriteFontFace2_GetRecommendedRenderingMode((IDWriteFontFace2*)iface, font_emsize, dpiX, dpiY, transform, is_sideways,
- threshold, measuring_mode, NULL, rendering_mode, &gridfitmode);
+ return IDWriteFontFace2_GetRecommendedRenderingMode((IDWriteFontFace2 *)iface, font_emsize, dpiX, dpiY, transform,
+ is_sideways, threshold, measuring_mode, NULL, rendering_mode, &gridfitmode);
}
-static HRESULT WINAPI dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace4 *iface, UINT32 glyph_count,
+static HRESULT WINAPI dwritefontface1_GetVerticalGlyphVariants(IDWriteFontFace5 *iface, UINT32 glyph_count,
const UINT16 *nominal_indices, UINT16 *vertical_indices)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%u %p %p): stub\n", This, glyph_count, nominal_indices, vertical_indices);
+ FIXME("%p, %u, %p, %p: stub\n", iface, glyph_count, nominal_indices, vertical_indices);
+
return E_NOTIMPL;
}
-static BOOL WINAPI dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace4 *iface)
+static BOOL WINAPI dwritefontface1_HasVerticalGlyphVariants(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return !!(This->flags & FONTFACE_HAS_VERTICAL_VARIANTS);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return !!(fontface->flags & FONTFACE_HAS_VERTICAL_VARIANTS);
}
-static BOOL WINAPI dwritefontface2_IsColorFont(IDWriteFontFace4 *iface)
+static BOOL WINAPI dwritefontface2_IsColorFont(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return get_fontface_cpal(This) && get_fontface_colr(This);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return get_fontface_cpal(fontface) && get_fontface_colr(fontface);
}
-static UINT32 WINAPI dwritefontface2_GetColorPaletteCount(IDWriteFontFace4 *iface)
+static UINT32 WINAPI dwritefontface2_GetColorPaletteCount(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return opentype_get_cpal_palettecount(get_fontface_cpal(This));
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return opentype_get_cpal_palettecount(get_fontface_cpal(fontface));
}
-static UINT32 WINAPI dwritefontface2_GetPaletteEntryCount(IDWriteFontFace4 *iface)
+static UINT32 WINAPI dwritefontface2_GetPaletteEntryCount(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return opentype_get_cpal_paletteentrycount(get_fontface_cpal(This));
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return opentype_get_cpal_paletteentrycount(get_fontface_cpal(fontface));
}
-static HRESULT WINAPI dwritefontface2_GetPaletteEntries(IDWriteFontFace4 *iface, UINT32 palette_index,
+static HRESULT WINAPI dwritefontface2_GetPaletteEntries(IDWriteFontFace5 *iface, UINT32 palette_index,
UINT32 first_entry_index, UINT32 entry_count, DWRITE_COLOR_F *entries)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)->(%u %u %u %p)\n", This, palette_index, first_entry_index, entry_count, entries);
- return opentype_get_cpal_entries(get_fontface_cpal(This), palette_index, first_entry_index, entry_count, entries);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p, %u, %u, %u, %p.\n", iface, palette_index, first_entry_index, entry_count, entries);
+
+ return opentype_get_cpal_entries(get_fontface_cpal(fontface), palette_index, first_entry_index, entry_count, entries);
}
-static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace4 *iface, FLOAT emSize,
+static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFace5 *iface, FLOAT emSize,
FLOAT dpiX, FLOAT dpiY, DWRITE_MATRIX const *m, BOOL is_sideways, DWRITE_OUTLINE_THRESHOLD threshold,
DWRITE_MEASURING_MODE measuringmode, IDWriteRenderingParams *params, DWRITE_RENDERING_MODE *renderingmode,
DWRITE_GRID_FIT_MODE *gridfitmode)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
unsigned int flags;
FLOAT emthreshold;
- TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold,
+ TRACE("%p, %.8e, %.8e, %.8e, %p, %d, %d, %d, %p, %p, %p.\n", iface, emSize, dpiX, dpiY, m, is_sideways, threshold,
measuringmode, params, renderingmode, gridfitmode);
if (m)
@@ -1139,7 +1175,7 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac
emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD;
- flags = opentype_get_gasp_flags(get_fontface_gasp(This), emSize);
+ flags = opentype_get_gasp_flags(get_fontface_gasp(fontface), emSize);
if (*renderingmode == DWRITE_RENDERING_MODE_DEFAULT) {
if (emSize >= emthreshold)
@@ -1161,86 +1197,94 @@ static HRESULT WINAPI dwritefontface2_GetRecommendedRenderingMode(IDWriteFontFac
return S_OK;
}
-static HRESULT WINAPI dwritefontface3_GetFontFaceReference(IDWriteFontFace4 *iface, IDWriteFontFaceReference **ref)
+static HRESULT WINAPI dwritefontface3_GetFontFaceReference(IDWriteFontFace5 *iface, IDWriteFontFaceReference **ref)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%p): stub\n", This, ref);
+ FIXME("%p, %p: stub\n", iface, ref);
+
return E_NOTIMPL;
}
-static void WINAPI dwritefontface3_GetPanose(IDWriteFontFace4 *iface, DWRITE_PANOSE *panose)
+static void WINAPI dwritefontface3_GetPanose(IDWriteFontFace5 *iface, DWRITE_PANOSE *panose)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)->(%p)\n", This, panose);
- *panose = This->panose;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p, %p.\n", iface, panose);
+
+ *panose = fontface->panose;
}
-static DWRITE_FONT_WEIGHT WINAPI dwritefontface3_GetWeight(IDWriteFontFace4 *iface)
+static DWRITE_FONT_WEIGHT WINAPI dwritefontface3_GetWeight(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return This->weight;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return fontface->weight;
}
-static DWRITE_FONT_STRETCH WINAPI dwritefontface3_GetStretch(IDWriteFontFace4 *iface)
+static DWRITE_FONT_STRETCH WINAPI dwritefontface3_GetStretch(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return This->stretch;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return fontface->stretch;
}
-static DWRITE_FONT_STYLE WINAPI dwritefontface3_GetStyle(IDWriteFontFace4 *iface)
+static DWRITE_FONT_STYLE WINAPI dwritefontface3_GetStyle(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- TRACE("(%p)\n", This);
- return This->style;
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+
+ TRACE("%p.\n", iface);
+
+ return fontface->style;
}
-static HRESULT WINAPI dwritefontface3_GetFamilyNames(IDWriteFontFace4 *iface, IDWriteLocalizedStrings **names)
+static HRESULT WINAPI dwritefontface3_GetFamilyNames(IDWriteFontFace5 *iface, IDWriteLocalizedStrings **names)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%p): stub\n", This, names);
+ FIXME("%p, %p: stub\n", iface, names);
+
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefontface3_GetFaceNames(IDWriteFontFace4 *iface, IDWriteLocalizedStrings **names)
+static HRESULT WINAPI dwritefontface3_GetFaceNames(IDWriteFontFace5 *iface, IDWriteLocalizedStrings **names)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%p): stub\n", This, names);
+ FIXME("%p, %p: stub\n", iface, names);
+
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefontface3_GetInformationalStrings(IDWriteFontFace4 *iface, DWRITE_INFORMATIONAL_STRING_ID stringid,
- IDWriteLocalizedStrings **strings, BOOL *exists)
+static HRESULT WINAPI dwritefontface3_GetInformationalStrings(IDWriteFontFace5 *iface,
+ DWRITE_INFORMATIONAL_STRING_ID stringid, IDWriteLocalizedStrings **strings, BOOL *exists)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%u %p %p): stub\n", This, stringid, strings, exists);
+ FIXME("%p, %u, %p, %p: stub\n", iface, stringid, strings, exists);
+
return E_NOTIMPL;
}
-static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace4 *iface, UINT32 ch)
+static BOOL WINAPI dwritefontface3_HasCharacter(IDWriteFontFace5 *iface, UINT32 ch)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
UINT16 index;
- TRACE("(%p)->(%#x)\n", This, ch);
+ TRACE("%p, %#x.\n", iface, ch);
index = 0;
- if (FAILED(fontface_get_glyphs(This, &ch, 1, &index)))
+ if (FAILED(fontface_get_glyphs(fontface, &ch, 1, &index)))
return FALSE;
return index != 0;
}
-static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFace4 *iface, FLOAT emSize, FLOAT dpiX, FLOAT dpiY,
+static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFace5 *iface, FLOAT emSize, FLOAT dpiX, FLOAT dpiY,
DWRITE_MATRIX const *m, BOOL is_sideways, DWRITE_OUTLINE_THRESHOLD threshold, DWRITE_MEASURING_MODE measuring_mode,
IDWriteRenderingParams *params, DWRITE_RENDERING_MODE1 *rendering_mode, DWRITE_GRID_FIT_MODE *gridfit_mode)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
unsigned int flags;
FLOAT emthreshold;
- TRACE("(%p)->(%.2f %.2f %.2f %p %d %d %d %p %p %p)\n", This, emSize, dpiX, dpiY, m, is_sideways, threshold,
+ TRACE("%p, %.8e, %.8e, %.8e, %p, %d, %d, %d, %p, %p, %p.\n", iface, emSize, dpiX, dpiY, m, is_sideways, threshold,
measuring_mode, params, rendering_mode, gridfit_mode);
if (m)
@@ -1269,7 +1313,7 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac
emthreshold = threshold == DWRITE_OUTLINE_THRESHOLD_ANTIALIASED ? RECOMMENDED_OUTLINE_AA_THRESHOLD : RECOMMENDED_OUTLINE_A_THRESHOLD;
- flags = opentype_get_gasp_flags(get_fontface_gasp(This), emSize);
+ flags = opentype_get_gasp_flags(get_fontface_gasp(fontface), emSize);
if (*rendering_mode == DWRITE_RENDERING_MODE1_DEFAULT) {
if (emSize >= emthreshold)
@@ -1291,68 +1335,97 @@ static HRESULT WINAPI dwritefontface3_GetRecommendedRenderingMode(IDWriteFontFac
return S_OK;
}
-static BOOL WINAPI dwritefontface3_IsCharacterLocal(IDWriteFontFace4 *iface, UINT32 ch)
+static BOOL WINAPI dwritefontface3_IsCharacterLocal(IDWriteFontFace5 *iface, UINT32 ch)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(0x%x): stub\n", This, ch);
+ FIXME("%p, %#x: stub\n", iface, ch);
+
return FALSE;
}
-static BOOL WINAPI dwritefontface3_IsGlyphLocal(IDWriteFontFace4 *iface, UINT16 glyph)
+static BOOL WINAPI dwritefontface3_IsGlyphLocal(IDWriteFontFace5 *iface, UINT16 glyph)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%u): stub\n", This, glyph);
+ FIXME("%p, %u: stub\n", iface, glyph);
+
return FALSE;
}
-static HRESULT WINAPI dwritefontface3_AreCharactersLocal(IDWriteFontFace4 *iface, WCHAR const *text,
+static HRESULT WINAPI dwritefontface3_AreCharactersLocal(IDWriteFontFace5 *iface, WCHAR const *text,
UINT32 count, BOOL enqueue_if_not, BOOL *are_local)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%s:%u %d %p): stub\n", This, debugstr_wn(text, count), count, enqueue_if_not, are_local);
+ FIXME("%p, %s:%u, %d %p: stub\n", iface, debugstr_wn(text, count), count, enqueue_if_not, are_local);
+
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefontface3_AreGlyphsLocal(IDWriteFontFace4 *iface, UINT16 const *glyphs,
+static HRESULT WINAPI dwritefontface3_AreGlyphsLocal(IDWriteFontFace5 *iface, UINT16 const *glyphs,
UINT32 count, BOOL enqueue_if_not, BOOL *are_local)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%p %u %d %p): stub\n", This, glyphs, count, enqueue_if_not, are_local);
+ FIXME("%p, %p, %u, %d, %p: stub\n", iface, glyphs, count, enqueue_if_not, are_local);
+
return E_NOTIMPL;
}
-static HRESULT WINAPI dwritefontface4_GetGlyphImageFormats_(IDWriteFontFace4 *iface, UINT16 glyph,
+static HRESULT WINAPI dwritefontface4_GetGlyphImageFormats_(IDWriteFontFace5 *iface, UINT16 glyph,
UINT32 ppem_first, UINT32 ppem_last, DWRITE_GLYPH_IMAGE_FORMATS *formats)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%u %u %u %p): stub\n", This, glyph, ppem_first, ppem_last, formats);
+ FIXME("%p, %u, %u, %u, %p: stub\n", iface, glyph, ppem_first, ppem_last, formats);
+
return E_NOTIMPL;
}
-static DWRITE_GLYPH_IMAGE_FORMATS WINAPI dwritefontface4_GetGlyphImageFormats(IDWriteFontFace4 *iface)
+static DWRITE_GLYPH_IMAGE_FORMATS WINAPI dwritefontface4_GetGlyphImageFormats(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
- TRACE("(%p)\n", This);
+ TRACE("%p.\n", iface);
- return This->glyph_image_formats;
+ return fontface->glyph_image_formats;
}
-static HRESULT WINAPI dwritefontface4_GetGlyphImageData(IDWriteFontFace4 *iface, UINT16 glyph,
+static HRESULT WINAPI dwritefontface4_GetGlyphImageData(IDWriteFontFace5 *iface, UINT16 glyph,
UINT32 ppem, DWRITE_GLYPH_IMAGE_FORMATS format, DWRITE_GLYPH_IMAGE_DATA *data, void **context)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%u %u %d %p %p): stub\n", This, glyph, ppem, format, data, context);
+ FIXME("%p, %u, %u, %d, %p, %p: stub\n", iface, glyph, ppem, format, data, context);
+
+ return E_NOTIMPL;
+}
+
+static void WINAPI dwritefontface4_ReleaseGlyphImageData(IDWriteFontFace5 *iface, void *context)
+{
+ FIXME("%p, %p: stub\n", iface, context);
+}
+
+static UINT32 WINAPI dwritefontface5_GetFontAxisValueCount(IDWriteFontFace5 *iface)
+{
+ FIXME("%p: stub\n", iface);
+
+ return 0;
+}
+
+static HRESULT WINAPI dwritefontface5_GetFontAxisValues(IDWriteFontFace5 *iface, DWRITE_FONT_AXIS_VALUE *axis_values,
+ UINT32 value_count)
+{
+ FIXME("%p, %p, %u: stub\n", iface, axis_values, value_count);
+
return E_NOTIMPL;
}
-static void WINAPI dwritefontface4_ReleaseGlyphImageData(IDWriteFontFace4 *iface, void *context)
+static BOOL WINAPI dwritefontface5_HasVariantions(IDWriteFontFace5 *iface)
{
- struct dwrite_fontface *This = impl_from_IDWriteFontFace4(iface);
- FIXME("(%p)->(%p): stub\n", This, context);
+ FIXME("%p: stub\n", iface);
+
+ return FALSE;
}
-static const IDWriteFontFace4Vtbl dwritefontfacevtbl = {
+static HRESULT WINAPI dwritefontface5_GetFontResource(IDWriteFontFace5 *iface, IDWriteFontResource **resource)
+{
+ FIXME("%p, %p: stub\n", iface, resource);
+
+ return E_NOTIMPL;
+}
+
+static const IDWriteFontFace5Vtbl dwritefontfacevtbl =
+{
dwritefontface_QueryInterface,
dwritefontface_AddRef,
dwritefontface_Release,
@@ -1405,10 +1478,14 @@ static const IDWriteFontFace4Vtbl dwritefontfacevtbl = {
dwritefontface4_GetGlyphImageFormats_,
dwritefontface4_GetGlyphImageFormats,
dwritefontface4_GetGlyphImageData,
- dwritefontface4_ReleaseGlyphImageData
+ dwritefontface4_ReleaseGlyphImageData,
+ dwritefontface5_GetFontAxisValueCount,
+ dwritefontface5_GetFontAxisValues,
+ dwritefontface5_HasVariantions,
+ dwritefontface5_GetFontResource,
};
-static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace4 **fontface)
+static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace5 **fontface)
{
struct dwrite_font_data *data = font->data;
struct fontface_desc desc;
@@ -1518,19 +1595,19 @@ static DWRITE_FONT_STYLE WINAPI dwritefont_GetStyle(IDWriteFont3 *iface)
static BOOL WINAPI dwritefont_IsSymbolFont(IDWriteFont3 *iface)
{
- struct dwrite_font *This = impl_from_IDWriteFont3(iface);
- IDWriteFontFace4 *fontface;
+ struct dwrite_font *font = impl_from_IDWriteFont3(iface);
+ IDWriteFontFace5 *fontface;
HRESULT hr;
BOOL ret;
- TRACE("(%p)\n", This);
+ TRACE("%p.\n", iface);
- hr = get_fontface_from_font(This, &fontface);
+ hr = get_fontface_from_font(font, &fontface);
if (FAILED(hr))
return FALSE;
- ret = IDWriteFontFace4_IsSymbolFont(fontface);
- IDWriteFontFace4_Release(fontface);
+ ret = IDWriteFontFace5_IsSymbolFont(fontface);
+ IDWriteFontFace5_Release(fontface);
return ret;
}
@@ -1544,11 +1621,11 @@ static HRESULT WINAPI dwritefont_GetFaceNames(IDWriteFont3 *iface, IDWriteLocali
static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface,
DWRITE_INFORMATIONAL_STRING_ID stringid, IDWriteLocalizedStrings **strings, BOOL *exists)
{
- struct dwrite_font *This = impl_from_IDWriteFont3(iface);
- struct dwrite_font_data *data = This->data;
+ struct dwrite_font *font = impl_from_IDWriteFont3(iface);
+ struct dwrite_font_data *data = font->data;
HRESULT hr;
- TRACE("(%p)->(%d %p %p)\n", This, stringid, strings, exists);
+ TRACE("%p, %d, %p, %p.\n", iface, stringid, strings, exists);
*exists = FALSE;
*strings = NULL;
@@ -1556,29 +1633,31 @@ static HRESULT WINAPI dwritefont_GetInformationalStrings(IDWriteFont3 *iface,
if (stringid > DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME || stringid == DWRITE_INFORMATIONAL_STRING_NONE)
return S_OK;
- if (!data->info_strings[stringid]) {
- IDWriteFontFace4 *fontface;
+ if (!data->info_strings[stringid])
+ {
+ IDWriteFontFace5 *fontface;
const void *table_data;
BOOL table_exists;
void *context;
UINT32 size;
- hr = get_fontface_from_font(This, &fontface);
+ hr = get_fontface_from_font(font, &fontface);
if (FAILED(hr))
return hr;
table_exists = FALSE;
- hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_NAME_TAG, &table_data, &size, &context, &table_exists);
+ hr = IDWriteFontFace5_TryGetFontTable(fontface, MS_NAME_TAG, &table_data, &size, &context, &table_exists);
if (FAILED(hr) || !table_exists)
WARN("no NAME table found.\n");
- if (table_exists) {
+ if (table_exists)
+ {
hr = opentype_get_font_info_strings(table_data, stringid, &data->info_strings[stringid]);
- IDWriteFontFace4_ReleaseFontTable(fontface, context);
+ IDWriteFontFace5_ReleaseFontTable(fontface, context);
if (FAILED(hr) || !data->info_strings[stringid])
return hr;
}
- IDWriteFontFace4_Release(fontface);
+ IDWriteFontFace5_Release(fontface);
}
hr = clone_localizedstring(data->info_strings[stringid], strings);
@@ -1606,7 +1685,7 @@ static void WINAPI dwritefont_GetMetrics(IDWriteFont3 *iface, DWRITE_FONT_METRIC
static HRESULT font_has_character(struct dwrite_font *font, UINT32 ch, BOOL *exists)
{
- IDWriteFontFace4 *fontface;
+ IDWriteFontFace5 *fontface;
UINT16 index;
HRESULT hr;
@@ -1617,8 +1696,8 @@ static HRESULT font_has_character(struct dwrite_font *font, UINT32 ch, BOOL *exi
return hr;
index = 0;
- hr = IDWriteFontFace4_GetGlyphIndices(fontface, &ch, 1, &index);
- IDWriteFontFace4_Release(fontface);
+ hr = IDWriteFontFace5_GetGlyphIndices(fontface, &ch, 1, &index);
+ IDWriteFontFace5_Release(fontface);
if (FAILED(hr))
return hr;
@@ -1637,9 +1716,11 @@ static HRESULT WINAPI dwritefont_HasCharacter(IDWriteFont3 *iface, UINT32 ch, BO
static HRESULT WINAPI dwritefont_CreateFontFace(IDWriteFont3 *iface, IDWriteFontFace **fontface)
{
- struct dwrite_font *This = impl_from_IDWriteFont3(iface);
- TRACE("(%p)->(%p)\n", This, fontface);
- return get_fontface_from_font(This, (IDWriteFontFace4 **)fontface);
+ struct dwrite_font *font = impl_from_IDWriteFont3(iface);
+
+ TRACE("%p, %p.\n", iface, fontface);
+
+ return get_fontface_from_font(font, (IDWriteFontFace5 **)fontface);
}
static void WINAPI dwritefont1_GetMetrics(IDWriteFont3 *iface, DWRITE_FONT_METRICS1 *metrics)
@@ -1658,64 +1739,64 @@ static void WINAPI dwritefont1_GetPanose(IDWriteFont3 *iface, DWRITE_PANOSE *pan
static HRESULT WINAPI dwritefont1_GetUnicodeRanges(IDWriteFont3 *iface, UINT32 max_count, DWRITE_UNICODE_RANGE *ranges, UINT32 *count)
{
- struct dwrite_font *This = impl_from_IDWriteFont3(iface);
- IDWriteFontFace4 *fontface;
+ struct dwrite_font *font = impl_from_IDWriteFont3(iface);
+ IDWriteFontFace5 *fontface;
HRESULT hr;
- TRACE("(%p)->(%u %p %p)\n", This, max_count, ranges, count);
+ TRACE("%p, %u, %p, %p.\n", iface, max_count, ranges, count);
- hr = get_fontface_from_font(This, &fontface);
+ hr = get_fontface_from_font(font, &fontface);
if (FAILED(hr))
return hr;
- hr = IDWriteFontFace4_GetUnicodeRanges(fontface, max_count, ranges, count);
- IDWriteFontFace4_Release(fontface);
+ hr = IDWriteFontFace5_GetUnicodeRanges(fontface, max_count, ranges, count);
+ IDWriteFontFace5_Release(fontface);
return hr;
}
static BOOL WINAPI dwritefont1_IsMonospacedFont(IDWriteFont3 *iface)
{
- struct dwrite_font *This = impl_from_IDWriteFont3(iface);
- IDWriteFontFace4 *fontface;
+ struct dwrite_font *font = impl_from_IDWriteFont3(iface);
+ IDWriteFontFace5 *fontface;
HRESULT hr;
BOOL ret;
- TRACE("(%p)\n", This);
+ TRACE("%p.\n", iface);
- hr = get_fontface_from_font(This, &fontface);
+ hr = get_fontface_from_font(font, &fontface);
if (FAILED(hr))
return FALSE;
- ret = IDWriteFontFace4_IsMonospacedFont(fontface);
- IDWriteFontFace4_Release(fontface);
+ ret = IDWriteFontFace5_IsMonospacedFont(fontface);
+ IDWriteFontFace5_Release(fontface);
return ret;
}
static BOOL WINAPI dwritefont2_IsColorFont(IDWriteFont3 *iface)
{
- struct dwrite_font *This = impl_from_IDWriteFont3(iface);
- IDWriteFontFace4 *fontface;
+ struct dwrite_font *font = impl_from_IDWriteFont3(iface);
+ IDWriteFontFace5 *fontface;
HRESULT hr;
BOOL ret;
- TRACE("(%p)\n", This);
+ TRACE("%p.\n", iface);
- hr = get_fontface_from_font(This, &fontface);
+ hr = get_fontface_from_font(font, &fontface);
if (FAILED(hr))
return FALSE;
- ret = IDWriteFontFace4_IsColorFont(fontface);
- IDWriteFontFace4_Release(fontface);
+ ret = IDWriteFontFace5_IsColorFont(fontface);
+ IDWriteFontFace5_Release(fontface);
return ret;
}
static HRESULT WINAPI dwritefont3_CreateFontFace(IDWriteFont3 *iface, IDWriteFontFace3 **fontface)
{
- struct dwrite_font *This = impl_from_IDWriteFont3(iface);
+ struct dwrite_font *font = impl_from_IDWriteFont3(iface);
- TRACE("(%p)->(%p)\n", This, fontface);
+ TRACE("%p, %p.\n", iface, fontface);
- return get_fontface_from_font(This, (IDWriteFontFace4 **)fontface);
+ return get_fontface_from_font(font, (IDWriteFontFace5 **)fontface);
}
static BOOL WINAPI dwritefont3_Equals(IDWriteFont3 *iface, IDWriteFont *font)
@@ -1792,7 +1873,7 @@ struct dwrite_fontface *unsafe_impl_from_IDWriteFontFace(IDWriteFontFace *iface)
if (!iface)
return NULL;
assert(iface->lpVtbl == (IDWriteFontFaceVtbl*)&dwritefontfacevtbl);
- return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace4_iface);
+ return CONTAINING_RECORD(iface, struct dwrite_fontface, IDWriteFontFace5_iface);
}
void get_logfont_from_font(IDWriteFont *iface, LOGFONTW *lf)
@@ -4532,7 +4613,7 @@ HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_ke
return S_OK;
}
-HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list, IDWriteFontFace4 **ret)
+HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list, IDWriteFontFace5 **ret)
{
struct file_stream_desc stream_desc;
struct dwrite_fontface *fontface;
@@ -4552,8 +4633,8 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
return E_OUTOFMEMORY;
}
- fontface->IDWriteFontFace4_iface.lpVtbl = &dwritefontfacevtbl;
- fontface->ref = 1;
+ fontface->IDWriteFontFace5_iface.lpVtbl = &dwritefontfacevtbl;
+ fontface->refcount = 1;
fontface->type = desc->face_type;
fontface->file_count = desc->files_number;
fontface->cmap.exists = TRUE;
@@ -4585,16 +4666,16 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
}
}
- fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace4_iface, &is_symbol);
+ fontface->charmap = freetype_get_charmap_index(&fontface->IDWriteFontFace5_iface, &is_symbol);
if (is_symbol)
fontface->flags |= FONTFACE_IS_SYMBOL;
- if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace4_iface))
+ if (freetype_has_kerning_pairs(&fontface->IDWriteFontFace5_iface))
fontface->flags |= FONTFACE_HAS_KERNING_PAIRS;
- if (freetype_is_monospaced(&fontface->IDWriteFontFace4_iface))
+ if (freetype_is_monospaced(&fontface->IDWriteFontFace5_iface))
fontface->flags |= FONTFACE_IS_MONOSPACED;
- if (opentype_has_vertical_variants(&fontface->IDWriteFontFace4_iface))
+ if (opentype_has_vertical_variants(&fontface->IDWriteFontFace5_iface))
fontface->flags |= FONTFACE_HAS_VERTICAL_VARIANTS;
- fontface->glyph_image_formats = opentype_get_glyph_image_formats(&fontface->IDWriteFontFace4_iface);
+ fontface->glyph_image_formats = opentype_get_glyph_image_formats(&fontface->IDWriteFontFace5_iface);
/* Font properties are reused from font object when 'normal' face creation path is used:
collection -> family -> matching font -> fontface.
@@ -4614,8 +4695,9 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
struct dwrite_font_data *data;
hr = init_font_data(desc, &names, &data);
- if (FAILED(hr)) {
- IDWriteFontFace4_Release(&fontface->IDWriteFontFace4_iface);
+ if (FAILED(hr))
+ {
+ IDWriteFontFace5_Release(&fontface->IDWriteFontFace5_iface);
return hr;
}
@@ -4630,9 +4712,10 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
release_font_data(data);
}
- fontface->cached = factory_cache_fontface(fontface->factory, cached_list, &fontface->IDWriteFontFace4_iface);
+ fontface->cached = factory_cache_fontface(fontface->factory, cached_list, &fontface->IDWriteFontFace5_iface);
+
+ *ret = &fontface->IDWriteFontFace5_iface;
- *ret = &fontface->IDWriteFontFace4_iface;
return S_OK;
}
@@ -5670,8 +5753,8 @@ static ULONG WINAPI colorglyphenum_Release(IDWriteColorGlyphRunEnumerator1 *ifac
heap_free(glyphenum->glyphindices);
heap_free(glyphenum->glyphs);
if (glyphenum->colr.context)
- IDWriteFontFace4_ReleaseFontTable(glyphenum->fontface, glyphenum->colr.context);
- IDWriteFontFace4_Release(glyphenum->fontface);
+ IDWriteFontFace5_ReleaseFontTable(glyphenum->fontface, glyphenum->colr.context);
+ IDWriteFontFace5_Release(glyphenum->fontface);
heap_free(glyphenum);
}
@@ -5744,9 +5827,10 @@ static BOOL colorglyphenum_build_color_run(struct dwrite_colorglyphenum *glyphen
colorrun->paletteIndex = glyphenum->glyphs[g].palette_index;
/* use foreground color or request one from the font */
memset(&colorrun->runColor, 0, sizeof(colorrun->runColor));
- if (colorrun->paletteIndex != 0xffff) {
- HRESULT hr = IDWriteFontFace4_GetPaletteEntries(glyphenum->fontface, glyphenum->palette, colorrun->paletteIndex,
- 1, &colorrun->runColor);
+ if (colorrun->paletteIndex != 0xffff)
+ {
+ HRESULT hr = IDWriteFontFace5_GetPaletteEntries(glyphenum->fontface, glyphenum->palette,
+ colorrun->paletteIndex, 1, &colorrun->runColor);
if (FAILED(hr))
WARN("failed to get palette entry, fontface %p, palette %u, index %u, 0x%08x\n", glyphenum->fontface,
glyphenum->palette, colorrun->paletteIndex, hr);
@@ -5857,8 +5941,8 @@ HRESULT create_colorglyphenum(float originX, float originY, const DWRITE_GLYPH_R
fontface = unsafe_impl_from_IDWriteFontFace(run->fontFace);
- colorfont = IDWriteFontFace4_IsColorFont(&fontface->IDWriteFontFace4_iface) &&
- IDWriteFontFace4_GetColorPaletteCount(&fontface->IDWriteFontFace4_iface) > palette;
+ colorfont = IDWriteFontFace5_IsColorFont(&fontface->IDWriteFontFace5_iface) &&
+ IDWriteFontFace5_GetColorPaletteCount(&fontface->IDWriteFontFace5_iface) > palette;
if (!colorfont)
return DWRITE_E_NOCOLOR;
@@ -5870,8 +5954,8 @@ HRESULT create_colorglyphenum(float originX, float originY, const DWRITE_GLYPH_R
colorglyphenum->refcount = 1;
colorglyphenum->origin_x = originX;
colorglyphenum->origin_y = originY;
- colorglyphenum->fontface = &fontface->IDWriteFontFace4_iface;
- IDWriteFontFace4_AddRef(colorglyphenum->fontface);
+ colorglyphenum->fontface = &fontface->IDWriteFontFace5_iface;
+ IDWriteFontFace5_AddRef(colorglyphenum->fontface);
colorglyphenum->glyphs = NULL;
colorglyphenum->run = *run;
colorglyphenum->run.glyphIndices = NULL;
@@ -5880,7 +5964,7 @@ HRESULT create_colorglyphenum(float originX, float originY, const DWRITE_GLYPH_R
colorglyphenum->palette = palette;
memset(&colorglyphenum->colr, 0, sizeof(colorglyphenum->colr));
colorglyphenum->colr.exists = TRUE;
- get_fontface_table(&fontface->IDWriteFontFace4_iface, MS_COLR_TAG, &colorglyphenum->colr);
+ get_fontface_table(&fontface->IDWriteFontFace5_iface, MS_COLR_TAG, &colorglyphenum->colr);
colorglyphenum->current_layer = 0;
colorglyphenum->max_layer_num = 0;
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index 16317036e3..ffc97f1d8a 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -256,7 +256,7 @@ void release_freetype(void)
pFT_Done_FreeType(library);
}
-void freetype_notify_cacheremove(IDWriteFontFace4 *fontface)
+void freetype_notify_cacheremove(IDWriteFontFace5 *fontface)
{
EnterCriticalSection(&freetype_cs);
pFTC_Manager_RemoveFaceID(cache_manager, fontface);
@@ -268,7 +268,7 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT
FTC_ScalerRec scaler;
FT_Size size;
- scaler.face_id = &fontface->IDWriteFontFace4_iface;
+ scaler.face_id = &fontface->IDWriteFontFace5_iface;
scaler.width = fontface->metrics.designUnitsPerEm;
scaler.height = fontface->metrics.designUnitsPerEm;
scaler.pixel = 1;
@@ -303,7 +303,7 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT
return S_OK;
}
-BOOL freetype_is_monospaced(IDWriteFontFace4 *fontface)
+BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface)
{
BOOL is_monospaced = FALSE;
FT_Face face;
@@ -484,7 +484,7 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize)
embolden_glyph_outline(&outline_glyph->outline, emsize);
}
-HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emSize, UINT16 const *glyphs,
+HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 const *glyphs,
float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl,
IDWriteGeometrySink *sink)
{
@@ -498,7 +498,7 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emSize,
ID2D1SimplifiedGeometrySink_SetFillMode(sink, D2D1_FILL_MODE_WINDING);
- simulations = IDWriteFontFace4_GetSimulations(fontface);
+ simulations = IDWriteFontFace5_GetSimulations(fontface);
scaler.face_id = fontface;
scaler.width = emSize;
@@ -563,7 +563,7 @@ HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emSize,
return hr;
}
-UINT16 freetype_get_glyphcount(IDWriteFontFace4 *fontface)
+UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface)
{
UINT16 count = 0;
FT_Face face;
@@ -576,7 +576,7 @@ UINT16 freetype_get_glyphcount(IDWriteFontFace4 *fontface)
return count;
}
-void freetype_get_glyphs(IDWriteFontFace4 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count,
+void freetype_get_glyphs(IDWriteFontFace5 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count,
UINT16 *glyphs)
{
UINT32 i;
@@ -597,7 +597,7 @@ void freetype_get_glyphs(IDWriteFontFace4 *fontface, INT charmap, UINT32 const *
LeaveCriticalSection(&freetype_cs);
}
-BOOL freetype_has_kerning_pairs(IDWriteFontFace4 *fontface)
+BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface)
{
BOOL has_kerning_pairs = FALSE;
FT_Face face;
@@ -610,7 +610,7 @@ BOOL freetype_has_kerning_pairs(IDWriteFontFace4 *fontface)
return has_kerning_pairs;
}
-INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4 *fontface, UINT16 left, UINT16 right)
+INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace5 *fontface, UINT16 left, UINT16 right)
{
INT32 adjustment = 0;
FT_Face face;
@@ -855,7 +855,7 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
return ret;
}
-INT freetype_get_charmap_index(IDWriteFontFace4 *fontface, BOOL *is_symbol)
+INT freetype_get_charmap_index(IDWriteFontFace5 *fontface, BOOL *is_symbol)
{
INT charmap_index = -1;
FT_Face face;
@@ -887,7 +887,7 @@ INT freetype_get_charmap_index(IDWriteFontFace4 *fontface, BOOL *is_symbol)
return charmap_index;
}
-INT32 freetype_get_glyph_advance(IDWriteFontFace4 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode,
+INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode,
BOOL *has_contours)
{
FTC_ImageTypeRec imagetype;
@@ -926,7 +926,7 @@ void release_freetype(void)
{
}
-void freetype_notify_cacheremove(IDWriteFontFace4 *fontface)
+void freetype_notify_cacheremove(IDWriteFontFace5 *fontface)
{
}
@@ -935,35 +935,35 @@ HRESULT freetype_get_design_glyph_metrics(struct dwrite_fontface *fontface, UINT
return E_NOTIMPL;
}
-BOOL freetype_is_monospaced(IDWriteFontFace4 *fontface)
+BOOL freetype_is_monospaced(IDWriteFontFace5 *fontface)
{
return FALSE;
}
-HRESULT freetype_get_glyphrun_outline(IDWriteFontFace4 *fontface, float emSize, UINT16 const *glyphs,
+HRESULT freetype_get_glyphrun_outline(IDWriteFontFace5 *fontface, float emSize, UINT16 const *glyphs,
float const *advances, DWRITE_GLYPH_OFFSET const *offsets, unsigned int count, BOOL is_rtl,
IDWriteGeometrySink *sink)
{
return E_NOTIMPL;
}
-UINT16 freetype_get_glyphcount(IDWriteFontFace4 *fontface)
+UINT16 freetype_get_glyphcount(IDWriteFontFace5 *fontface)
{
return 0;
}
-void freetype_get_glyphs(IDWriteFontFace4 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count,
+void freetype_get_glyphs(IDWriteFontFace5 *fontface, INT charmap, UINT32 const *codepoints, UINT32 count,
UINT16 *glyphs)
{
memset(glyphs, 0, count * sizeof(*glyphs));
}
-BOOL freetype_has_kerning_pairs(IDWriteFontFace4 *fontface)
+BOOL freetype_has_kerning_pairs(IDWriteFontFace5 *fontface)
{
return FALSE;
}
-INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace4 *fontface, UINT16 left, UINT16 right)
+INT32 freetype_get_kerning_pair_adjustment(IDWriteFontFace5 *fontface, UINT16 left, UINT16 right)
{
return 0;
}
@@ -978,13 +978,13 @@ BOOL freetype_get_glyph_bitmap(struct dwrite_glyphbitmap *bitmap)
return FALSE;
}
-INT freetype_get_charmap_index(IDWriteFontFace4 *fontface, BOOL *is_symbol)
+INT freetype_get_charmap_index(IDWriteFontFace5 *fontface, BOOL *is_symbol)
{
*is_symbol = FALSE;
return -1;
}
-INT32 freetype_get_glyph_advance(IDWriteFontFace4 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode,
+INT32 freetype_get_glyph_advance(IDWriteFontFace5 *fontface, FLOAT emSize, UINT16 index, DWRITE_MEASURING_MODE mode,
BOOL *has_contours)
{
*has_contours = FALSE;
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index fb3ed090e6..7b97d77bd1 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -901,14 +901,14 @@ HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * co
const void *cached_key;
IDWriteFontFile *file;
- cached_face_index = IDWriteFontFace4_GetIndex(cached->fontface);
- cached_simulations = IDWriteFontFace4_GetSimulations(cached->fontface);
+ cached_face_index = IDWriteFontFace5_GetIndex(cached->fontface);
+ cached_simulations = IDWriteFontFace5_GetSimulations(cached->fontface);
/* skip earlier */
if (cached_face_index != index || cached_simulations != simulations)
continue;
- hr = IDWriteFontFace4_GetFiles(cached->fontface, &count, &file);
+ hr = IDWriteFontFace5_GetFiles(cached->fontface, &count, &file);
if (FAILED(hr))
break;
@@ -917,8 +917,9 @@ HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * co
if (FAILED(hr))
break;
- if (cached_key_size == key_size && !memcmp(cached_key, key, key_size)) {
- if (FAILED(hr = IDWriteFontFace4_QueryInterface(cached->fontface, riid, obj)))
+ if (cached_key_size == key_size && !memcmp(cached_key, key, key_size))
+ {
+ if (FAILED(hr = IDWriteFontFace5_QueryInterface(cached->fontface, riid, obj)))
WARN("Failed to get %s from fontface, hr %#x.\n", debugstr_guid(riid), hr);
TRACE("returning cached fontface %p\n", cached->fontface);
@@ -932,7 +933,7 @@ HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * co
}
struct fontfacecached *factory_cache_fontface(IDWriteFactory5 *iface, struct list *fontfaces,
- IDWriteFontFace4 *fontface)
+ IDWriteFontFace5 *fontface)
{
struct dwritefactory *factory = impl_from_IDWriteFactory5(iface);
struct fontfacecached *cached;
@@ -1011,7 +1012,7 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory5 *iface, DWRIT
desc.index = index;
desc.simulations = simulations;
desc.font_data = NULL;
- hr = create_fontface(&desc, fontfaces, (IDWriteFontFace4 **)fontface);
+ hr = create_fontface(&desc, fontfaces, (IDWriteFontFace5 **)fontface);
failed:
IDWriteFontFileStream_Release(stream);
diff --git a/dlls/dwrite/opentype.c b/dlls/dwrite/opentype.c
index efae402f91..09a9a861c3 100644
--- a/dlls/dwrite/opentype.c
+++ b/dlls/dwrite/opentype.c
@@ -2440,7 +2440,7 @@ void opentype_colr_next_glyph(const struct dwrite_fonttable *colr, struct dwrite
}
}
-BOOL opentype_has_vertical_variants(IDWriteFontFace4 *fontface)
+BOOL opentype_has_vertical_variants(IDWriteFontFace5 *fontface)
{
const struct gpos_gsub_header *header;
const struct ot_feature_list *featurelist;
@@ -2452,7 +2452,7 @@ BOOL opentype_has_vertical_variants(IDWriteFontFace4 *fontface)
UINT32 size;
HRESULT hr;
- hr = IDWriteFontFace4_TryGetFontTable(fontface, MS_GSUB_TAG, &data, &size, &context, &exists);
+ hr = IDWriteFontFace5_TryGetFontTable(fontface, MS_GSUB_TAG, &data, &size, &context, &exists);
if (FAILED(hr) || !exists)
return FALSE;
@@ -2510,12 +2510,12 @@ BOOL opentype_has_vertical_variants(IDWriteFontFace4 *fontface)
}
}
- IDWriteFontFace4_ReleaseFontTable(fontface, context);
+ IDWriteFontFace5_ReleaseFontTable(fontface, context);
return ret;
}
-static BOOL opentype_has_font_table(IDWriteFontFace4 *fontface, UINT32 tag)
+static BOOL opentype_has_font_table(IDWriteFontFace5 *fontface, UINT32 tag)
{
BOOL exists = FALSE;
const void *data;
@@ -2523,17 +2523,17 @@ static BOOL opentype_has_font_table(IDWriteFontFace4 *fontface, UINT32 tag)
UINT32 size;
HRESULT hr;
- hr = IDWriteFontFace4_TryGetFontTable(fontface, tag, &data, &size, &context, &exists);
+ hr = IDWriteFontFace5_TryGetFontTable(fontface, tag, &data, &size, &context, &exists);
if (FAILED(hr))
return FALSE;
if (exists)
- IDWriteFontFace4_ReleaseFontTable(fontface, context);
+ IDWriteFontFace5_ReleaseFontTable(fontface, context);
return exists;
}
-static unsigned int opentype_get_sbix_formats(IDWriteFontFace4 *fontface)
+static unsigned int opentype_get_sbix_formats(IDWriteFontFace5 *fontface)
{
unsigned int num_strikes, num_glyphs, i, j, ret = 0;
const struct sbix_header *sbix_header;
@@ -2547,7 +2547,7 @@ static unsigned int opentype_get_sbix_formats(IDWriteFontFace4 *fontface)
num_glyphs = table_read_be_word(&table, FIELD_OFFSET(struct maxp, num_glyphs));
- IDWriteFontFace4_ReleaseFontTable(fontface, table.context);
+ IDWriteFontFace5_ReleaseFontTable(fontface, table.context);
memset(&table, 0, sizeof(table));
table.exists = TRUE;
@@ -2600,12 +2600,12 @@ static unsigned int opentype_get_sbix_formats(IDWriteFontFace4 *fontface)
}
}
- IDWriteFontFace4_ReleaseFontTable(fontface, table.context);
+ IDWriteFontFace5_ReleaseFontTable(fontface, table.context);
return ret;
}
-static unsigned int opentype_get_cblc_formats(IDWriteFontFace4 *fontface)
+static unsigned int opentype_get_cblc_formats(IDWriteFontFace5 *fontface)
{
const unsigned int format_mask = DWRITE_GLYPH_IMAGE_FORMATS_PNG |
DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8;
@@ -2637,12 +2637,12 @@ static unsigned int opentype_get_cblc_formats(IDWriteFontFace4 *fontface)
}
}
- IDWriteFontFace4_ReleaseFontTable(fontface, cblc.context);
+ IDWriteFontFace5_ReleaseFontTable(fontface, cblc.context);
return ret;
}
-UINT32 opentype_get_glyph_image_formats(IDWriteFontFace4 *fontface)
+UINT32 opentype_get_glyph_image_formats(IDWriteFontFace5 *fontface)
{
UINT32 ret = DWRITE_GLYPH_IMAGE_FORMATS_NONE;
--
2.24.0
Dec. 2, 2019
[PATCH] testbot/LibvirtTool: Only check the start count after a reboot.
by Francois Gouget
The start count check is not related to taking live snapshots.
And we can skip it if the VM was not freshly booted.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/LibvirtTool.pl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/LibvirtTool.pl b/testbot/bin/LibvirtTool.pl
index e5dc8372e..a2939e738 100755
--- a/testbot/bin/LibvirtTool.pl
+++ b/testbot/bin/LibvirtTool.pl
@@ -463,14 +463,14 @@ sub SetupTestAgentd($$$$)
# So it all works out.
$TA->SetProperty("start.count", 0);
}
- else
+ elsif ($Booting)
{
# Check that TestAgentd is not displaying the "Has Windows rebooted?"
# warning.
my $Count = $TA->GetProperties("start.count");
if (defined $Count and $Count > 1)
{
- FatalError("Cannot take a live snapshot because start.count=$Count > 1");
+ FatalError("The VM has been rebooted too many times: start.count=$Count > 1");
}
}
$TA->Disconnect();
--
2.20.1
Dec. 2, 2019
[PATCH] testbot/LogUtils: Skip the search for new errors if there is no error.
by Francois Gouget
This avoids loading and parsing the reference log when not needed.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/LogUtils.pm | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 282906e62..51932965c 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -888,10 +888,12 @@ sub GetNewLogErrors($$$)
{
my ($RefFileName, $Groups, $Errors) = @_;
+ my (@NewGroups, %NewErrors, %NewIndices);
+ return (\@NewGroups, \%NewErrors, \%NewIndices) if (!@$Groups);
+
my ($RefGroups, $RefErrors) = GetLogErrors($RefFileName);
return (undef, undef) if (!$RefGroups);
- my (@NewGroups, %NewErrors, %NewIndices);
foreach my $GroupName (@$Groups)
{
if ($RefErrors->{$GroupName})
--
2.20.1
Dec. 2, 2019
[PATCH] testbot/WineRunTask: Move TestAgent error reporting to match WineRunWineTest.
by Francois Gouget
It belongs in the wrap up section which makes it less likely that code
will be inserted between it and WrapUpAndExit().
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 1f21050b3..a324265eb 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -584,11 +584,11 @@ elsif (!defined $TAError)
}
$TA->Disconnect();
-FatalTAError(undef, $TAError, $PossibleCrash) if (defined $TAError);
-
#
# Wrap up
#
+FatalTAError(undef, $TAError, $PossibleCrash) if (defined $TAError);
+
WrapUpAndExit($NewStatus, $TaskFailures, undef, $TaskTimedOut);
--
2.20.1
Dec. 2, 2019
[PATCH] testbotWineRunReconfig: Fix formatting of a trace.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunReconfig.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index 5c7b46bb9..985d9312e 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -503,7 +503,7 @@ if ($NewStatus eq "completed")
my $ErrMessage = $TA->GetLastError();
FatalError("Could not connect to the new ". $VM->Name ." TestAgent: $ErrMessage\n");
}
- Debug(Elapsed($Start), "Upgraded testagentd to $Version\n");
+ Debug(Elapsed($Start), " Upgraded testagentd to $Version\n");
}
}
--
2.20.1
Dec. 2, 2019
[PATCH] testbot: Fix the VM Missions validation.
by Francois Gouget
$Item->Xxx("foo") does not go through PutColValue()!
Instead AUTOLOAD sets the specified property directly, maybe fori
performance reasons, and PutColValue() is only used by DBIBackend.pm.
WineTestBot::VMs was overriding PutColValue() to only revalidate a VM's
missions field if either the VM Type of Missions field were modified.
But instead ValidateMissions was always true after loading a VM from the
database (because of the PutColValue() calls), and not when creating a
new VM (in which case all the properties are set through AUTOLOAD).
So take a snapshot of the initial Type and Missions values when the
database code resets the IsModified field by calling ResetModified();
and then revalidate them whenever they have changed.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/VMs.pm | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm
index 37ebf9a62..279b7bccd 100644
--- a/testbot/lib/WineTestBot/VMs.pm
+++ b/testbot/lib/WineTestBot/VMs.pm
@@ -304,15 +304,13 @@ sub KillChild($)
$self->ChildPid(undef);
}
-sub PutColValue($$$)
+sub ResetModified($)
{
- my ($self, $ColName, $Value) = @_;
+ my ($self) = @_;
- $self->SUPER::PutColValue($ColName, $Value);
- if ($self->{IsModified} and ($ColName eq "Type" or $ColName eq "Missions"))
- {
- $self->{ValidateMissions} = 1;
- }
+ $self->SUPER::ResetModified();
+ $self->{OldType} = $self->Type;
+ $self->{OldMissions} = $self->Missions;
}
my $_SupportedMissions = {
@@ -331,7 +329,8 @@ sub Validate($)
{
return ("Role", "Only win32, win64 and wine VMs can have a role of '" . $self->Role . "'");
}
- if ($self->{ValidateMissions})
+ if ($self->ValuesDiffer($self->{OldType}, $self->Type) or
+ $self->ValuesDiffer($self->{OldMissions}, $self->Missions))
{
my ($ErrMessage, $Missions) = ParseMissionStatement($self->Missions);
return ("Missions", $ErrMessage) if (defined $ErrMessage);
@@ -350,7 +349,8 @@ sub Validate($)
}
}
}
- delete $self->{ValidateMissions};
+ $self->{OldType} = $self->Type;
+ $self->{OldMissions} = $self->Missions;
}
return $self->SUPER::Validate();
--
2.20.1
Dec. 2, 2019
[PATCH v2 3/3] wined3d: Check dirty region dimensions.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d8/tests/visual.c | 2 +-
dlls/d3d9/tests/visual.c | 2 +-
dlls/wined3d/texture.c | 7 +++++++
3 files changed, 9 insertions(+), 2 deletions(-)
Dec. 2, 2019
[PATCH v2 2/3] d3d8/tests: Add out-of-bounds region tests.
by Akihiro Sagawa
In v2, fix todo_wine keyword position.
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d8/tests/visual.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
Dec. 2, 2019
[PATCH v2 1/3] d3d9/tests: Add out-of-bounds region tests.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d9/tests/visual.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
Dec. 2, 2019
Re: [PATCH v3 2/7] wined3d: Add functions to support device local and non-local memory info management.
by Henri Verbeet
On Mon, 2 Dec 2019 at 12:14, Conor McCarthy <cmccarthy(a)codeweavers.com> wrote:
> November 27, 2019 6:01 AM, "Henri Verbeet" <hverbeet(a)gmail.com> wrote:
> > On Mon, 25 Nov 2019 at 17:43, Conor McCarthy <cmccarthy(a)codeweavers.com> wrote:
> > Is it ever necessary to override the total amount of video memory?
> If the totals come from adapter_vk they will be correct, but adapter_gl won't have the non-local total. Should a zero total be overridden by a non-zero one? Also should totals be passed in a separate call? That could be done using a more generic messaging callback function.
>
The GL backend won't be able to query the amount of non-local video
memory (unless we add an extension, perhaps), but ultimately that's an
implementation detail, and I'm not sure how much it really matters.
Chances are we'll ultimately get that information from winex11.
> > If we have wined3d_get_adapter_memory_info(), the memory information
> > in struct wined3d_adapter_identifier becomes redundant and could be
> > removed.
>
> Should vram_bytes and sysmem_bytes stay in wined3d_driver_info though?
>
Well, they need to be stored somewhere, but that doesn't necessarily
need to be the wined3d_driver_info structure. If you think a separate
structure for adapter memory info makes sense, that's fine.
Dec. 2, 2019
[PATCH 4/4] wusa: Install updates.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
programs/wusa/Makefile.in | 2 +-
programs/wusa/main.c | 562 ++++++++++++++++++++++++++++++++++++++
programs/wusa/wusa.h | 19 ++
3 files changed, 582 insertions(+), 1 deletion(-)
diff --git a/programs/wusa/Makefile.in b/programs/wusa/Makefile.in
index 87bfe1dae0..4167747ffc 100644
--- a/programs/wusa/Makefile.in
+++ b/programs/wusa/Makefile.in
@@ -1,5 +1,5 @@
MODULE = wusa.exe
-IMPORTS = cabinet shlwapi ole32 oleaut32
+IMPORTS = cabinet shlwapi ole32 oleaut32 advapi32
EXTRADLLFLAGS = -mconsole -municode -mno-cygwin
diff --git a/programs/wusa/main.c b/programs/wusa/main.c
index 8df8731e2b..49e7dc7530 100644
--- a/programs/wusa/main.c
+++ b/programs/wusa/main.c
@@ -29,6 +29,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(wusa);
+struct strbuf
+{
+ WCHAR *buf;
+ DWORD pos;
+ DWORD len;
+};
+
struct installer_tempdir
{
struct list entry;
@@ -394,6 +401,508 @@ static BOOL load_assemblies_from_cab(const WCHAR *filename, struct installer_sta
return TRUE;
}
+static BOOL compare_assembly_string(const WCHAR *str1, const WCHAR *str2)
+{
+ return !wcscmp(str1, str2) || !wcscmp(str1, L"*") || !wcscmp(str2, L"*");
+}
+
+static struct assembly_entry *lookup_assembly(struct list *manifest_list, struct assembly_identity *identity)
+{
+ struct assembly_entry *assembly;
+
+ LIST_FOR_EACH_ENTRY(assembly, manifest_list, struct assembly_entry, entry)
+ {
+ if (wcsicmp(assembly->identity.name, identity->name)) continue;
+ if (!compare_assembly_string(assembly->identity.architecture, identity->architecture)) continue;
+ if (!compare_assembly_string(assembly->identity.language, identity->language)) continue;
+ if (!compare_assembly_string(assembly->identity.pubkey_token, identity->pubkey_token)) continue;
+ if (!compare_assembly_string(assembly->identity.version, identity->version))
+ {
+ WARN("Ignoring version difference for %s (expected %s, found %s)\n",
+ debugstr_w(identity->name), debugstr_w(identity->version), debugstr_w(assembly->identity.version));
+ }
+ return assembly;
+ }
+
+ return NULL;
+}
+
+static WCHAR *get_assembly_source(struct assembly_entry *assembly)
+{
+ WCHAR *p, *path = strdupW(assembly->filename);
+ if (path && (p = wcsrchr(path, '.'))) *p = 0;
+ return path;
+}
+
+static BOOL strbuf_init(struct strbuf *buf)
+{
+ buf->pos = 0;
+ buf->len = 64;
+ buf->buf = heap_alloc(buf->len * sizeof(WCHAR));
+ return buf->buf != NULL;
+}
+
+static void strbuf_free(struct strbuf *buf)
+{
+ heap_free(buf->buf);
+ buf->buf = NULL;
+}
+
+static BOOL strbuf_append(struct strbuf *buf, const WCHAR *str, DWORD len)
+{
+ DWORD new_len;
+ WCHAR *new_buf;
+
+ if (!buf->buf) return FALSE;
+ if (!str) return TRUE;
+
+ if (len == ~0U) len = lstrlenW(str);
+ if (buf->pos + len + 1 > buf->len)
+ {
+ new_len = max(buf->pos + len + 1, buf->len * 2);
+ new_buf = heap_realloc(buf->buf, new_len * sizeof(WCHAR));
+ if (!new_buf)
+ {
+ strbuf_free(buf);
+ return FALSE;
+ }
+ buf->buf = new_buf;
+ buf->len = new_len;
+ }
+
+ memcpy(&buf->buf[buf->pos], str, len * sizeof(WCHAR));
+ buf->buf[buf->pos + len] = 0;
+ buf->pos += len;
+ return TRUE;
+}
+
+static WCHAR *lookup_expression(struct assembly_entry *assembly, const WCHAR *key)
+{
+ WCHAR path[MAX_PATH];
+
+ if (!wcscmp(key, L"runtime.system32"))
+ {
+#ifdef __x86_64__
+ if (!wcscmp(assembly->identity.architecture, L"x86"))
+ {
+ GetSystemWow64DirectoryW(path, ARRAY_SIZE(path));
+ return strdupW(path);
+ }
+#endif
+ GetSystemDirectoryW(path, ARRAY_SIZE(path));
+ return strdupW(path);
+ }
+ if (!wcscmp(key, L"runtime.windows"))
+ {
+ GetWindowsDirectoryW(path, ARRAY_SIZE(path));
+ return strdupW(path);
+ }
+
+ FIXME("Unknown expression %s\n", debugstr_w(key));
+ return NULL;
+}
+
+static WCHAR *expand_expression(struct assembly_entry *assembly, const WCHAR *expression)
+{
+ const WCHAR *pos, *next;
+ WCHAR *key, *value;
+ struct strbuf buf;
+
+ if (!expression || !strbuf_init(&buf)) return NULL;
+
+ for (pos = expression; (next = wcsstr(pos, L"$(")); pos = next + 1)
+ {
+ strbuf_append(&buf, pos, next - pos);
+ pos = next + 2;
+ if (!(next = wcsstr(pos, L")")))
+ {
+ strbuf_append(&buf, L"$(", 2);
+ break;
+ }
+
+ if (!(key = strdupWn(pos, next - pos))) goto error;
+ value = lookup_expression(assembly, key);
+ heap_free(key);
+ if (!value) goto error;
+ strbuf_append(&buf, value, ~0U);
+ heap_free(value);
+ }
+
+ strbuf_append(&buf, pos, ~0U);
+ return buf.buf;
+
+error:
+ FIXME("Couldn't resolve expression %s\n", debugstr_w(expression));
+ strbuf_free(&buf);
+ return NULL;
+}
+
+static BOOL install_files_copy(struct assembly_entry *assembly, const WCHAR *source_path, struct fileop_entry *fileop, BOOL dryrun)
+{
+ WCHAR *target_path, *target, *source = NULL;
+ BOOL ret = FALSE;
+
+ if (!(target_path = expand_expression(assembly, fileop->target))) return FALSE;
+ if (!(target = path_combine(target_path, fileop->source))) goto error;
+ if (!(source = path_combine(source_path, fileop->source))) goto error;
+
+ if (dryrun)
+ {
+ if (!(ret = PathFileExistsW(source)))
+ {
+ ERR("Required file %s not found\n", debugstr_w(source));
+ goto error;
+ }
+ }
+ else
+ {
+ TRACE("Copying %s -> %s\n", debugstr_w(source), debugstr_w(target));
+
+ if (!create_parent_directory(target))
+ {
+ ERR("Failed to create parent directory for %s\n", debugstr_w(target));
+ goto error;
+ }
+ if (!(ret = CopyFileExW(source, target, NULL, NULL, NULL, 0)))
+ {
+ ERR("Failed to copy %s to %s\n", debugstr_w(source), debugstr_w(target));
+ goto error;
+ }
+ }
+
+error:
+ heap_free(target_path);
+ heap_free(target);
+ heap_free(source);
+ return ret;
+}
+
+static BOOL install_files(struct assembly_entry *assembly, BOOL dryrun)
+{
+ struct fileop_entry *fileop;
+ WCHAR *source_path;
+ BOOL ret = TRUE;
+
+ if (!(source_path = get_assembly_source(assembly)))
+ {
+ ERR("Failed to get assembly source directory\n");
+ return FALSE;
+ }
+
+ LIST_FOR_EACH_ENTRY(fileop, &assembly->fileops, struct fileop_entry, entry)
+ {
+ if (!(ret = install_files_copy(assembly, source_path, fileop, dryrun))) break;
+ }
+
+ heap_free(source_path);
+ return ret;
+}
+
+static WCHAR *split_registry_key(WCHAR *key, HKEY *root)
+{
+ DWORD size;
+ WCHAR *p;
+
+ if (!(p = wcschr(key, '\\'))) return NULL;
+ size = p - key;
+
+ if (lstrlenW(L"HKEY_CLASSES_ROOT") == size && !wcsncmp(key, L"HKEY_CLASSES_ROOT", size))
+ *root = HKEY_CLASSES_ROOT;
+ else if (lstrlenW(L"HKEY_CURRENT_CONFIG") == size && !wcsncmp(key, L"HKEY_CURRENT_CONFIG", size))
+ *root = HKEY_CURRENT_CONFIG;
+ else if (lstrlenW(L"HKEY_CURRENT_USER") == size && !wcsncmp(key, L"HKEY_CURRENT_USER", size))
+ *root = HKEY_CURRENT_USER;
+ else if (lstrlenW(L"HKEY_LOCAL_MACHINE") == size && !wcsncmp(key, L"HKEY_LOCAL_MACHINE", size))
+ *root = HKEY_LOCAL_MACHINE;
+ else if (lstrlenW(L"HKEY_USERS") == size && !wcsncmp(key, L"HKEY_USERS", size))
+ *root = HKEY_USERS;
+ else
+ {
+ FIXME("Unknown root key %s\n", debugstr_wn(key, size));
+ return NULL;
+ }
+
+ return p + 1;
+}
+
+static BOOL install_registry_string(struct assembly_entry *assembly, HKEY key, struct registrykv_entry *registrykv, DWORD type, BOOL dryrun)
+{
+ DWORD value_size;
+ WCHAR *value = expand_expression(assembly, registrykv->value);
+ BOOL ret = TRUE;
+
+ if (registrykv->value && !value)
+ return FALSE;
+
+ value_size = value ? (lstrlenW(value) + 1) * sizeof(WCHAR) : 0;
+ if (!dryrun && RegSetValueExW(key, registrykv->name, 0, type, (void *)value, value_size))
+ {
+ ERR("Failed to set registry key %s\n", debugstr_w(registrykv->name));
+ ret = FALSE;
+ }
+
+ heap_free(value);
+ return ret;
+}
+
+static WCHAR *parse_multisz(const WCHAR *input, DWORD *size)
+{
+ const WCHAR *pos, *next;
+ struct strbuf buf;
+
+ *size = 0;
+ if (!input || !input[0] || !strbuf_init(&buf)) return NULL;
+
+ for (pos = input; pos[0] == '"'; pos++)
+ {
+ pos++;
+ if (!(next = wcsstr(pos, L"\""))) goto error;
+ strbuf_append(&buf, pos, next - pos);
+ strbuf_append(&buf, L"", ARRAY_SIZE(L""));
+
+ pos = next + 1;
+ if (!pos[0]) break;
+ if (pos[0] != ',')
+ {
+ FIXME("Error while parsing REG_MULTI_SZ string: Expected comma but got '%c'\n", pos[0]);
+ goto error;
+ }
+ }
+
+ if (pos[0])
+ {
+ FIXME("Error while parsing REG_MULTI_SZ string: Garbage at end of string\n");
+ goto error;
+ }
+
+ strbuf_append(&buf, L"", ARRAY_SIZE(L""));
+ *size = buf.pos * sizeof(WCHAR);
+ return buf.buf;
+
+error:
+ strbuf_free(&buf);
+ return NULL;
+}
+
+static BOOL install_registry_multisz(struct assembly_entry *assembly, HKEY key, struct registrykv_entry *registrykv, BOOL dryrun)
+{
+ DWORD value_size;
+ WCHAR *value = parse_multisz(registrykv->value, &value_size);
+ BOOL ret = TRUE;
+
+ if (registrykv->value && registrykv->value[0] && !value)
+ return FALSE;
+
+ if (!dryrun && RegSetValueExW(key, registrykv->name, 0, REG_MULTI_SZ, (void *)value, value_size))
+ {
+ ERR("Failed to set registry key %s\n", debugstr_w(registrykv->name));
+ ret = FALSE;
+ }
+
+ heap_free(value);
+ return ret;
+}
+
+static BOOL install_registry_dword(struct assembly_entry *assembly, HKEY key, struct registrykv_entry *registrykv, BOOL dryrun)
+{
+ DWORD value = registrykv->value_type ? wcstoul(registrykv->value_type, NULL, 16) : 0;
+ BOOL ret = TRUE;
+
+ if (!dryrun && RegSetValueExW(key, registrykv->name, 0, REG_DWORD, (void *)&value, sizeof(value)))
+ {
+ ERR("Failed to set registry key %s\n", debugstr_w(registrykv->name));
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+static BYTE *parse_hex(const WCHAR *input, DWORD *size)
+{
+ WCHAR number[3] = {0, 0, 0};
+ BYTE *output, *p;
+ int length;
+
+ *size = 0;
+ if (!input) return NULL;
+ length = lstrlenW(input);
+ if (length & 1) return NULL;
+ length >>= 1;
+
+ if (!(output = heap_alloc(length))) return NULL;
+ for (p = output; *input; input += 2)
+ {
+ number[0] = input[0];
+ number[1] = input[1];
+ *p++ = wcstoul(number, 0, 16);
+ }
+ *size = length;
+ return output;
+}
+
+static BOOL install_registry_binary(struct assembly_entry *assembly, HKEY key, struct registrykv_entry *registrykv, BOOL dryrun)
+{
+ DWORD value_size;
+ BYTE *value = parse_hex(registrykv->value, &value_size);
+ BOOL ret = TRUE;
+
+ if (registrykv->value && !value)
+ return FALSE;
+
+ if (!dryrun && RegSetValueExW(key, registrykv->name, 0, REG_BINARY, value, value_size))
+ {
+ ERR("Failed to set registry key %s\n", debugstr_w(registrykv->name));
+ ret = FALSE;
+ }
+
+ heap_free(value);
+ return ret;
+}
+
+static BOOL install_registry_value(struct assembly_entry *assembly, HKEY key, struct registrykv_entry *registrykv, BOOL dryrun)
+{
+ TRACE("Setting registry key %s = %s\n", debugstr_w(registrykv->name), debugstr_w(registrykv->value));
+
+ if (!wcscmp(registrykv->value_type, L"REG_SZ"))
+ return install_registry_string(assembly, key, registrykv, REG_SZ, dryrun);
+ if (!wcscmp(registrykv->value_type, L"REG_EXPAND_SZ"))
+ return install_registry_string(assembly, key, registrykv, REG_EXPAND_SZ, dryrun);
+ if (!wcscmp(registrykv->value_type, L"REG_MULTI_SZ"))
+ return install_registry_multisz(assembly, key, registrykv, dryrun);
+ if (!wcscmp(registrykv->value_type, L"REG_DWORD"))
+ return install_registry_dword(assembly, key, registrykv, dryrun);
+ if (!wcscmp(registrykv->value_type, L"REG_BINARY"))
+ return install_registry_binary(assembly, key, registrykv, dryrun);
+
+ FIXME("Unsupported registry value type %s\n", debugstr_w(registrykv->value_type));
+ return FALSE;
+}
+
+static BOOL install_registry(struct assembly_entry *assembly, BOOL dryrun)
+{
+ struct registryop_entry *registryop;
+ struct registrykv_entry *registrykv;
+ HKEY root, subkey;
+ WCHAR *path;
+ REGSAM sam = KEY_ALL_ACCESS;
+ BOOL ret = TRUE;
+
+#ifdef __x86_64__
+ if (!wcscmp(assembly->identity.architecture, L"x86")) sam |= KEY_WOW64_32KEY;
+#endif
+
+ LIST_FOR_EACH_ENTRY(registryop, &assembly->registryops, struct registryop_entry, entry)
+ {
+ if (!(path = split_registry_key(registryop->key, &root)))
+ {
+ ret = FALSE;
+ break;
+ }
+
+ TRACE("Processing registry key %s\n", debugstr_w(registryop->key));
+
+ if (!dryrun && RegCreateKeyExW(root, path, 0, NULL, 0, sam, NULL, &subkey, NULL))
+ {
+ ERR("Failed to open registry key %s\n", debugstr_w(registryop->key));
+ ret = FALSE;
+ break;
+ }
+
+ LIST_FOR_EACH_ENTRY(registrykv, ®istryop->keyvalues, struct registrykv_entry, entry)
+ {
+ if (!(ret = install_registry_value(assembly, subkey, registrykv, dryrun))) break;
+ }
+
+ if (!dryrun) RegCloseKey(subkey);
+ if (!ret) break;
+ }
+
+ return ret;
+}
+
+static BOOL install_assembly(struct list *manifest_list, struct assembly_identity *identity, BOOL dryrun)
+{
+ struct dependency_entry *dependency;
+ struct assembly_entry *assembly;
+ const WCHAR *name;
+
+ if (!(assembly = lookup_assembly(manifest_list, identity)))
+ {
+ FIXME("Assembly %s not found\n", debugstr_w(identity->name));
+ return FALSE;
+ }
+
+ name = assembly->identity.name;
+
+ if (assembly->status == ASSEMBLY_STATUS_INSTALLED)
+ {
+ TRACE("Assembly %s already installed\n", debugstr_w(name));
+ return TRUE;
+ }
+ if (assembly->status == ASSEMBLY_STATUS_IN_PROGRESS)
+ {
+ ERR("Assembly %s caused circular dependency\n", debugstr_w(name));
+ return FALSE;
+ }
+
+#ifdef __i386__
+ if (!wcscmp(assembly->identity.architecture, L"amd64"))
+ {
+ ERR("Cannot install amd64 assembly in 32-bit prefix\n");
+ return FALSE;
+ }
+#endif
+
+ assembly->status = ASSEMBLY_STATUS_IN_PROGRESS;
+
+ LIST_FOR_EACH_ENTRY(dependency, &assembly->dependencies, struct dependency_entry, entry)
+ {
+ if (!install_assembly(manifest_list, &dependency->identity, dryrun)) return FALSE;
+ }
+
+ TRACE("Installing assembly %s%s\n", debugstr_w(name), dryrun ? " (dryrun)" : "");
+
+ if (!install_files(assembly, dryrun))
+ {
+ ERR("Failed to install all files for %s\n", debugstr_w(name));
+ return FALSE;
+ }
+
+ if (!install_registry(assembly, dryrun))
+ {
+ ERR("Failed to install registry keys for %s\n", debugstr_w(name));
+ return FALSE;
+ }
+
+ TRACE("Installation of %s finished\n", debugstr_w(name));
+
+ assembly->status = ASSEMBLY_STATUS_INSTALLED;
+ return TRUE;
+}
+
+static BOOL install_updates(struct installer_state *state, BOOL dryrun)
+{
+ struct dependency_entry *dependency;
+ LIST_FOR_EACH_ENTRY(dependency, &state->updates, struct dependency_entry, entry)
+ {
+ if (!install_assembly(&state->assemblies, &dependency->identity, dryrun))
+ {
+ ERR("Failed to install update %s\n", debugstr_w(dependency->identity.name));
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void set_assembly_status(struct list *manifest_list, DWORD status)
+{
+ struct assembly_entry *assembly;
+ LIST_FOR_EACH_ENTRY(assembly, manifest_list, struct assembly_entry, entry)
+ {
+ assembly->status = status;
+ }
+}
+
static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
{
const WCHAR *temp_path;
@@ -474,6 +983,29 @@ static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
}
}
+ if (list_empty(&state->updates))
+ {
+ ERR("No updates found, probably incompatible MSU file format?\n");
+ goto done;
+ }
+
+ /* perform dry run */
+ set_assembly_status(&state->assemblies, ASSEMBLY_STATUS_NONE);
+ if (!install_updates(state, TRUE))
+ {
+ ERR("Dry run failed, aborting installation\n");
+ goto done;
+ }
+
+ /* installation */
+ set_assembly_status(&state->assemblies, ASSEMBLY_STATUS_NONE);
+ if (!install_updates(state, FALSE))
+ {
+ ERR("Installation failed\n");
+ goto done;
+ }
+
+ TRACE("Installation finished\n");
ret = TRUE;
done:
@@ -481,12 +1013,42 @@ done:
return ret;
}
+static void restart_as_x86_64(void)
+{
+ WCHAR filename[MAX_PATH];
+ PROCESS_INFORMATION pi;
+ STARTUPINFOW si;
+ DWORD exit_code = 1;
+ void *redir;
+
+ memset(&si, 0, sizeof(si));
+ si.cb = sizeof(si);
+ GetModuleFileNameW(0, filename, MAX_PATH);
+
+ Wow64DisableWow64FsRedirection(&redir);
+ if (CreateProcessW(filename, GetCommandLineW(), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
+ {
+ TRACE("Restarting %s\n", wine_dbgstr_w(filename));
+ WaitForSingleObject(pi.hProcess, INFINITE);
+ GetExitCodeProcess(pi.hProcess, &exit_code);
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ }
+ else ERR("Failed to restart 64-bit %s, err %u\n", wine_dbgstr_w(filename), GetLastError());
+ Wow64RevertWow64FsRedirection(redir);
+
+ ExitProcess(exit_code);
+}
+
int __cdecl wmain(int argc, WCHAR *argv[])
{
struct installer_state state;
const WCHAR *filename = NULL;
+ BOOL is_wow64;
int i;
+ if (IsWow64Process( GetCurrentProcess(), &is_wow64 ) && is_wow64) restart_as_x86_64();
+
state.norestart = FALSE;
state.quiet = FALSE;
diff --git a/programs/wusa/wusa.h b/programs/wusa/wusa.h
index e717fad6e0..dcd784e764 100644
--- a/programs/wusa/wusa.h
+++ b/programs/wusa/wusa.h
@@ -90,6 +90,12 @@ static inline void *heap_alloc_zero(size_t len)
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
}
+static void *heap_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2);
+static inline void *heap_realloc(void *mem, size_t len)
+{
+ return HeapReAlloc(GetProcessHeap(), 0, mem, len);
+}
+
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
@@ -127,3 +133,16 @@ static inline WCHAR *strdupW(const WCHAR *str)
if (ret) lstrcpyW(ret, str);
return ret;
}
+
+static inline WCHAR *strdupWn(const WCHAR *str, DWORD len)
+{
+ WCHAR *ret;
+ if (!str) return NULL;
+ ret = heap_alloc((len + 1) * sizeof(WCHAR));
+ if (ret)
+ {
+ memcpy(ret, str, len * sizeof(WCHAR));
+ ret[len] = 0;
+ }
+ return ret;
+}
--
2.20.1
Dec. 2, 2019
[PATCH 3/4] wusa: Parse update descriptions.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
programs/wusa/main.c | 46 +++++++++++++++++
programs/wusa/manifest.c | 106 +++++++++++++++++++++++++++++++++++++++
programs/wusa/wusa.h | 2 +
3 files changed, 154 insertions(+)
diff --git a/programs/wusa/main.c b/programs/wusa/main.c
index a1cdea4ee8..8df8731e2b 100644
--- a/programs/wusa/main.c
+++ b/programs/wusa/main.c
@@ -41,6 +41,7 @@ struct installer_state
BOOL quiet;
struct list tempdirs;
struct list assemblies;
+ struct list updates;
};
static void * CDECL cabinet_alloc(ULONG cb)
@@ -317,6 +318,7 @@ static void installer_cleanup(struct installer_state *state)
{
struct installer_tempdir *tempdir, *tempdir2;
struct assembly_entry *assembly, *assembly2;
+ struct dependency_entry *dependency, *dependency2;
LIST_FOR_EACH_ENTRY_SAFE(tempdir, tempdir2, &state->tempdirs, struct installer_tempdir, entry)
{
@@ -330,6 +332,11 @@ static void installer_cleanup(struct installer_state *state)
list_remove(&assembly->entry);
free_assembly(assembly);
}
+ LIST_FOR_EACH_ENTRY_SAFE(dependency, dependency2, &state->updates, struct dependency_entry, entry)
+ {
+ list_remove(&dependency->entry);
+ free_dependency(dependency);
+ }
}
static BOOL str_ends_with(const WCHAR *str, const WCHAR *suffix)
@@ -397,6 +404,7 @@ static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
list_init(&state->tempdirs);
list_init(&state->assemblies);
+ list_init(&state->updates);
CoInitialize(NULL);
TRACE("Processing msu file %s\n", debugstr_w(filename));
@@ -428,6 +436,44 @@ static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
FindClose(search);
}
+ /* load all update descriptions */
+ if (!(path = path_combine(temp_path, L"*.xml"))) goto done;
+ search = FindFirstFileW(path, &data);
+ heap_free(path);
+
+ if (search != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+ if (!(path = path_combine(temp_path, data.cFileName))) continue;
+ if (!load_update(path, &state->updates))
+ ERR("Failed to load all updates from %s, ignoring\n", debugstr_w(path));
+ heap_free(path);
+ }
+ while (FindNextFileW(search, &data));
+ FindClose(search);
+ }
+
+ /* dump package information (for debugging) */
+ if (TRACE_ON(wusa))
+ {
+ struct dependency_entry *dependency;
+ struct assembly_entry *assembly;
+
+ TRACE("List of updates:\n");
+ LIST_FOR_EACH_ENTRY(dependency, &state->updates, struct dependency_entry, entry)
+ TRACE(" * %s\n", debugstr_w(dependency->identity.name));
+
+ TRACE("List of manifests (with dependencies):\n");
+ LIST_FOR_EACH_ENTRY(assembly, &state->assemblies, struct assembly_entry, entry)
+ {
+ TRACE(" * %s\n", debugstr_w(assembly->identity.name));
+ LIST_FOR_EACH_ENTRY(dependency, &assembly->dependencies, struct dependency_entry, entry)
+ TRACE(" -> %s\n", debugstr_w(dependency->identity.name));
+ }
+ }
+
ret = TRUE;
done:
diff --git a/programs/wusa/manifest.c b/programs/wusa/manifest.c
index 44c263f6c0..e80c11998c 100644
--- a/programs/wusa/manifest.c
+++ b/programs/wusa/manifest.c
@@ -565,3 +565,109 @@ done:
IXMLDOMElement_Release(root);
return entry;
}
+
+/* <unattend><servicing><package> */
+static BOOL read_update_package(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct dependency_entry *entry;
+ struct list *update_list = context;
+
+ if (!wcscmp(tagname, L"source")) return TRUE;
+ if (wcscmp(tagname, L"assemblyIdentity"))
+ {
+ TRACE("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ if ((entry = alloc_dependency()))
+ {
+ if (read_identity(child, &entry->identity))
+ {
+ TRACE("Found update %s\n", debugstr_w(entry->identity.name));
+ list_add_tail(update_list, &entry->entry);
+ return TRUE;
+ }
+ free_dependency(entry);
+ }
+
+ return FALSE;
+}
+
+static BOOL iter_update_package(IXMLDOMElement *root, struct list *update_list)
+{
+ return call_xml_callbacks(root, read_update_package, update_list);
+}
+
+/* <unattend><servicing> */
+static BOOL read_servicing(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct list *update_list = context;
+ WCHAR *action;
+ BOOL ret = TRUE;
+
+ if (wcscmp(tagname, L"package"))
+ {
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ if (!(action = get_xml_attribute(child, L"action")))
+ {
+ FIXME("Servicing tag doesn't specify action\n");
+ return FALSE;
+ }
+
+ if (!wcscmp(action, L"install"))
+ ret = iter_update_package(child, update_list);
+ else
+ FIXME("action %s not supported\n", debugstr_w(action));
+
+ heap_free(action);
+ return ret;
+}
+
+static BOOL iter_servicing(IXMLDOMElement *root, struct list *update_list)
+{
+ return call_xml_callbacks(root, read_servicing, update_list);
+}
+
+/* <unattend> */
+static BOOL read_unattend(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct list *update_list = context;
+
+ if (wcscmp(tagname, L"servicing"))
+ {
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ return iter_servicing(child, update_list);
+
+}
+
+static BOOL iter_unattend(IXMLDOMElement *root, struct list *update_list)
+{
+ return call_xml_callbacks(root, read_unattend, update_list);
+}
+
+BOOL load_update(const WCHAR *filename, struct list *update_list)
+{
+ IXMLDOMElement *root = NULL;
+ BOOL ret = FALSE;
+
+ TRACE("Reading update %s\n", debugstr_w(filename));
+
+ if (!(root = load_xml(filename))) return FALSE;
+ if (!check_xml_tagname(root, L"unattend"))
+ {
+ FIXME("Didn't find unattend root node?\n");
+ goto done;
+ }
+
+ ret = iter_unattend(root, update_list);
+
+done:
+ IXMLDOMElement_Release(root);
+ return ret;
+}
diff --git a/programs/wusa/wusa.h b/programs/wusa/wusa.h
index 2c81b639b9..e717fad6e0 100644
--- a/programs/wusa/wusa.h
+++ b/programs/wusa/wusa.h
@@ -74,7 +74,9 @@ struct assembly_entry
};
void free_assembly(struct assembly_entry *entry) DECLSPEC_HIDDEN;
+void free_dependency(struct dependency_entry *entry) DECLSPEC_HIDDEN;
struct assembly_entry *load_manifest(const WCHAR *filename) DECLSPEC_HIDDEN;
+BOOL load_update(const WCHAR *filename, struct list *update_list) DECLSPEC_HIDDEN;
static void *heap_alloc(size_t len) __WINE_ALLOC_SIZE(1);
static inline void *heap_alloc(size_t len)
--
2.20.1
Dec. 2, 2019
[PATCH 2/4] wusa: Parse assembly manifests.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
programs/wusa/Makefile.in | 5 +-
programs/wusa/main.c | 87 ++++++
programs/wusa/manifest.c | 567 ++++++++++++++++++++++++++++++++++++++
programs/wusa/wusa.h | 65 +++++
4 files changed, 722 insertions(+), 2 deletions(-)
create mode 100644 programs/wusa/manifest.c
diff --git a/programs/wusa/Makefile.in b/programs/wusa/Makefile.in
index 5e60bdf1b0..87bfe1dae0 100644
--- a/programs/wusa/Makefile.in
+++ b/programs/wusa/Makefile.in
@@ -1,7 +1,8 @@
MODULE = wusa.exe
-IMPORTS = cabinet shlwapi
+IMPORTS = cabinet shlwapi ole32 oleaut32
EXTRADLLFLAGS = -mconsole -municode -mno-cygwin
C_SRCS = \
- main.c
+ main.c \
+ manifest.c
diff --git a/programs/wusa/main.c b/programs/wusa/main.c
index a719eefc5b..a1cdea4ee8 100644
--- a/programs/wusa/main.c
+++ b/programs/wusa/main.c
@@ -40,6 +40,7 @@ struct installer_state
BOOL norestart;
BOOL quiet;
struct list tempdirs;
+ struct list assemblies;
};
static void * CDECL cabinet_alloc(ULONG cb)
@@ -315,6 +316,7 @@ static BOOL delete_directory(const WCHAR *path)
static void installer_cleanup(struct installer_state *state)
{
struct installer_tempdir *tempdir, *tempdir2;
+ struct assembly_entry *assembly, *assembly2;
LIST_FOR_EACH_ENTRY_SAFE(tempdir, tempdir2, &state->tempdirs, struct installer_tempdir, entry)
{
@@ -323,14 +325,79 @@ static void installer_cleanup(struct installer_state *state)
heap_free(tempdir->path);
heap_free(tempdir);
}
+ LIST_FOR_EACH_ENTRY_SAFE(assembly, assembly2, &state->assemblies, struct assembly_entry, entry)
+ {
+ list_remove(&assembly->entry);
+ free_assembly(assembly);
+ }
+}
+
+static BOOL str_ends_with(const WCHAR *str, const WCHAR *suffix)
+{
+ DWORD str_len = lstrlenW(str), suffix_len = lstrlenW(suffix);
+ if (suffix_len > str_len) return FALSE;
+ return !wcsicmp(str + str_len - suffix_len, suffix);
+}
+
+static BOOL load_assemblies_from_cab(const WCHAR *filename, struct installer_state *state)
+{
+ struct assembly_entry *assembly;
+ const WCHAR *temp_path;
+ WIN32_FIND_DATAW data;
+ HANDLE search;
+ WCHAR *path;
+
+ TRACE("Processing cab file %s\n", debugstr_w(filename));
+
+ if (!(temp_path = create_temp_directory(state))) return FALSE;
+ if (!extract_cabinet(filename, temp_path))
+ {
+ ERR("Failed to extract %s\n", debugstr_w(filename));
+ return FALSE;
+ }
+
+ if (!(path = path_combine(temp_path, L"_manifest_.cix.xml"))) return FALSE;
+ if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
+ {
+ FIXME("Cabinet uses proprietary msdelta file compression which is not (yet) supported\n");
+ FIXME("Installation of msu file will most likely fail\n");
+ }
+ heap_free(path);
+
+ if (!(path = path_combine(temp_path, L"*"))) return FALSE;
+ search = FindFirstFileW(path, &data);
+ heap_free(path);
+
+ if (search != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+ if (!str_ends_with(data.cFileName, L".manifest") &&
+ !str_ends_with(data.cFileName, L".mum")) continue;
+ if (!(path = path_combine(temp_path, data.cFileName))) continue;
+ if ((assembly = load_manifest(path)))
+ list_add_tail(&state->assemblies, &assembly->entry);
+ heap_free(path);
+ }
+ while (FindNextFileW(search, &data));
+ FindClose(search);
+ }
+
+ return TRUE;
}
static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
{
const WCHAR *temp_path;
+ WIN32_FIND_DATAW data;
+ HANDLE search;
+ WCHAR *path;
BOOL ret = FALSE;
list_init(&state->tempdirs);
+ list_init(&state->assemblies);
+ CoInitialize(NULL);
TRACE("Processing msu file %s\n", debugstr_w(filename));
@@ -341,6 +408,26 @@ static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
goto done;
}
+ /* load all manifests from contained cabinet archives */
+ if (!(path = path_combine(temp_path, L"*.cab"))) goto done;
+ search = FindFirstFileW(path, &data);
+ heap_free(path);
+
+ if (search != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+ if (!wcsicmp(data.cFileName, L"WSUSSCAN.cab")) continue;
+ if (!(path = path_combine(temp_path, data.cFileName))) continue;
+ if (!load_assemblies_from_cab(path, state))
+ ERR("Failed to load all manifests from %s, ignoring\n", debugstr_w(path));
+ heap_free(path);
+ }
+ while (FindNextFileW(search, &data));
+ FindClose(search);
+ }
+
ret = TRUE;
done:
diff --git a/programs/wusa/manifest.c b/programs/wusa/manifest.c
new file mode 100644
index 0000000000..44c263f6c0
--- /dev/null
+++ b/programs/wusa/manifest.c
@@ -0,0 +1,567 @@
+/*
+ * Manifest parser for WUSA
+ *
+ * Copyright 2015 Michael Müller
+ * Copyright 2015 Sebastian Lackner
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <windows.h>
+#define COBJMACROS
+#include <initguid.h>
+#include <msxml.h>
+
+#include "wine/debug.h"
+#include "wine/list.h"
+#include "wusa.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wusa);
+
+static struct dependency_entry *alloc_dependency(void)
+{
+ struct dependency_entry *entry = heap_alloc_zero(sizeof(*entry));
+ if (!entry) ERR("Failed to allocate memory for dependency\n");
+ return entry;
+}
+
+static struct fileop_entry *alloc_fileop(void)
+{
+ struct fileop_entry *entry = heap_alloc_zero(sizeof(*entry));
+ if (!entry) ERR("Failed to allocate memory for fileop\n");
+ return entry;
+}
+
+static struct registrykv_entry *alloc_registrykv(void)
+{
+ struct registrykv_entry *entry = heap_alloc_zero(sizeof(*entry));
+ if (!entry) ERR("Failed to allocate memory for registrykv\n");
+ return entry;
+}
+
+static struct registryop_entry *alloc_registryop(void)
+{
+ struct registryop_entry *entry = heap_alloc_zero(sizeof(*entry));
+ if (!entry) ERR("Failed to allocate memory for registryop\n");
+ else
+ {
+ list_init(&entry->keyvalues);
+ }
+ return entry;
+}
+
+static struct assembly_entry *alloc_assembly(void)
+{
+ struct assembly_entry *entry = heap_alloc_zero(sizeof(*entry));
+ if (!entry) ERR("Failed to allocate memory for assembly\n");
+ else
+ {
+ list_init(&entry->dependencies);
+ list_init(&entry->fileops);
+ list_init(&entry->registryops);
+ }
+ return entry;
+}
+
+static void clear_identity(struct assembly_identity *entry)
+{
+ heap_free(entry->name);
+ heap_free(entry->version);
+ heap_free(entry->architecture);
+ heap_free(entry->language);
+ heap_free(entry->pubkey_token);
+}
+
+void free_dependency(struct dependency_entry *entry)
+{
+ clear_identity(&entry->identity);
+ heap_free(entry);
+}
+
+static void free_fileop(struct fileop_entry *entry)
+{
+ heap_free(entry->source);
+ heap_free(entry->target);
+ heap_free(entry);
+}
+
+static void free_registrykv(struct registrykv_entry *entry)
+{
+ heap_free(entry->name);
+ heap_free(entry->value_type);
+ heap_free(entry->value);
+ heap_free(entry);
+}
+
+static void free_registryop(struct registryop_entry *entry)
+{
+ struct registrykv_entry *keyvalue, *keyvalue2;
+
+ heap_free(entry->key);
+
+ LIST_FOR_EACH_ENTRY_SAFE(keyvalue, keyvalue2, &entry->keyvalues, struct registrykv_entry, entry)
+ {
+ list_remove(&keyvalue->entry);
+ free_registrykv(keyvalue);
+ }
+
+ heap_free(entry);
+}
+
+void free_assembly(struct assembly_entry *entry)
+{
+ struct dependency_entry *dependency, *dependency2;
+ struct fileop_entry *fileop, *fileop2;
+ struct registryop_entry *registryop, *registryop2;
+
+ heap_free(entry->filename);
+ heap_free(entry->displayname);
+ clear_identity(&entry->identity);
+
+ LIST_FOR_EACH_ENTRY_SAFE(dependency, dependency2, &entry->dependencies, struct dependency_entry, entry)
+ {
+ list_remove(&dependency->entry);
+ free_dependency(dependency);
+ }
+ LIST_FOR_EACH_ENTRY_SAFE(fileop, fileop2, &entry->fileops, struct fileop_entry, entry)
+ {
+ list_remove(&fileop->entry);
+ free_fileop(fileop);
+ }
+ LIST_FOR_EACH_ENTRY_SAFE(registryop, registryop2, &entry->registryops, struct registryop_entry, entry)
+ {
+ list_remove(®istryop->entry);
+ free_registryop(registryop);
+ }
+
+ heap_free(entry);
+}
+
+static WCHAR *get_xml_attribute(IXMLDOMElement *root, const WCHAR *name)
+{
+ WCHAR *ret = NULL;
+ VARIANT var;
+ BSTR bstr;
+
+ if ((bstr = SysAllocString(name)))
+ {
+ VariantInit(&var);
+ if (SUCCEEDED(IXMLDOMElement_getAttribute(root, bstr, &var)))
+ {
+ ret = (V_VT(&var) == VT_BSTR) ? strdupW(V_BSTR(&var)) : NULL;
+ VariantClear(&var);
+ }
+ SysFreeString(bstr);
+ }
+
+ return ret;
+}
+
+static BOOL check_xml_tagname(IXMLDOMElement *root, const WCHAR *tagname)
+{
+ BOOL ret = FALSE;
+ BSTR bstr;
+
+ if (SUCCEEDED(IXMLDOMElement_get_tagName(root, &bstr)))
+ {
+ ret = !wcscmp(bstr, tagname);
+ SysFreeString(bstr);
+ }
+
+ return ret;
+}
+
+static IXMLDOMElement *select_xml_node(IXMLDOMElement *root, const WCHAR *name)
+{
+ IXMLDOMElement *ret = NULL;
+ IXMLDOMNode *node;
+ BSTR bstr;
+
+ if ((bstr = SysAllocString(name)))
+ {
+ if (SUCCEEDED(IXMLDOMElement_selectSingleNode(root, bstr, &node)))
+ {
+ if (FAILED(IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void **)&ret)))
+ ret = NULL;
+ IXMLDOMNode_Release(node);
+ }
+ SysFreeString(bstr);
+ }
+
+ return ret;
+}
+
+static BOOL call_xml_callbacks(IXMLDOMElement *root, BOOL (*func)(IXMLDOMElement *child, WCHAR *tagname, void *context), void *context)
+{
+ IXMLDOMNodeList *children;
+ IXMLDOMElement *child;
+ IXMLDOMNode *node;
+ BSTR tagname;
+ BOOL ret = TRUE;
+
+ if (FAILED(IXMLDOMElement_get_childNodes(root, &children)))
+ return FALSE;
+
+ while (ret && IXMLDOMNodeList_nextNode(children, &node) == S_OK)
+ {
+ if (SUCCEEDED(IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, (void **)&child)))
+ {
+ if (SUCCEEDED(IXMLDOMElement_get_tagName(child, &tagname)))
+ {
+ ret = func(child, tagname, context);
+ SysFreeString(tagname);
+ }
+ IXMLDOMElement_Release(child);
+ }
+ IXMLDOMNode_Release(node);
+ }
+
+ IXMLDOMNodeList_Release(children);
+ return ret;
+}
+
+static IXMLDOMElement *load_xml(const WCHAR *filename)
+{
+ IXMLDOMDocument *document = NULL;
+ IXMLDOMElement *root = NULL;
+ VARIANT_BOOL success;
+ VARIANT variant;
+ BSTR bstr;
+
+ TRACE("Loading XML from %s\n", debugstr_w(filename));
+
+ if (!(bstr = SysAllocString(filename)))
+ return FALSE;
+
+ if (SUCCEEDED(CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&document)))
+ {
+ VariantInit(&variant);
+ V_VT(&variant) = VT_BSTR;
+ V_BSTR(&variant) = bstr;
+
+ if (SUCCEEDED(IXMLDOMDocument_load(document, variant, &success)) && success)
+ {
+ if (FAILED(IXMLDOMDocument_get_documentElement(document, &root)))
+ root = NULL;
+ }
+ IXMLDOMDocument_Release(document);
+ }
+
+ SysFreeString(bstr);
+ return root;
+}
+
+static BOOL read_identity(IXMLDOMElement *root, struct assembly_identity *identity)
+{
+ memset(identity, 0, sizeof(*identity));
+ if (!(identity->name = get_xml_attribute(root, L"name"))) goto error;
+ if (!(identity->version = get_xml_attribute(root, L"version"))) goto error;
+ if (!(identity->architecture = get_xml_attribute(root, L"processorArchitecture"))) goto error;
+ if (!(identity->language = get_xml_attribute(root, L"language"))) goto error;
+ if (!(identity->pubkey_token = get_xml_attribute(root, L"publicKeyToken"))) goto error;
+ return TRUE;
+
+error:
+ clear_identity(identity);
+ return FALSE;
+}
+
+/* <assembly><dependency><dependentAssembly> */
+static BOOL read_dependent_assembly(IXMLDOMElement *root, struct assembly_identity *identity)
+{
+ IXMLDOMElement *child = NULL;
+ WCHAR *dependency_type;
+ BOOL ret = FALSE;
+
+ if (!(dependency_type = get_xml_attribute(root, L"dependencyType")))
+ {
+ WARN("Failed to get dependency type, assuming install\n");
+ }
+ if (dependency_type && wcscmp(dependency_type, L"install") && wcscmp(dependency_type, L"prerequisite"))
+ {
+ FIXME("Unimplemented dependency type %s\n", debugstr_w(dependency_type));
+ goto error;
+ }
+ if (!(child = select_xml_node(root, L".//assemblyIdentity")))
+ {
+ FIXME("Failed to find assemblyIdentity child node\n");
+ goto error;
+ }
+
+ ret = read_identity(child, identity);
+
+error:
+ if (child) IXMLDOMElement_Release(child);
+ heap_free(dependency_type);
+ return ret;
+}
+
+/* <assembly><dependency> */
+static BOOL read_dependency(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct assembly_entry *assembly = context;
+ struct dependency_entry *entry;
+
+ if (wcscmp(tagname, L"dependentAssembly"))
+ {
+ FIXME("Don't know how to handle dependency tag %s\n", debugstr_w(tagname));
+ return FALSE;
+ }
+
+ if ((entry = alloc_dependency()))
+ {
+ if (read_dependent_assembly(child, &entry->identity))
+ {
+ TRACE("Found dependency %s\n", debugstr_w(entry->identity.name));
+ list_add_tail(&assembly->dependencies, &entry->entry);
+ return TRUE;
+ }
+ free_dependency(entry);
+ }
+
+ return FALSE;
+}
+
+static BOOL iter_dependency(IXMLDOMElement *root, struct assembly_entry *assembly)
+{
+ return call_xml_callbacks(root, read_dependency, assembly);
+}
+
+/* <assembly><package><update><component> */
+/* <assembly><package><update><package> */
+static BOOL read_components(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct assembly_entry *assembly = context;
+ struct dependency_entry *entry;
+
+ if (wcscmp(tagname, L"assemblyIdentity"))
+ {
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ if ((entry = alloc_dependency()))
+ {
+ if (read_identity(child, &entry->identity))
+ {
+ TRACE("Found identity %s\n", debugstr_w(entry->identity.name));
+ list_add_tail(&assembly->dependencies, &entry->entry);
+ return TRUE;
+ }
+ free_dependency(entry);
+ }
+
+ return FALSE;
+}
+
+static BOOL iter_components(IXMLDOMElement *root, struct assembly_entry *assembly)
+{
+ return call_xml_callbacks(root, read_components, assembly);
+}
+
+/* <assembly><package><update> */
+static BOOL read_update(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct assembly_entry *assembly = context;
+
+ if (!wcscmp(tagname, L"component"))
+ return iter_components(child, assembly);
+ if (!wcscmp(tagname, L"package"))
+ return iter_components(child, assembly);
+ if (!wcscmp(tagname, L"applicable"))
+ return TRUE;
+
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return FALSE;
+}
+
+static BOOL iter_update(IXMLDOMElement *root, struct assembly_entry *assembly)
+{
+ return call_xml_callbacks(root, read_update, assembly);
+}
+
+/* <assembly><package> */
+static BOOL read_package(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct assembly_entry *assembly = context;
+
+ if (!wcscmp(tagname, L"update"))
+ return iter_update(child, assembly);
+ if (!wcscmp(tagname, L"parent"))
+ return TRUE;
+
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+}
+
+static BOOL iter_package(IXMLDOMElement *root, struct assembly_entry *assembly)
+{
+ return call_xml_callbacks(root, read_package, assembly);
+}
+
+/* <assembly><file> */
+static BOOL read_file(IXMLDOMElement *root, struct assembly_entry *assembly)
+{
+ struct fileop_entry *entry;
+
+ if (!(entry = alloc_fileop()))
+ return FALSE;
+
+ if (!(entry->source = get_xml_attribute(root, L"sourceName"))) goto error;
+ if (!(entry->target = get_xml_attribute(root, L"destinationPath"))) goto error;
+
+ TRACE("Found fileop %s -> %s\n", debugstr_w(entry->source), debugstr_w(entry->target));
+ list_add_tail(&assembly->fileops, &entry->entry);
+ return TRUE;
+
+error:
+ free_fileop(entry);
+ return FALSE;
+}
+
+/* <assembly><registryKeys><registryKey> */
+static BOOL read_registry_key(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct registryop_entry *registryop = context;
+ struct registrykv_entry *entry;
+
+ if (!wcscmp(tagname, L"securityDescriptor")) return TRUE;
+ if (!wcscmp(tagname, L"systemProtection")) return TRUE;
+ if (wcscmp(tagname, L"registryValue"))
+ {
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ if (!(entry = alloc_registrykv()))
+ return FALSE;
+
+ if (!(entry->value_type = get_xml_attribute(child, L"valueType"))) goto error;
+ entry->name = get_xml_attribute(child, L"name"); /* optional */
+ entry->value = get_xml_attribute(child, L"value"); /* optional */
+
+ TRACE("Found registry %s -> %s\n", debugstr_w(entry->name), debugstr_w(entry->value));
+ list_add_tail(®istryop->keyvalues, &entry->entry);
+ return TRUE;
+
+error:
+ free_registrykv(entry);
+ return FALSE;
+}
+
+static BOOL iter_registry_key(IXMLDOMElement *root, struct registryop_entry *registryop)
+{
+ return call_xml_callbacks(root, read_registry_key, registryop);
+}
+
+/* <assembly><registryKeys> */
+static BOOL read_registry_keys(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct assembly_entry *assembly = context;
+ struct registryop_entry *entry;
+ WCHAR *keyname;
+
+ if (wcscmp(tagname, L"registryKey"))
+ {
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ if (!(keyname = get_xml_attribute(child, L"keyName")))
+ {
+ FIXME("RegistryKey tag doesn't specify keyName\n");
+ return FALSE;
+ }
+
+ if ((entry = alloc_registryop()))
+ {
+ list_init(&entry->keyvalues);
+ if (iter_registry_key(child, entry))
+ {
+ entry->key = keyname;
+ TRACE("Found registryop %s\n", debugstr_w(entry->key));
+ list_add_tail(&assembly->registryops, &entry->entry);
+ return TRUE;
+ }
+ free_registryop(entry);
+ }
+
+ heap_free(keyname);
+ return FALSE;
+}
+
+static BOOL iter_registry_keys(IXMLDOMElement *root, struct assembly_entry *assembly)
+{
+ return call_xml_callbacks(root, read_registry_keys, assembly);
+}
+
+/* <assembly> */
+static BOOL read_assembly(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct assembly_entry *assembly = context;
+
+ if (!wcscmp(tagname, L"assemblyIdentity") && !assembly->identity.name)
+ return read_identity(child, &assembly->identity);
+ if (!wcscmp(tagname, L"dependency"))
+ return iter_dependency(child, assembly);
+ if (!wcscmp(tagname, L"package"))
+ return iter_package(child, assembly);
+ if (!wcscmp(tagname, L"file"))
+ return read_file(child, assembly);
+ if (!wcscmp(tagname, L"registryKeys"))
+ return iter_registry_keys(child, assembly);
+ if (!wcscmp(tagname, L"trustInfo"))
+ return TRUE;
+ if (!wcscmp(tagname, L"configuration"))
+ return TRUE;
+ if (!wcscmp(tagname, L"deployment"))
+ return TRUE;
+
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+}
+
+static BOOL iter_assembly(IXMLDOMElement *root, struct assembly_entry *assembly)
+{
+ return call_xml_callbacks(root, read_assembly, assembly);
+}
+
+struct assembly_entry *load_manifest(const WCHAR *filename)
+{
+ struct assembly_entry *entry = NULL;
+ IXMLDOMElement *root = NULL;
+
+ TRACE("Loading manifest %s\n", debugstr_w(filename));
+
+ if (!(root = load_xml(filename))) return NULL;
+ if (!check_xml_tagname(root, L"assembly"))
+ {
+ FIXME("Didn't find assembly root node?\n");
+ goto done;
+ }
+
+ if ((entry = alloc_assembly()))
+ {
+ entry->filename = strdupW(filename);
+ entry->displayname = get_xml_attribute(root, L"displayName");
+ if (iter_assembly(root, entry)) goto done;
+ free_assembly(entry);
+ entry = NULL;
+ }
+
+done:
+ IXMLDOMElement_Release(root);
+ return entry;
+}
diff --git a/programs/wusa/wusa.h b/programs/wusa/wusa.h
index c6bf7eda11..2c81b639b9 100644
--- a/programs/wusa/wusa.h
+++ b/programs/wusa/wusa.h
@@ -17,12 +17,77 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+enum
+{
+ ASSEMBLY_STATUS_NONE,
+ ASSEMBLY_STATUS_IN_PROGRESS,
+ ASSEMBLY_STATUS_INSTALLED,
+};
+
+struct assembly_identity
+{
+ WCHAR *name;
+ WCHAR *version;
+ WCHAR *architecture;
+ WCHAR *language;
+ WCHAR *pubkey_token;
+};
+
+struct dependency_entry
+{
+ struct list entry;
+ struct assembly_identity identity;
+};
+
+struct fileop_entry
+{
+ struct list entry;
+ WCHAR *source;
+ WCHAR *target;
+};
+
+struct registrykv_entry
+{
+ struct list entry;
+ WCHAR *name;
+ WCHAR *value_type;
+ WCHAR *value;
+};
+
+struct registryop_entry
+{
+ struct list entry;
+ WCHAR *key;
+ struct list keyvalues;
+};
+
+struct assembly_entry
+{
+ struct list entry;
+ DWORD status;
+ WCHAR *filename;
+ WCHAR *displayname;
+ struct assembly_identity identity;
+ struct list dependencies;
+ struct list fileops;
+ struct list registryops;
+};
+
+void free_assembly(struct assembly_entry *entry) DECLSPEC_HIDDEN;
+struct assembly_entry *load_manifest(const WCHAR *filename) DECLSPEC_HIDDEN;
+
static void *heap_alloc(size_t len) __WINE_ALLOC_SIZE(1);
static inline void *heap_alloc(size_t len)
{
return HeapAlloc(GetProcessHeap(), 0, len);
}
+static void *heap_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1);
+static inline void *heap_alloc_zero(size_t len)
+{
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+}
+
static inline BOOL heap_free(void *mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
--
2.20.1
Dec. 2, 2019
[PATCH 1/4] wusa: Add support for extracting MSU files.
by Hans Leidekker
This is mostly the work of Michael Müller and Sebastian Lackner. I have
split the large first patch up and folded some of the later patches into
the earlier ones. I left out a workaround for Vista updates and updated
the code to use modern Wine conventions.
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
programs/wusa/Makefile.in | 1 +
programs/wusa/main.c | 369 +++++++++++++++++++++++++++++++++++++-
programs/wusa/wusa.h | 62 +++++++
3 files changed, 427 insertions(+), 5 deletions(-)
create mode 100644 programs/wusa/wusa.h
diff --git a/programs/wusa/Makefile.in b/programs/wusa/Makefile.in
index 3042e86bf8..5e60bdf1b0 100644
--- a/programs/wusa/Makefile.in
+++ b/programs/wusa/Makefile.in
@@ -1,4 +1,5 @@
MODULE = wusa.exe
+IMPORTS = cabinet shlwapi
EXTRADLLFLAGS = -mconsole -municode -mno-cygwin
diff --git a/programs/wusa/main.c b/programs/wusa/main.c
index c3e3dfd38c..a719eefc5b 100644
--- a/programs/wusa/main.c
+++ b/programs/wusa/main.c
@@ -1,5 +1,7 @@
/*
* Copyright 2012 Austin English
+ * Copyright 2015 Michael Müller
+ * Copyright 2015 Sebastian Lackner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,18 +18,375 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include <windows.h>
+#include <fcntl.h>
+#include <fdi.h>
+#include <shlwapi.h>
+
#include "wine/debug.h"
+#include "wine/list.h"
+#include "wusa.h"
WINE_DEFAULT_DEBUG_CHANNEL(wusa);
+struct installer_tempdir
+{
+ struct list entry;
+ WCHAR *path;
+};
+
+struct installer_state
+{
+ BOOL norestart;
+ BOOL quiet;
+ struct list tempdirs;
+};
+
+static void * CDECL cabinet_alloc(ULONG cb)
+{
+ return heap_alloc(cb);
+}
+
+static void CDECL cabinet_free(void *pv)
+{
+ heap_free(pv);
+}
+
+static INT_PTR CDECL cabinet_open(char *pszFile, int oflag, int pmode)
+{
+ DWORD dwAccess = 0;
+ DWORD dwShareMode = 0;
+ DWORD dwCreateDisposition = OPEN_EXISTING;
+
+ switch (oflag & _O_ACCMODE)
+ {
+ case _O_RDONLY:
+ dwAccess = GENERIC_READ;
+ dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
+ break;
+ case _O_WRONLY:
+ dwAccess = GENERIC_WRITE;
+ dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ break;
+ case _O_RDWR:
+ dwAccess = GENERIC_READ | GENERIC_WRITE;
+ dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ break;
+ }
+
+ if ((oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
+ dwCreateDisposition = CREATE_NEW;
+ else if (oflag & _O_CREAT)
+ dwCreateDisposition = CREATE_ALWAYS;
+
+ return (INT_PTR)CreateFileA(pszFile, dwAccess, dwShareMode, NULL, dwCreateDisposition, 0, NULL);
+}
+
+static UINT CDECL cabinet_read(INT_PTR hf, void *pv, UINT cb)
+{
+ HANDLE handle = (HANDLE)hf;
+ DWORD read;
+
+ if (ReadFile(handle, pv, cb, &read, NULL))
+ return read;
+
+ return 0;
+}
+
+static UINT CDECL cabinet_write(INT_PTR hf, void *pv, UINT cb)
+{
+ HANDLE handle = (HANDLE)hf;
+ DWORD written;
+
+ if (WriteFile(handle, pv, cb, &written, NULL))
+ return written;
+
+ return 0;
+}
+
+static int CDECL cabinet_close(INT_PTR hf)
+{
+ HANDLE handle = (HANDLE)hf;
+ return CloseHandle(handle) ? 0 : -1;
+}
+
+static LONG CDECL cabinet_seek(INT_PTR hf, LONG dist, int seektype)
+{
+ HANDLE handle = (HANDLE)hf;
+ /* flags are compatible and so are passed straight through */
+ return SetFilePointer(handle, dist, NULL, seektype);
+}
+
+static WCHAR *path_combine(const WCHAR *path, const WCHAR *filename)
+{
+ WCHAR *result;
+ DWORD length;
+
+ if (!path || !filename) return NULL;
+ length = lstrlenW(path) + lstrlenW(filename) + 2;
+ if (!(result = heap_alloc(length * sizeof(WCHAR)))) return NULL;
+
+ lstrcpyW(result, path);
+ if (result[0] && result[lstrlenW(result) - 1] != '\\') lstrcatW(result, L"\\");
+ lstrcatW(result, filename);
+ return result;
+}
+
+static WCHAR *get_uncompressed_path(PFDINOTIFICATION pfdin)
+{
+ WCHAR *file = strdupAtoW(pfdin->psz1);
+ WCHAR *path = path_combine(pfdin->pv, file);
+ heap_free(file);
+ return path;
+}
+
+static BOOL is_directory(const WCHAR *path)
+{
+ DWORD attrs = GetFileAttributesW(path);
+ if (attrs == INVALID_FILE_ATTRIBUTES) return FALSE;
+ return (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0;
+}
+
+static BOOL create_directory(const WCHAR *path)
+{
+ if (is_directory(path)) return TRUE;
+ if (CreateDirectoryW(path, NULL)) return TRUE;
+ return (GetLastError() == ERROR_ALREADY_EXISTS);
+}
+
+static BOOL create_parent_directory(const WCHAR *filename)
+{
+ WCHAR *p, *path = strdupW(filename);
+ BOOL ret = FALSE;
+
+ if (!path) return FALSE;
+ if (!PathRemoveFileSpecW(path)) goto done;
+ if (is_directory(path))
+ {
+ ret = TRUE;
+ goto done;
+ }
+
+ for (p = path; *p; p++)
+ {
+ if (*p != '\\') continue;
+ *p = 0;
+ if (!create_directory(path)) goto done;
+ *p = '\\';
+ }
+ ret = create_directory(path);
+
+done:
+ heap_free(path);
+ return ret;
+}
+
+static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
+{
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ WCHAR *file;
+ DWORD attrs;
+
+ if (!(file = get_uncompressed_path(pfdin)))
+ return -1;
+
+ TRACE("Extracting %s -> %s\n", debugstr_a(pfdin->psz1), debugstr_w(file));
+
+ if (create_parent_directory(file))
+ {
+ attrs = pfdin->attribs;
+ if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
+ handle = CreateFileW(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL);
+ }
+
+ heap_free(file);
+ return (handle != INVALID_HANDLE_VALUE) ? (INT_PTR)handle : -1;
+}
+
+static INT_PTR cabinet_close_file_info(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
+{
+ HANDLE handle = (HANDLE)pfdin->hf;
+ CloseHandle(handle);
+ return 1;
+}
+
+static INT_PTR CDECL cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
+{
+ switch (fdint)
+ {
+ case fdintPARTIAL_FILE:
+ FIXME("fdintPARTIAL_FILE not implemented\n");
+ return 0;
+
+ case fdintNEXT_CABINET:
+ FIXME("fdintNEXT_CABINET not implemented\n");
+ return 0;
+
+ case fdintCOPY_FILE:
+ return cabinet_copy_file(fdint, pfdin);
+
+ case fdintCLOSE_FILE_INFO:
+ return cabinet_close_file_info(fdint, pfdin);
+
+ default:
+ return 0;
+ }
+}
+
+static BOOL extract_cabinet(const WCHAR *filename, const WCHAR *destination)
+{
+ char *filenameA = NULL;
+ BOOL ret = FALSE;
+ HFDI hfdi;
+ ERF erf;
+
+ hfdi = FDICreate(cabinet_alloc, cabinet_free, cabinet_open, cabinet_read,
+ cabinet_write, cabinet_close, cabinet_seek, 0, &erf);
+ if (!hfdi) return FALSE;
+
+ if ((filenameA = strdupWtoA(filename)))
+ {
+ ret = FDICopy(hfdi, filenameA, NULL, 0, cabinet_notify, NULL, (void *)destination);
+ heap_free(filenameA);
+ }
+
+ FDIDestroy(hfdi);
+ return ret;
+}
+
+static const WCHAR *create_temp_directory(struct installer_state *state)
+{
+ static UINT id;
+ struct installer_tempdir *entry;
+ WCHAR tmp[MAX_PATH];
+
+ if (!GetTempPathW(ARRAY_SIZE(tmp), tmp)) return NULL;
+ if (!(entry = heap_alloc(sizeof(*entry)))) return NULL;
+ if (!(entry->path = heap_alloc((MAX_PATH + 20) * sizeof(WCHAR))))
+ {
+ heap_free(entry);
+ return NULL;
+ }
+ for (;;)
+ {
+ if (!GetTempFileNameW(tmp, L"msu", ++id, entry->path))
+ {
+ heap_free(entry->path);
+ heap_free(entry);
+ return NULL;
+ }
+ if (CreateDirectoryW(entry->path, NULL)) break;
+ }
+
+ list_add_tail(&state->tempdirs, &entry->entry);
+ return entry->path;
+}
+
+static BOOL delete_directory(const WCHAR *path)
+{
+ WIN32_FIND_DATAW data;
+ WCHAR *full_path;
+ HANDLE search;
+
+ if (!(full_path = path_combine(path, L"*"))) return FALSE;
+ search = FindFirstFileW(full_path, &data);
+ heap_free(full_path);
+
+ if (search != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (!wcscmp(data.cFileName, L".")) continue;
+ if (!wcscmp(data.cFileName, L"..")) continue;
+ if (!(full_path = path_combine(path, data.cFileName))) continue;
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ delete_directory(full_path);
+ else
+ DeleteFileW(full_path);
+ heap_free(full_path);
+ }
+ while (FindNextFileW(search, &data));
+ FindClose(search);
+ }
+
+ return RemoveDirectoryW(path);
+}
+
+static void installer_cleanup(struct installer_state *state)
+{
+ struct installer_tempdir *tempdir, *tempdir2;
+
+ LIST_FOR_EACH_ENTRY_SAFE(tempdir, tempdir2, &state->tempdirs, struct installer_tempdir, entry)
+ {
+ list_remove(&tempdir->entry);
+ delete_directory(tempdir->path);
+ heap_free(tempdir->path);
+ heap_free(tempdir);
+ }
+}
+
+static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
+{
+ const WCHAR *temp_path;
+ BOOL ret = FALSE;
+
+ list_init(&state->tempdirs);
+
+ TRACE("Processing msu file %s\n", debugstr_w(filename));
+
+ if (!(temp_path = create_temp_directory(state))) return FALSE;
+ if (!extract_cabinet(filename, temp_path))
+ {
+ ERR("Failed to extract %s\n", debugstr_w(filename));
+ goto done;
+ }
+
+ ret = TRUE;
+
+done:
+ installer_cleanup(state);
+ return ret;
+}
+
int __cdecl wmain(int argc, WCHAR *argv[])
{
+ struct installer_state state;
+ const WCHAR *filename = NULL;
int i;
- WINE_FIXME("stub:");
- for (i = 0; i < argc; i++)
- WINE_FIXME(" %s", wine_dbgstr_w(argv[i]));
- WINE_FIXME("\n");
+ state.norestart = FALSE;
+ state.quiet = FALSE;
- return 0;
+ if (TRACE_ON(wusa))
+ {
+ TRACE("Command line:");
+ for (i = 0; i < argc; i++)
+ TRACE(" %s", wine_dbgstr_w(argv[i]));
+ TRACE("\n");
+ }
+
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] == '/')
+ {
+ if (!wcscmp(argv[i], L"/norestart"))
+ state.norestart = TRUE;
+ else if (!wcscmp(argv[i], L"/quiet"))
+ state.quiet = TRUE;
+ else
+ FIXME("Unknown option: %s\n", wine_dbgstr_w(argv[i]));
+ }
+ else if (!filename)
+ filename = argv[i];
+ else
+ FIXME("Unknown option: %s\n", wine_dbgstr_w(argv[i]));
+ }
+
+ if (!filename)
+ {
+ FIXME("Missing filename argument\n");
+ return 1;
+ }
+
+ return !install_msu(filename, &state);
}
diff --git a/programs/wusa/wusa.h b/programs/wusa/wusa.h
new file mode 100644
index 0000000000..c6bf7eda11
--- /dev/null
+++ b/programs/wusa/wusa.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2015 Michael Müller
+ * Copyright 2015 Sebastian Lackner
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+static void *heap_alloc(size_t len) __WINE_ALLOC_SIZE(1);
+static inline void *heap_alloc(size_t len)
+{
+ return HeapAlloc(GetProcessHeap(), 0, len);
+}
+
+static inline BOOL heap_free(void *mem)
+{
+ return HeapFree(GetProcessHeap(), 0, mem);
+}
+
+static inline char *strdupWtoA(const WCHAR *str)
+{
+ char *ret = NULL;
+ DWORD len;
+
+ if (!str) return ret;
+ len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
+ if ((ret = heap_alloc(len)))
+ WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, NULL, NULL);
+ return ret;
+}
+
+static inline WCHAR *strdupAtoW(const char *str)
+{
+ WCHAR *ret = NULL;
+ DWORD len;
+
+ if (!str) return ret;
+ len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+ if ((ret = heap_alloc(len * sizeof(WCHAR))))
+ MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+ return ret;
+}
+
+static inline WCHAR *strdupW(const WCHAR *str)
+{
+ WCHAR *ret;
+ if (!str) return NULL;
+ ret = heap_alloc((lstrlenW(str) + 1) * sizeof(WCHAR));
+ if (ret) lstrcpyW(ret, str);
+ return ret;
+}
--
2.20.1
Dec. 2, 2019
Re: [PATCH v3 2/7] wined3d: Add functions to support device local and non-local memory info management.
by Conor McCarthy
November 27, 2019 6:01 AM, "Henri Verbeet" <hverbeet(a)gmail.com> wrote:
> On Mon, 25 Nov 2019 at 17:43, Conor McCarthy <cmccarthy(a)codeweavers.com> wrote:
>
> Is it ever necessary to override the total amount of video memory?
>
If the totals come from adapter_vk they will be correct, but adapter_gl won't have the non-local total. Should a zero total be overridden by a non-zero one? Also should totals be passed in a separate call? That could be done using a more generic messaging callback function.
> If we have wined3d_get_adapter_memory_info(), the memory information
> in struct wined3d_adapter_identifier becomes redundant and could be
> removed.
Should vram_bytes and sysmem_bytes stay in wined3d_driver_info though?
Conor
Dec. 2, 2019
[PATCH] ieframe: implement COM aggregation in WebBrowser
by Damjan Jovanovic
Wine's WebBrowser currently just ignores the "outer" it is passed.
Support COM aggregation like Windows does instead.
Signed-off-by: Damjan Jovanovic <damjan.jov(a)gmail.com>
---
dlls/ieframe/classinfo.c | 6 +-
dlls/ieframe/ieframe.h | 2 +
dlls/ieframe/oleobject.c | 30 +--
dlls/ieframe/persist.c | 18 +-
dlls/ieframe/tests/webbrowser.c | 42 +++++
dlls/ieframe/view.c | 12 +-
dlls/ieframe/webbrowser.c | 323 ++++++++++++++++++--------------
7 files changed, 259 insertions(+), 174 deletions(-)
Dec. 2, 2019
[PATCH] riched20/tests: Fix function names in two ok() messages.
by Mathew Hodson
Signed-off-by: Mathew Hodson <mathew.hodson(a)gmail.com>
---
dlls/riched20/tests/txtsrv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/riched20/tests/txtsrv.c b/dlls/riched20/tests/txtsrv.c
index dd290e3..487b9a0 100644
--- a/dlls/riched20/tests/txtsrv.c
+++ b/dlls/riched20/tests/txtsrv.c
@@ -992,10 +992,10 @@ static void test_TxGetScroll(void)
return;
ret = ITextServices_TxGetHScroll(txtserv, NULL, NULL, NULL, NULL, NULL);
- ok(ret == S_OK, "ITextSerHices_GetVScroll failed: 0x%08x.\n", ret);
+ ok(ret == S_OK, "ITextServices_TxGetHScroll failed: 0x%08x.\n", ret);
ret = ITextServices_TxGetVScroll(txtserv, NULL, NULL, NULL, NULL, NULL);
- ok(ret == S_OK, "ITextServices_GetVScroll failed: 0x%08x.\n", ret);
+ ok(ret == S_OK, "ITextServices_TxGetVScroll failed: 0x%08x.\n", ret);
ITextServices_Release(txtserv);
ITextHost_Release(host);
--
2.7.4
Dec. 1, 2019
Re: [PATCH 2/3] d3d8/tests: Add out-of-bounds region tests.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61182
Your paranoid android.
=== debian10 (32 bit report) ===
d3d8:
visual.c:5799: Test failed: [0] Got unexpected hr 0.
visual.c:5799: Test failed: [1] Got unexpected hr 0.
visual.c:5799: Test failed: [2] Got unexpected hr 0.
visual.c:5799: Test failed: [3] Got unexpected hr 0.
visual.c:5799: Test failed: [4] Got unexpected hr 0.
visual.c:5799: Test failed: [5] Got unexpected hr 0.
=== debian10 (32 bit French report) ===
d3d8:
visual.c:5799: Test failed: [0] Got unexpected hr 0.
visual.c:5799: Test failed: [1] Got unexpected hr 0.
visual.c:5799: Test failed: [2] Got unexpected hr 0.
visual.c:5799: Test failed: [3] Got unexpected hr 0.
visual.c:5799: Test failed: [4] Got unexpected hr 0.
visual.c:5799: Test failed: [5] Got unexpected hr 0.
=== debian10 (32 bit Japanese:Japan report) ===
d3d8:
visual.c:5799: Test failed: [0] Got unexpected hr 0.
visual.c:5799: Test failed: [1] Got unexpected hr 0.
visual.c:5799: Test failed: [2] Got unexpected hr 0.
visual.c:5799: Test failed: [3] Got unexpected hr 0.
visual.c:5799: Test failed: [4] Got unexpected hr 0.
visual.c:5799: Test failed: [5] Got unexpected hr 0.
=== debian10 (32 bit Chinese:China report) ===
d3d8:
visual.c:5799: Test failed: [0] Got unexpected hr 0.
visual.c:5799: Test failed: [1] Got unexpected hr 0.
visual.c:5799: Test failed: [2] Got unexpected hr 0.
visual.c:5799: Test failed: [3] Got unexpected hr 0.
visual.c:5799: Test failed: [4] Got unexpected hr 0.
visual.c:5799: Test failed: [5] Got unexpected hr 0.
=== debian10 (32 bit WoW report) ===
d3d8:
visual.c:5799: Test failed: [0] Got unexpected hr 0.
visual.c:5799: Test failed: [1] Got unexpected hr 0.
visual.c:5799: Test failed: [2] Got unexpected hr 0.
visual.c:5799: Test failed: [3] Got unexpected hr 0.
visual.c:5799: Test failed: [4] Got unexpected hr 0.
visual.c:5799: Test failed: [5] Got unexpected hr 0.
=== debian10 (64 bit WoW report) ===
d3d8:
visual.c:5799: Test failed: [0] Got unexpected hr 0.
visual.c:5799: Test failed: [1] Got unexpected hr 0.
visual.c:5799: Test failed: [2] Got unexpected hr 0.
visual.c:5799: Test failed: [3] Got unexpected hr 0.
visual.c:5799: Test failed: [4] Got unexpected hr 0.
visual.c:5799: Test failed: [5] Got unexpected hr 0.
Dec. 1, 2019
[PATCH 3/3] wined3d: Check dirty region dimensions.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d8/tests/visual.c | 2 +-
dlls/d3d9/tests/visual.c | 2 +-
dlls/wined3d/texture.c | 7 +++++++
3 files changed, 9 insertions(+), 2 deletions(-)
Dec. 1, 2019
[PATCH 2/3] d3d8/tests: Add out-of-bounds region tests.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d8/tests/visual.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
Dec. 1, 2019
[PATCH 1/3] d3d9/tests: Add out-of-bounds region tests.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/d3d9/tests/visual.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
Dec. 1, 2019
Re: [PATCH] ieframe: WebBrowser shouldn't support COM aggregation
by Damjan Jovanovic
Hi
Please reject this patch, it's wrong. Windows does support WebBrowser
aggregation, when you ask for IID_IUnknown like I should have.
Damjan
On Sun, Dec 1, 2019 at 12:47 PM Marvin <testbot(a)winehq.org> wrote:
> Hi,
>
> While running your changed tests, I think I found new failures.
> Being a bot and all I'm not very good at pattern recognition, so I might be
> wrong, but could you please double-check?
>
> Full results can be found at:
> https://testbot.winehq.org/JobDetails.pl?Key=61177
>
> Your paranoid android.
>
>
> === wxppro (32 bit report) ===
>
> ieframe:
> 09dc:webbrowser: unhandled exception c0000005 at 00407981
>
> === w2003std (32 bit report) ===
>
> ieframe:
> 01e8:webbrowser: unhandled exception c0000005 at 00407981
>
> === wvistau64 (32 bit report) ===
>
> ieframe:
> 0284:webbrowser: unhandled exception c0000005 at 00407981
>
> === w2008s64 (32 bit report) ===
>
> ieframe:
> 0390:webbrowser: unhandled exception c0000005 at 00407981
>
> === w7u (32 bit report) ===
>
> ieframe:
> 0c2c:webbrowser: unhandled exception c0000005 at 00407981
>
> === w8 (32 bit report) ===
>
> ieframe:
> 0ca0:webbrowser: unhandled exception c0000005 at 00407981
>
> === w8adm (32 bit report) ===
>
> ieframe:
> 0cf0:webbrowser: unhandled exception c0000005 at 00407981
>
> === w864 (32 bit report) ===
>
> ieframe:
> 0e84:webbrowser: unhandled exception c0000005 at 00407981
>
> === w1064v1507 (32 bit report) ===
>
> ieframe:
> 0c88:webbrowser: unhandled exception c0000005 at 00407981
>
> === w1064v1809 (32 bit report) ===
>
> ieframe:
> 195c:webbrowser: unhandled exception c0000005 at 00407981
>
> === w1064v1809_2scr (32 bit report) ===
>
> ieframe:
> 0f24:webbrowser: unhandled exception c0000005 at 00407981
>
> === w1064v1809_ar (32 bit report) ===
>
> ieframe:
> 1874:webbrowser: unhandled exception c0000005 at 00407981
>
> === w1064v1809_he (32 bit report) ===
>
> ieframe:
> 0fb4:webbrowser: unhandled exception c0000005 at 00407981
>
> === w1064v1809_ja (32 bit report) ===
>
> ieframe:
> 19bc:webbrowser: unhandled exception c0000005 at 00407981
>
> === w1064v1809_zh_CN (32 bit report) ===
>
> ieframe:
> 1a08:webbrowser: unhandled exception c0000005 at 00407981
>
> === wvistau64 (64 bit report) ===
>
> ieframe:
> 0910:webbrowser: unhandled exception c0000005 at 0000000000406BD0
>
> === w2008s64 (64 bit report) ===
>
> ieframe:
> 0390:webbrowser: unhandled exception c0000005 at 0000000000406BD0
>
> === w864 (64 bit report) ===
>
> ieframe:
> 0870:webbrowser: unhandled exception c0000005 at 0000000000406BD0
>
> === w1064v1507 (64 bit report) ===
>
> ieframe:
> 0fe0:webbrowser: unhandled exception c0000005 at 0000000000406BD0
>
> === w1064v1809 (64 bit report) ===
>
> ieframe:
> 1948:webbrowser: unhandled exception c0000005 at 0000000000406BD0
>
> === debian10 (32 bit report) ===
>
> ieframe:
> Unhandled exception: page fault on read access to 0x00000000 in 32-bit
> code (0x00407950).
>
> Report errors:
> ieframe:webbrowser crashed (c0000005)
>
> === debian10 (32 bit French report) ===
>
> ieframe:
> Unhandled exception: page fault on read access to 0x00000000 in 32-bit
> code (0x00407950).
>
> Report errors:
> ieframe:webbrowser crashed (c0000005)
>
> === debian10 (32 bit Japanese:Japan report) ===
>
> ieframe:
> Unhandled exception: page fault on read access to 0x00000000 in 32-bit
> code (0x00407950).
>
> Report errors:
> ieframe:webbrowser crashed (c0000005)
>
> === debian10 (32 bit Chinese:China report) ===
>
> ieframe:
> Unhandled exception: page fault on read access to 0x00000000 in 32-bit
> code (0x00407950).
>
> Report errors:
> ieframe:webbrowser crashed (c0000005)
>
> === debian10 (32 bit WoW report) ===
>
> ieframe:
> Unhandled exception: page fault on read access to 0x00000000 in 32-bit
> code (0x00407950).
>
> Report errors:
> ieframe:webbrowser crashed (c0000005)
>
> === debian10 (64 bit WoW report) ===
>
> ieframe:
> ie: Timeout
> Unhandled exception: page fault on read access to 0x00000000 in 32-bit
> code (0x00407950).
>
> Report errors:
> ieframe:webbrowser crashed (c0000005)
>
Dec. 1, 2019
Re: [PATCH] ieframe: WebBrowser shouldn't support COM aggregation
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61177
Your paranoid android.
=== wxppro (32 bit report) ===
ieframe:
09dc:webbrowser: unhandled exception c0000005 at 00407981
=== w2003std (32 bit report) ===
ieframe:
01e8:webbrowser: unhandled exception c0000005 at 00407981
=== wvistau64 (32 bit report) ===
ieframe:
0284:webbrowser: unhandled exception c0000005 at 00407981
=== w2008s64 (32 bit report) ===
ieframe:
0390:webbrowser: unhandled exception c0000005 at 00407981
=== w7u (32 bit report) ===
ieframe:
0c2c:webbrowser: unhandled exception c0000005 at 00407981
=== w8 (32 bit report) ===
ieframe:
0ca0:webbrowser: unhandled exception c0000005 at 00407981
=== w8adm (32 bit report) ===
ieframe:
0cf0:webbrowser: unhandled exception c0000005 at 00407981
=== w864 (32 bit report) ===
ieframe:
0e84:webbrowser: unhandled exception c0000005 at 00407981
=== w1064v1507 (32 bit report) ===
ieframe:
0c88:webbrowser: unhandled exception c0000005 at 00407981
=== w1064v1809 (32 bit report) ===
ieframe:
195c:webbrowser: unhandled exception c0000005 at 00407981
=== w1064v1809_2scr (32 bit report) ===
ieframe:
0f24:webbrowser: unhandled exception c0000005 at 00407981
=== w1064v1809_ar (32 bit report) ===
ieframe:
1874:webbrowser: unhandled exception c0000005 at 00407981
=== w1064v1809_he (32 bit report) ===
ieframe:
0fb4:webbrowser: unhandled exception c0000005 at 00407981
=== w1064v1809_ja (32 bit report) ===
ieframe:
19bc:webbrowser: unhandled exception c0000005 at 00407981
=== w1064v1809_zh_CN (32 bit report) ===
ieframe:
1a08:webbrowser: unhandled exception c0000005 at 00407981
=== wvistau64 (64 bit report) ===
ieframe:
0910:webbrowser: unhandled exception c0000005 at 0000000000406BD0
=== w2008s64 (64 bit report) ===
ieframe:
0390:webbrowser: unhandled exception c0000005 at 0000000000406BD0
=== w864 (64 bit report) ===
ieframe:
0870:webbrowser: unhandled exception c0000005 at 0000000000406BD0
=== w1064v1507 (64 bit report) ===
ieframe:
0fe0:webbrowser: unhandled exception c0000005 at 0000000000406BD0
=== w1064v1809 (64 bit report) ===
ieframe:
1948:webbrowser: unhandled exception c0000005 at 0000000000406BD0
=== debian10 (32 bit report) ===
ieframe:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00407950).
Report errors:
ieframe:webbrowser crashed (c0000005)
=== debian10 (32 bit French report) ===
ieframe:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00407950).
Report errors:
ieframe:webbrowser crashed (c0000005)
=== debian10 (32 bit Japanese:Japan report) ===
ieframe:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00407950).
Report errors:
ieframe:webbrowser crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
ieframe:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00407950).
Report errors:
ieframe:webbrowser crashed (c0000005)
=== debian10 (32 bit WoW report) ===
ieframe:
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00407950).
Report errors:
ieframe:webbrowser crashed (c0000005)
=== debian10 (64 bit WoW report) ===
ieframe:
ie: Timeout
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00407950).
Report errors:
ieframe:webbrowser crashed (c0000005)
Dec. 1, 2019
[PATCH] ieframe: WebBrowser shouldn't support COM aggregation
by Damjan Jovanovic
COM objects should either fully support aggregation or cleanly fail.
Our ieframe's WebBrowser completely ignores it. Fail with
CLASS_E_NOAGGREGATION like Windows does instead.
Signed-off-by: Damjan Jovanovic <damjan.jov(a)gmail.com>
---
dlls/ieframe/tests/webbrowser.c | 3 +++
dlls/ieframe/webbrowser.c | 3 +++
2 files changed, 6 insertions(+)
Dec. 1, 2019
Re: [PATCH 4/6] winegstreamer: Also wait for the no-more-pads signal when pausing the filter.
by Zebediah Figura
On 11/30/19 7:48 PM, Zebediah Figura wrote:
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/winegstreamer/gstdemux.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
> index 479077b48f..dc8db85b72 100644
> --- a/dlls/winegstreamer/gstdemux.c
> +++ b/dlls/winegstreamer/gstdemux.c
> @@ -1433,8 +1433,17 @@ static HRESULT WINAPI GST_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
> }
>
> EnterCriticalSection(&This->filter.csFilter);
> +
> + if (This->no_more_pads_event)
> + ResetEvent(This->no_more_pads_event);
> +
> gst_element_set_state(This->container, GST_STATE_PLAYING);
>
> + /* Make sure that all of our pads are connected before returning, lest we
> + * e.g. try to seek and fail. */
> + if (This->no_more_pads_event)
> + WaitForSingleObject(This->no_more_pads_event, INFINITE);
> +
> for (i = 0; i < This->cStreams; i++) {
> hr = BaseOutputPinImpl_Active(&This->ppPins[i]->pin);
> if (SUCCEEDED(hr)) {
>
Please ignore the last three patches in this series; as the test
failures show I clearly missed a spot.
Dec. 1, 2019
Re: [PATCH 6/6] winegstreamer: Use strmbase state change methods.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61159
Your paranoid android.
=== debian10 (32 bit report) ===
quartz:
filtergraph: Timeout
=== debian10 (32 bit Chinese:China report) ===
quartz:
filtergraph: Timeout
=== debian10 (32 bit WoW report) ===
quartz:
filtergraph: Timeout
=== debian10 (64 bit WoW report) ===
quartz:
filtergraph: Timeout
Dec. 1, 2019
Re: [PATCH 4/6] winegstreamer: Also wait for the no-more-pads signal when pausing the filter.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61157
Your paranoid android.
=== debian10 (32 bit report) ===
quartz:
avisplit: Timeout
filtergraph: Timeout
=== debian10 (32 bit Chinese:China report) ===
quartz:
avisplit: Timeout
filtergraph: Timeout
=== debian10 (32 bit WoW report) ===
quartz:
avisplit: Timeout
filtergraph: Timeout
=== debian10 (64 bit WoW report) ===
quartz:
avisplit: Timeout
filtergraph: Timeout
Dec. 1, 2019
[PATCH 6/6] winegstreamer: Use strmbase state change methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gstdemux.c | 255 ++++++++++++++++------------------
1 file changed, 122 insertions(+), 133 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 0f53efc6eb..e7489efc91 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -88,11 +88,6 @@ struct gstdemux_source
SourceSeeking seek;
};
-static inline struct gstdemux *impl_from_IBaseFilter(IBaseFilter *iface)
-{
- return CONTAINING_RECORD(iface, struct gstdemux, filter.IBaseFilter_iface);
-}
-
static inline struct gstdemux *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct gstdemux, filter);
@@ -1246,10 +1241,123 @@ static void gstdemux_destroy(struct strmbase_filter *iface)
heap_free(filter);
}
+static HRESULT gstdemux_init_stream(struct strmbase_filter *iface)
+{
+ struct gstdemux *filter = impl_from_strmbase_filter(iface);
+ HRESULT hr = VFW_E_NOT_CONNECTED, pin_hr;
+ GstStateChangeReturn ret;
+ unsigned int i;
+
+ if (!filter->container)
+ return VFW_E_NOT_CONNECTED;
+
+ if (filter->no_more_pads_event)
+ ResetEvent(filter->no_more_pads_event);
+
+ if ((ret = gst_element_set_state(filter->container, GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE)
+ {
+ ERR("Failed to pause stream.\n");
+ return E_FAIL;
+ }
+
+ /* Make sure that all of our pads are connected before returning, lest we
+ * e.g. try to seek and fail. */
+ if (filter->no_more_pads_event)
+ WaitForSingleObject(filter->no_more_pads_event, INFINITE);
+
+ for (i = 0; i < filter->cStreams; ++i)
+ {
+ if (SUCCEEDED(pin_hr = BaseOutputPinImpl_Active(&filter->ppPins[i]->pin)))
+ hr = pin_hr;
+ }
+ return hr;
+}
+
+static HRESULT gstdemux_start_stream(struct strmbase_filter *iface, REFERENCE_TIME time)
+{
+ struct gstdemux *filter = impl_from_strmbase_filter(iface);
+ GstStateChangeReturn ret;
+
+ if (!filter->container)
+ return VFW_E_NOT_CONNECTED;
+
+ if ((ret = gst_element_set_state(filter->container, GST_STATE_PLAYING)) == GST_STATE_CHANGE_FAILURE)
+ {
+ ERR("Failed to play stream.\n");
+ return E_FAIL;
+ }
+ else if (ret == GST_STATE_CHANGE_ASYNC)
+ return S_FALSE;
+ return S_OK;
+}
+
+static HRESULT gstdemux_stop_stream(struct strmbase_filter *iface)
+{
+ struct gstdemux *filter = impl_from_strmbase_filter(iface);
+ GstStateChangeReturn ret;
+
+ if (!filter->container)
+ return VFW_E_NOT_CONNECTED;
+
+ if ((ret = gst_element_set_state(filter->container, GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE)
+ {
+ ERR("Failed to pause stream.\n");
+ return E_FAIL;
+ }
+ else if (ret == GST_STATE_CHANGE_ASYNC)
+ return S_FALSE;
+ return S_OK;
+}
+
+static HRESULT gstdemux_cleanup_stream(struct strmbase_filter *iface)
+{
+ struct gstdemux *filter = impl_from_strmbase_filter(iface);
+ GstStateChangeReturn ret;
+
+ if (!filter->container)
+ return S_OK;
+
+ filter->ignore_flush = TRUE;
+ if ((ret = gst_element_set_state(filter->container, GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE)
+ {
+ ERR("Failed to pause stream.\n");
+ return E_FAIL;
+ }
+ gst_element_get_state(filter->container, NULL, NULL, GST_CLOCK_TIME_NONE);
+ filter->ignore_flush = FALSE;
+
+ return S_OK;
+}
+
+static HRESULT gstdemux_wait_state(struct strmbase_filter *iface, DWORD timeout)
+{
+ struct gstdemux *filter = impl_from_strmbase_filter(iface);
+ GstStateChangeReturn ret;
+
+ if (!filter->container)
+ return S_OK;
+
+ ret = gst_element_get_state(filter->container, NULL, NULL,
+ timeout == INFINITE ? GST_CLOCK_TIME_NONE : timeout * 1000);
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ {
+ ERR("Failed to get state.\n");
+ return E_FAIL;
+ }
+ else if (ret == GST_STATE_CHANGE_ASYNC)
+ return VFW_S_STATE_INTERMEDIATE;
+ return S_OK;
+}
+
static const struct strmbase_filter_ops filter_ops =
{
.filter_get_pin = gstdemux_get_pin,
.filter_destroy = gstdemux_destroy,
+ .filter_init_stream = gstdemux_init_stream,
+ .filter_start_stream = gstdemux_start_stream,
+ .filter_stop_stream = gstdemux_stop_stream,
+ .filter_cleanup_stream = gstdemux_cleanup_stream,
+ .filter_wait_state = gstdemux_wait_state,
};
static HRESULT sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
@@ -1359,139 +1467,15 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
return &object->filter.IUnknown_inner;
}
-static HRESULT WINAPI GST_Stop(IBaseFilter *iface)
-{
- struct gstdemux *This = impl_from_IBaseFilter(iface);
-
- TRACE("(%p)\n", This);
-
- mark_wine_thread();
-
- if (This->container) {
- This->ignore_flush = TRUE;
- gst_element_set_state(This->container, GST_STATE_READY);
- gst_element_get_state(This->container, NULL, NULL, -1);
- This->ignore_flush = FALSE;
- }
- return S_OK;
-}
-
-static HRESULT WINAPI GST_Pause(IBaseFilter *iface)
-{
- struct gstdemux *This = impl_from_IBaseFilter(iface);
- HRESULT hr = S_OK;
- GstState now;
- GstStateChangeReturn ret;
-
- TRACE("(%p)\n", This);
-
- if (!This->container)
- return VFW_E_NOT_CONNECTED;
-
- mark_wine_thread();
-
- gst_element_get_state(This->container, &now, NULL, -1);
- if (now == GST_STATE_PAUSED)
- return S_OK;
- if (now != GST_STATE_PLAYING)
- hr = IBaseFilter_Run(iface, -1);
- if (FAILED(hr))
- return hr;
- ret = gst_element_set_state(This->container, GST_STATE_PAUSED);
- if (ret == GST_STATE_CHANGE_ASYNC)
- hr = S_FALSE;
- return hr;
-}
-
-static HRESULT WINAPI GST_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
-{
- struct gstdemux *This = impl_from_IBaseFilter(iface);
- HRESULT hr = S_OK;
- ULONG i;
- GstState now;
- HRESULT hr_any = VFW_E_NOT_CONNECTED;
-
- TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart));
-
- mark_wine_thread();
-
- if (!This->container)
- return VFW_E_NOT_CONNECTED;
-
- gst_element_get_state(This->container, &now, NULL, -1);
- if (now == GST_STATE_PLAYING)
- return S_OK;
- if (now == GST_STATE_PAUSED) {
- GstStateChangeReturn ret;
- ret = gst_element_set_state(This->container, GST_STATE_PLAYING);
- if (ret == GST_STATE_CHANGE_ASYNC)
- return S_FALSE;
- return S_OK;
- }
-
- EnterCriticalSection(&This->filter.csFilter);
-
- if (This->no_more_pads_event)
- ResetEvent(This->no_more_pads_event);
-
- gst_element_set_state(This->container, GST_STATE_PLAYING);
-
- /* Make sure that all of our pads are connected before returning, lest we
- * e.g. try to seek and fail. */
- if (This->no_more_pads_event)
- WaitForSingleObject(This->no_more_pads_event, INFINITE);
-
- for (i = 0; i < This->cStreams; i++) {
- hr = BaseOutputPinImpl_Active(&This->ppPins[i]->pin);
- if (SUCCEEDED(hr)) {
- hr_any = hr;
- }
- }
- hr = hr_any;
- LeaveCriticalSection(&This->filter.csFilter);
-
- return hr;
-}
-
-static HRESULT WINAPI GST_GetState(IBaseFilter *iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
-{
- struct gstdemux *This = impl_from_IBaseFilter(iface);
- HRESULT hr = S_OK;
- GstState now, pending;
- GstStateChangeReturn ret;
-
- TRACE("(%p)->(%d, %p)\n", This, dwMilliSecsTimeout, pState);
-
- mark_wine_thread();
-
- if (!This->container) {
- *pState = State_Stopped;
- return S_OK;
- }
-
- ret = gst_element_get_state(This->container, &now, &pending, dwMilliSecsTimeout == INFINITE ? -1 : dwMilliSecsTimeout * 1000);
-
- if (ret == GST_STATE_CHANGE_ASYNC)
- hr = VFW_S_STATE_INTERMEDIATE;
- else
- pending = now;
-
- switch (pending) {
- case GST_STATE_PAUSED: *pState = State_Paused; return hr;
- case GST_STATE_PLAYING: *pState = State_Running; return hr;
- default: *pState = State_Stopped; return hr;
- }
-}
-
static const IBaseFilterVtbl GST_Vtbl = {
BaseFilterImpl_QueryInterface,
BaseFilterImpl_AddRef,
BaseFilterImpl_Release,
BaseFilterImpl_GetClassID,
- GST_Stop,
- GST_Pause,
- GST_Run,
- GST_GetState,
+ BaseFilterImpl_Stop,
+ BaseFilterImpl_Pause,
+ BaseFilterImpl_Run,
+ BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
BaseFilterImpl_EnumPins,
@@ -2630,6 +2614,11 @@ static const struct strmbase_filter_ops mpeg_splitter_ops =
.filter_query_interface = mpeg_splitter_query_interface,
.filter_get_pin = gstdemux_get_pin,
.filter_destroy = gstdemux_destroy,
+ .filter_init_stream = gstdemux_init_stream,
+ .filter_start_stream = gstdemux_start_stream,
+ .filter_stop_stream = gstdemux_stop_stream,
+ .filter_cleanup_stream = gstdemux_cleanup_stream,
+ .filter_wait_state = gstdemux_wait_state,
};
IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
--
2.24.0
Dec. 1, 2019
[PATCH 5/6] winegstreamer: Don't hold the filter lock from the pad-added callback.
by Zebediah Figura
This may be called from the streaming thread, so it's not safe to do so.
Nor does it seem necessary. We expect that no streaming thread should ever
call methods on our pad or pin, and as long as we hold the filter lock and
wait for the no-more-pads signal when connecting or starting the stream, we
cannot race with application threads.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gstdemux.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index dc8db85b72..0f53efc6eb 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -971,7 +971,6 @@ static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user)
return;
}
- EnterCriticalSection(&This->filter.csFilter);
for (x = 0; x < This->cStreams; ++x) {
struct gstdemux_source *pin = This->ppPins[x];
if (!pin->their_src) {
@@ -986,13 +985,11 @@ static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user)
pin->their_src = pad;
gst_object_ref(pin->their_src);
TRACE("Relinked\n");
- LeaveCriticalSection(&This->filter.csFilter);
return;
}
}
}
init_new_decoded_pad(bin, pad, This);
- LeaveCriticalSection(&This->filter.csFilter);
}
static gboolean query_function(GstPad *pad, GstObject *parent, GstQuery *query)
--
2.24.0
Dec. 1, 2019
[PATCH 4/6] winegstreamer: Also wait for the no-more-pads signal when pausing the filter.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gstdemux.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 479077b48f..dc8db85b72 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -1433,8 +1433,17 @@ static HRESULT WINAPI GST_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
}
EnterCriticalSection(&This->filter.csFilter);
+
+ if (This->no_more_pads_event)
+ ResetEvent(This->no_more_pads_event);
+
gst_element_set_state(This->container, GST_STATE_PLAYING);
+ /* Make sure that all of our pads are connected before returning, lest we
+ * e.g. try to seek and fail. */
+ if (This->no_more_pads_event)
+ WaitForSingleObject(This->no_more_pads_event, INFINITE);
+
for (i = 0; i < This->cStreams; i++) {
hr = BaseOutputPinImpl_Active(&This->ppPins[i]->pin);
if (SUCCEEDED(hr)) {
--
2.24.0
Dec. 1, 2019
[PATCH 3/6] winegstreamer/gsttffilter: Don't drop the streaming lock in Gstreamer_transform_ProcessEnd().
by Zebediah Figura
This sort of reverts 096da45036959e57ae3aa5b0de0c06f69c651788. The deadlock
mentioned there is not spelled out in detail, but likely results from the
streaming thread trying to acquire the filter lock while a main thread which
is holding the filter lock waits for the streaming thread to finish. However,
DirectShow documentation (and manual testing) suggests that the correct way
to avoid this problem is simply to never take the filter lock from the
streaming thread. Since we currently don't do this anymore, it should be safe
to reinstate this lock.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gsttffilter.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/dlls/winegstreamer/gsttffilter.c b/dlls/winegstreamer/gsttffilter.c
index 9ff5f8741d..ee1851dfdc 100644
--- a/dlls/winegstreamer/gsttffilter.c
+++ b/dlls/winegstreamer/gsttffilter.c
@@ -272,9 +272,7 @@ static HRESULT WINAPI Gstreamer_transform_ProcessEnd(TransformFilter *iface)
mark_wine_thread();
- LeaveCriticalSection(&This->tf.csReceive);
ret = gst_element_set_state(This->filter, GST_STATE_READY);
- EnterCriticalSection(&This->tf.csReceive);
TRACE("Returned: %i\n", ret);
return S_OK;
}
--
2.24.0
Dec. 1, 2019
[PATCH 2/6] strmbase/transform: Hold the streaming lock for the entirety of Receive().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/acmwrapper.c | 4 ----
dlls/quartz/avidec.c | 22 +++++++++-------------
dlls/strmbase/transform.c | 2 +-
dlls/winegstreamer/gsttffilter.c | 3 ---
4 files changed, 10 insertions(+), 21 deletions(-)
diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c
index 64e0018980..8eea6ab147 100644
--- a/dlls/quartz/acmwrapper.c
+++ b/dlls/quartz/acmwrapper.c
@@ -66,12 +66,10 @@ static HRESULT WINAPI ACMWrapper_Receive(TransformFilter *tf, IMediaSample *pSam
LONGLONG tStart = -1, tStop = -1, tMed;
LONGLONG mtStart = -1, mtStop = -1, mtMed;
- EnterCriticalSection(&This->tf.csReceive);
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%x)\n", hr);
- LeaveCriticalSection(&This->tf.csReceive);
return hr;
}
@@ -107,7 +105,6 @@ static HRESULT WINAPI ACMWrapper_Receive(TransformFilter *tf, IMediaSample *pSam
if (FAILED(hr))
{
ERR("Unable to get delivery buffer (%x)\n", hr);
- LeaveCriticalSection(&This->tf.csReceive);
return hr;
}
IMediaSample_SetPreroll(pOutSample, preroll);
@@ -224,7 +221,6 @@ error:
This->lasttime_real = tStop;
This->lasttime_sent = tMed;
- LeaveCriticalSection(&This->tf.csReceive);
return hr;
}
diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c
index cbe109df2b..32969a3473 100644
--- a/dlls/quartz/avidec.c
+++ b/dlls/quartz/avidec.c
@@ -111,12 +111,11 @@ static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample)
LONGLONG tStart, tStop;
DWORD flags = 0;
- EnterCriticalSection(&This->tf.csReceive);
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
if (FAILED(hr))
{
ERR("Cannot get pointer to sample data (%x)\n", hr);
- goto error;
+ return hr;
}
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
@@ -129,7 +128,7 @@ static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample)
hr = BaseOutputPinImpl_GetDeliveryBuffer(&This->tf.source, &pOutSample, NULL, NULL, 0);
if (FAILED(hr)) {
ERR("Unable to get delivery buffer (%x)\n", hr);
- goto error;
+ return hr;
}
hr = IMediaSample_SetActualDataLength(pOutSample, 0);
@@ -138,13 +137,14 @@ static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample)
hr = IMediaSample_GetPointer(pOutSample, &pbDstStream);
if (FAILED(hr)) {
ERR("Unable to get pointer to buffer (%x)\n", hr);
- goto error;
+ IMediaSample_Release(pOutSample);
+ return hr;
}
cbDstStream = IMediaSample_GetSize(pOutSample);
if (cbDstStream < This->pBihOut->biSizeImage) {
ERR("Sample size is too small %d < %d\n", cbDstStream, This->pBihOut->biSizeImage);
- hr = E_FAIL;
- goto error;
+ IMediaSample_Release(pOutSample);
+ return E_FAIL;
}
if (IMediaSample_IsPreroll(pSample) == S_OK)
@@ -161,8 +161,8 @@ static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample)
/* Drop sample if it's intended to be dropped */
if (flags & ICDECOMPRESS_HURRYUP) {
- hr = S_OK;
- goto error;
+ IMediaSample_Release(pOutSample);
+ return S_OK;
}
IMediaSample_SetActualDataLength(pOutSample, This->pBihOut->biSizeImage);
@@ -187,11 +187,7 @@ static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample)
if (hr != S_OK && hr != VFW_E_NOT_CONNECTED)
ERR("Error sending sample (%x)\n", hr);
-error:
- if (pOutSample)
- IMediaSample_Release(pOutSample);
-
- LeaveCriticalSection(&This->tf.csReceive);
+ IMediaSample_Release(pOutSample);
return hr;
}
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 7650232c44..9e2582a0db 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -82,12 +82,12 @@ static HRESULT WINAPI TransformFilter_Input_Receive(struct strmbase_sink *This,
return S_FALSE;
}
- LeaveCriticalSection(&pTransform->csReceive);
if (pTransform->pFuncsTable->pfnReceive)
hr = pTransform->pFuncsTable->pfnReceive(pTransform, pInSample);
else
hr = S_FALSE;
+ LeaveCriticalSection(&pTransform->csReceive);
return hr;
}
diff --git a/dlls/winegstreamer/gsttffilter.c b/dlls/winegstreamer/gsttffilter.c
index baa4c0c2c5..9ff5f8741d 100644
--- a/dlls/winegstreamer/gsttffilter.c
+++ b/dlls/winegstreamer/gsttffilter.c
@@ -227,7 +227,6 @@ static HRESULT WINAPI Gstreamer_transform_ProcessData(TransformFilter *iface, IM
mark_wine_thread();
- EnterCriticalSection(&This->tf.csReceive);
IMediaSample_GetPointer(sample, &data);
IMediaSample_AddRef(sample);
@@ -235,7 +234,6 @@ static HRESULT WINAPI Gstreamer_transform_ProcessData(TransformFilter *iface, IM
buf = gst_buffer_new_wrapped_full(0, data, bufsize, 0, bufsize, sample, release_sample_wrapper);
if (!buf) {
IMediaSample_Release(sample);
- LeaveCriticalSection(&This->tf.csReceive);
return S_OK;
}
@@ -259,7 +257,6 @@ static HRESULT WINAPI Gstreamer_transform_ProcessData(TransformFilter *iface, IM
GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_LIVE);
if (IMediaSample_IsSyncPoint(sample) != S_OK)
GST_BUFFER_FLAG_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT);
- LeaveCriticalSection(&This->tf.csReceive);
ret = gst_pad_push(This->my_src, buf);
if (ret)
WARN("Sending returned: %i\n", ret);
--
2.24.0
Dec. 1, 2019
[PATCH 1/6] strmbase: Don't hold the filter lock while calling IPin::NewSegment().
by Zebediah Figura
It's not safe to hold the filter lock from a streaming thread, and anyway we aren't protecting anything that needs locking.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/strmbase/transform.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index d39dbbd3ab..7650232c44 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -495,12 +495,10 @@ static HRESULT WINAPI TransformFilter_InputPin_NewSegment(IPin * iface, REFERENC
TRACE("iface %p, start %s, stop %s, rate %.16e.\n",
iface, debugstr_time(tStart), debugstr_time(tStop), dRate);
- EnterCriticalSection(&pTransform->filter.csFilter);
if (pTransform->pFuncsTable->pfnNewSegment)
hr = pTransform->pFuncsTable->pfnNewSegment(pTransform, tStart, tStop, dRate);
if (SUCCEEDED(hr))
hr = BaseInputPinImpl_NewSegment(iface, tStart, tStop, dRate);
- LeaveCriticalSection(&pTransform->filter.csFilter);
return hr;
}
--
2.24.0
Dec. 1, 2019
[PATCH v3 2/2] wined3d: Introduce wined3d_stateblock_get_state().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/wined3d/stateblock.c | 5 +++
dlls/wined3d/wined3d.spec | 1 +
dlls/wined3d/wined3d_private.h | 55 ---------------------------------
include/wine/wined3d.h | 56 ++++++++++++++++++++++++++++++++++
4 files changed, 62 insertions(+), 55 deletions(-)
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 24017490e67..1a0ba0a3d59 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -1698,6 +1698,11 @@ HRESULT CDECL wined3d_stateblock_set_light_enable(struct wined3d_stateblock *sta
return S_OK;
}
+const struct wined3d_stateblock_state * CDECL wined3d_stateblock_get_state(const struct wined3d_stateblock *stateblock)
+{
+ return &stateblock->stateblock_state;
+}
+
static void init_default_render_states(DWORD rs[WINEHIGHEST_RENDER_STATE + 1], const struct wined3d_d3d_info *d3d_info)
{
union
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index fed5ce1b128..bec84b5979c 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -259,6 +259,7 @@
@ cdecl wined3d_stateblock_capture(ptr ptr)
@ cdecl wined3d_stateblock_create(ptr ptr long ptr)
@ cdecl wined3d_stateblock_decref(ptr)
+@ cdecl wined3d_stateblock_get_state(ptr)
@ cdecl wined3d_stateblock_incref(ptr)
@ cdecl wined3d_stateblock_init_contained_states(ptr)
@ cdecl wined3d_stateblock_reset(ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 5f779f041f0..2a7dffb26a9 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -272,14 +272,8 @@ static inline enum complex_fixup get_complex_fixup(struct color_fixup_desc fixup
}
/* Device caps */
-#define WINED3D_MAX_STREAMS 16
-#define WINED3D_MAX_TEXTURES 8
-#define WINED3D_MAX_FRAGMENT_SAMPLERS 16
-#define WINED3D_MAX_VERTEX_SAMPLERS 4
-#define WINED3D_MAX_COMBINED_SAMPLERS (WINED3D_MAX_FRAGMENT_SAMPLERS + WINED3D_MAX_VERTEX_SAMPLERS)
#define WINED3D_MAX_ACTIVE_LIGHTS 8
#define WINED3D_MAX_SOFTWARE_ACTIVE_LIGHTS 32
-#define WINED3D_MAX_CLIP_DISTANCES 8
#define MAX_CONSTANT_BUFFERS 15
#define MAX_SAMPLER_OBJECTS 16
#define MAX_SHADER_RESOURCE_VIEWS 128
@@ -699,10 +693,6 @@ enum wined3d_shader_conditional_op
#define MAX_REG_INPUT 32
#define MAX_REG_OUTPUT 32
#define WINED3D_MAX_CBS 15
-#define WINED3D_MAX_CONSTS_B 16
-#define WINED3D_MAX_CONSTS_I 16
-#define WINED3D_MAX_VS_CONSTS_F 256
-#define WINED3D_MAX_PS_CONSTS_F 224
/* FIXME: This needs to go up to 2048 for
* Shader model 3 according to msdn (and for software shaders) */
@@ -1504,8 +1494,6 @@ static inline void wined3d_colour_srgb_from_linear(struct wined3d_color *colour_
colour_srgb->a = colour->a;
}
-#define WINED3D_HIGHEST_TRANSFORM_STATE WINED3D_TS_WORLD_MATRIX(255) /* Highest value in wined3d_transform_state. */
-
void wined3d_check_gl_call(const struct wined3d_gl_info *gl_info,
const char *file, unsigned int line, const char *name) DECLSPEC_HIDDEN;
@@ -3121,15 +3109,6 @@ struct wined3d_stream_output
UINT offset;
};
-struct wined3d_stream_state
-{
- struct wined3d_buffer *buffer;
- UINT offset;
- UINT stride;
- UINT frequency;
- UINT flags;
-};
-
#define LIGHTMAP_SIZE 43
#define LIGHTMAP_HASHFUNC(x) ((x) % LIGHTMAP_SIZE)
@@ -3216,40 +3195,6 @@ struct wined3d_dummy_textures
* wined3d_device_create() ignores it. */
#define WINED3DCREATE_MULTITHREADED 0x00000004
-struct wined3d_stateblock_state
-{
- struct wined3d_vertex_declaration *vertex_declaration;
- struct wined3d_stream_state streams[WINED3D_MAX_STREAMS + 1];
- struct wined3d_buffer *index_buffer;
- enum wined3d_format_id index_format;
- int base_vertex_index;
-
- struct wined3d_shader *vs;
- struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
- struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
- BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
-
- struct wined3d_shader *ps;
- struct wined3d_vec4 ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
- struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I];
- BOOL ps_consts_b[WINED3D_MAX_CONSTS_B];
-
- DWORD rs[WINEHIGHEST_RENDER_STATE + 1];
- struct wined3d_color blend_factor;
-
- struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS];
- DWORD sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
- DWORD texture_states[WINED3D_MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
-
- struct wined3d_matrix transforms[WINED3D_HIGHEST_TRANSFORM_STATE + 1];
- struct wined3d_vec4 clip_planes[WINED3D_MAX_CLIP_DISTANCES];
- struct wined3d_material material;
- struct wined3d_viewport viewport;
- RECT scissor_rect;
-
- struct wined3d_light_state *light_state;
-};
-
struct wined3d_device
{
LONG ref;
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index eba14e9a022..8b64bf66c23 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -668,6 +668,7 @@ enum wined3d_transform_state
};
#define WINED3D_TS_WORLD_MATRIX(index) (enum wined3d_transform_state)(index + 256)
+#define WINED3D_HIGHEST_TRANSFORM_STATE WINED3D_TS_WORLD_MATRIX(255) /* Highest value in wined3d_transform_state. */
enum wined3d_basis_type
{
@@ -1588,6 +1589,17 @@ enum wined3d_shader_type
#define WINED3D_REGISTER_WINDOW_NO_ALT_ENTER 0x00000002u
#define WINED3D_REGISTER_WINDOW_NO_PRINT_SCREEN 0x00000004u
+#define WINED3D_MAX_STREAMS 16
+#define WINED3D_MAX_TEXTURES 8
+#define WINED3D_MAX_FRAGMENT_SAMPLERS 16
+#define WINED3D_MAX_VERTEX_SAMPLERS 4
+#define WINED3D_MAX_COMBINED_SAMPLERS (WINED3D_MAX_FRAGMENT_SAMPLERS + WINED3D_MAX_VERTEX_SAMPLERS)
+#define WINED3D_MAX_CLIP_DISTANCES 8
+#define WINED3D_MAX_CONSTS_B 16
+#define WINED3D_MAX_CONSTS_I 16
+#define WINED3D_MAX_VS_CONSTS_F 256
+#define WINED3D_MAX_PS_CONSTS_F 224
+
struct wined3d_display_mode
{
UINT width;
@@ -2111,6 +2123,49 @@ struct wined3d_output_desc
HMONITOR monitor;
};
+struct wined3d_stream_state
+{
+ struct wined3d_buffer *buffer;
+ UINT offset;
+ UINT stride;
+ UINT frequency;
+ UINT flags;
+};
+
+struct wined3d_stateblock_state
+{
+ struct wined3d_vertex_declaration *vertex_declaration;
+ struct wined3d_stream_state streams[WINED3D_MAX_STREAMS + 1];
+ struct wined3d_buffer *index_buffer;
+ enum wined3d_format_id index_format;
+ int base_vertex_index;
+
+ struct wined3d_shader *vs;
+ struct wined3d_vec4 vs_consts_f[WINED3D_MAX_VS_CONSTS_F];
+ struct wined3d_ivec4 vs_consts_i[WINED3D_MAX_CONSTS_I];
+ BOOL vs_consts_b[WINED3D_MAX_CONSTS_B];
+
+ struct wined3d_shader *ps;
+ struct wined3d_vec4 ps_consts_f[WINED3D_MAX_PS_CONSTS_F];
+ struct wined3d_ivec4 ps_consts_i[WINED3D_MAX_CONSTS_I];
+ BOOL ps_consts_b[WINED3D_MAX_CONSTS_B];
+
+ DWORD rs[WINEHIGHEST_RENDER_STATE + 1];
+ struct wined3d_color blend_factor;
+
+ struct wined3d_texture *textures[WINED3D_MAX_COMBINED_SAMPLERS];
+ DWORD sampler_states[WINED3D_MAX_COMBINED_SAMPLERS][WINED3D_HIGHEST_SAMPLER_STATE + 1];
+ DWORD texture_states[WINED3D_MAX_TEXTURES][WINED3D_HIGHEST_TEXTURE_STATE + 1];
+
+ struct wined3d_matrix transforms[WINED3D_HIGHEST_TRANSFORM_STATE + 1];
+ struct wined3d_vec4 clip_planes[WINED3D_MAX_CLIP_DISTANCES];
+ struct wined3d_material material;
+ struct wined3d_viewport viewport;
+ RECT scissor_rect;
+
+ struct wined3d_light_state *light_state;
+};
+
struct wined3d_parent_ops
{
void (__stdcall *wined3d_object_destroyed)(void *parent);
@@ -2666,6 +2721,7 @@ void __cdecl wined3d_stateblock_capture(struct wined3d_stateblock *stateblock,
HRESULT __cdecl wined3d_stateblock_create(struct wined3d_device *device, const struct wined3d_stateblock *device_state,
enum wined3d_stateblock_type type, struct wined3d_stateblock **stateblock);
ULONG __cdecl wined3d_stateblock_decref(struct wined3d_stateblock *stateblock);
+const struct wined3d_stateblock_state * __cdecl wined3d_stateblock_get_state(const struct wined3d_stateblock *stateblock);
ULONG __cdecl wined3d_stateblock_incref(struct wined3d_stateblock *stateblock);
void __cdecl wined3d_stateblock_init_contained_states(struct wined3d_stateblock *stateblock);
void __cdecl wined3d_stateblock_reset(struct wined3d_stateblock *stateblock);
--
2.23.0
Dec. 1, 2019
[PATCH v3 1/2] wined3d: Move the wined3d_light_state structure to the wined3d_stateblock structure.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/wined3d/stateblock.c | 37 +++++++++++++++++-----------------
dlls/wined3d/wined3d_private.h | 4 +++-
2 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c
index 1c3704c10a5..24017490e67 100644
--- a/dlls/wined3d/stateblock.c
+++ b/dlls/wined3d/stateblock.c
@@ -575,7 +575,7 @@ void wined3d_stateblock_state_cleanup(struct wined3d_stateblock_state *state)
for (i = 0; i < LIGHTMAP_SIZE; ++i)
{
- LIST_FOR_EACH_ENTRY_SAFE(light, cursor, &state->light_state.light_map[i], struct wined3d_light_info, entry)
+ LIST_FOR_EACH_ENTRY_SAFE(light, cursor, &state->light_state->light_map[i], struct wined3d_light_info, entry)
{
list_remove(&light->entry);
heap_free(light);
@@ -1025,7 +1025,7 @@ void CDECL wined3d_stateblock_capture(struct wined3d_stateblock *stateblock,
stateblock->stateblock_state.ps = state->ps;
}
- wined3d_state_record_lights(&stateblock->stateblock_state.light_state, &state->light_state);
+ wined3d_state_record_lights(stateblock->stateblock_state.light_state, state->light_state);
TRACE("Capture done.\n");
}
@@ -1073,17 +1073,17 @@ void CDECL wined3d_stateblock_apply(const struct wined3d_stateblock *stateblock,
wined3d_device_set_vs_consts_b(device, idx, 1, &stateblock->stateblock_state.vs_consts_b[idx]);
}
- for (i = 0; i < ARRAY_SIZE(stateblock->stateblock_state.light_state.light_map); ++i)
+ for (i = 0; i < ARRAY_SIZE(stateblock->stateblock_state.light_state->light_map); ++i)
{
const struct wined3d_light_info *light;
struct wined3d_light_info *new_light;
- LIST_FOR_EACH_ENTRY(light, &stateblock->stateblock_state.light_state.light_map[i], struct wined3d_light_info, entry)
+ LIST_FOR_EACH_ENTRY(light, &stateblock->stateblock_state.light_state->light_map[i], struct wined3d_light_info, entry)
{
- if (SUCCEEDED(wined3d_light_state_set_light(&state->light_state, light->OriginalIndex,
+ if (SUCCEEDED(wined3d_light_state_set_light(state->light_state, light->OriginalIndex,
&light->OriginalParms, &new_light)))
{
- wined3d_light_state_enable_light(&state->light_state, &device->adapter->d3d_info, new_light, light->glIndex != -1);
+ wined3d_light_state_enable_light(state->light_state, &device->adapter->d3d_info, new_light, light->glIndex != -1);
}
wined3d_device_set_light(device, light->OriginalIndex, &light->OriginalParms);
wined3d_device_set_light_enable(device, light->OriginalIndex, light->glIndex != -1);
@@ -1678,24 +1678,23 @@ HRESULT CDECL wined3d_stateblock_set_light(struct wined3d_stateblock *stateblock
return WINED3DERR_INVALIDCALL;
}
- return wined3d_light_state_set_light(&stateblock->stateblock_state.light_state, light_idx, light, &object);
+ return wined3d_light_state_set_light(stateblock->stateblock_state.light_state, light_idx, light, &object);
}
HRESULT CDECL wined3d_stateblock_set_light_enable(struct wined3d_stateblock *stateblock, UINT light_idx, BOOL enable)
{
+ struct wined3d_light_state *light_state = stateblock->stateblock_state.light_state;
struct wined3d_light_info *light_info;
HRESULT hr;
TRACE("stateblock %p, light_idx %u, enable %#x.\n", stateblock, light_idx, enable);
- if (!(light_info = wined3d_light_state_get_light(&stateblock->stateblock_state.light_state, light_idx)))
+ if (!(light_info = wined3d_light_state_get_light(light_state, light_idx)))
{
- if (FAILED(hr = wined3d_light_state_set_light(&stateblock->stateblock_state.light_state, light_idx,
- &WINED3D_default_light, &light_info)))
+ if (FAILED(hr = wined3d_light_state_set_light(light_state, light_idx, &WINED3D_default_light, &light_info)))
return hr;
}
- wined3d_light_state_enable_light(&stateblock->stateblock_state.light_state,
- &stateblock->device->adapter->d3d_info, light_info, enable);
+ wined3d_light_state_enable_light(light_state, &stateblock->device->adapter->d3d_info, light_info, enable);
return S_OK;
}
@@ -1981,9 +1980,9 @@ void wined3d_stateblock_state_init(struct wined3d_stateblock_state *state,
{
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(state->light_state.light_map); i++)
+ for (i = 0; i < ARRAY_SIZE(state->light_state->light_map); i++)
{
- list_init(&state->light_state.light_map[i]);
+ list_init(&state->light_state->light_map[i]);
}
if (flags & WINED3D_STATE_INIT_DEFAULT)
@@ -1998,6 +1997,7 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const stru
stateblock->ref = 1;
stateblock->device = device;
+ stateblock->stateblock_state.light_state = &stateblock->light_state;
wined3d_stateblock_state_init(&stateblock->stateblock_state, device,
type == WINED3D_SBT_PRIMARY ? WINED3D_STATE_INIT_DEFAULT : 0);
@@ -2011,8 +2011,8 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const stru
switch (type)
{
case WINED3D_SBT_ALL:
- stateblock_init_lights(stateblock->stateblock_state.light_state.light_map,
- device_state->stateblock_state.light_state.light_map);
+ stateblock_init_lights(stateblock->stateblock_state.light_state->light_map,
+ device_state->stateblock_state.light_state->light_map);
stateblock_savedstates_set_all(&stateblock->changed,
d3d_info->limits.vs_uniform_count, d3d_info->limits.ps_uniform_count);
break;
@@ -2023,8 +2023,8 @@ static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const stru
break;
case WINED3D_SBT_VERTEX_STATE:
- stateblock_init_lights(stateblock->stateblock_state.light_state.light_map,
- device_state->stateblock_state.light_state.light_map);
+ stateblock_init_lights(stateblock->stateblock_state.light_state->light_map,
+ device_state->stateblock_state.light_state->light_map);
stateblock_savedstates_set_vertex(&stateblock->changed,
d3d_info->limits.vs_uniform_count);
break;
@@ -2078,5 +2078,6 @@ void CDECL wined3d_stateblock_reset(struct wined3d_stateblock *stateblock)
wined3d_stateblock_state_cleanup(&stateblock->stateblock_state);
memset(&stateblock->stateblock_state, 0, sizeof(stateblock->stateblock_state));
+ stateblock->stateblock_state.light_state = &stateblock->light_state;
wined3d_stateblock_state_init(&stateblock->stateblock_state, stateblock->device, WINED3D_STATE_INIT_DEFAULT);
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 3ae7dab858e..5f779f041f0 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3247,7 +3247,7 @@ struct wined3d_stateblock_state
struct wined3d_viewport viewport;
RECT scissor_rect;
- struct wined3d_light_state light_state;
+ struct wined3d_light_state *light_state;
};
struct wined3d_device
@@ -3946,7 +3946,9 @@ struct wined3d_stateblock
/* Array indicating whether things have been set or changed */
struct wined3d_saved_states changed;
+
struct wined3d_stateblock_state stateblock_state;
+ struct wined3d_light_state light_state;
/* Contained state management */
DWORD contained_render_states[WINEHIGHEST_RENDER_STATE + 1];
--
2.23.0
Dec. 1, 2019