Compare commits

..

32 Commits
v7.17 ... v7.19

Author SHA1 Message Date
Alistair Leslie-Hughes
41a3c56c50 Release v7.19 2022-10-17 12:17:38 +11:00
Zebediah Figura
5be23b8ae8 Rebase against e3f00bf7c944f1cde6151fde969f2b49649c3de7. 2022-10-16 16:22:20 -05:00
Zebediah Figura
769ddd9f00 ntdll-Junction_Points: Updates from Erich E. Hoover. 2022-10-16 16:22:16 -05:00
Zebediah Figura
aabde22767 Rebase against fded20df6c7422e85dbcd5a20475fd0c5d38d3c6. 2022-10-13 19:46:39 -05:00
Zebediah Figura
ca3220cbd6 Rebase against f87ad783e23a2b6f5e9b8cf78dbf99bad4471a25. 2022-10-13 16:00:57 -05:00
Alistair Leslie-Hughes
ff6cef5d72 Rebase against f87ad783e23a2b6f5e9b8cf78dbf99bad4471a25. 2022-10-13 08:52:08 +11:00
Alistair Leslie-Hughes
d2b7b686f1 Fix Rebase 2022-10-12 13:52:20 +11:00
Alistair Leslie-Hughes
c5c29f9395 Rebase against 4312be1646cad32548f855e25823857092bf31dc. 2022-10-12 11:27:25 +11:00
Zebediah Figura
08ad410761 secur32-InitializeSecurityContext: Remove patch set.
Fixed upstream by c1993458ac.
2022-10-10 22:28:33 -05:00
Zebediah Figura
e6f9a449cd Rebase against 16c6c249a5134de2422fbd3471ead7425c968301. 2022-10-10 22:27:34 -05:00
Alistair Leslie-Hughes
0ea57a0262 Updated wined3d-bindless-texture patchset 2022-09-30 09:31:13 +10:00
Alistair Leslie-Hughes
4f75966580 Updated ntdll-DOS_Attributes patchset
Fixes: https://bugs.winehq.org/show_bug.cgi?id=53715
2022-09-30 09:31:13 +10:00
Zebediah Figura
9f9285256f mfplat-streaming-support: Remove patch 0067.
Upstreamed as 2d7c37da495c.
2022-09-29 16:04:31 -05:00
Alistair Leslie-Hughes
21009111bd Rebase against 2a4ec7dafc7ee38108f6a9f626a7c39e6b6777e0. 2022-09-27 10:29:23 +10:00
Alistair Leslie-Hughes
fe476e7241 Release v7.18 2022-09-24 09:52:05 +10:00
Alistair Leslie-Hughes
29e810ed54 Merge pull request #84 from Gcenx/patch-3
macOS.yml: Remove wine-devel action
2022-09-24 08:43:52 +10:00
Dean M Greer
1dc3666fd0 macOS.yml: Remove wine-devel action
Since gitlab.winehq.org hosts it’s own macOS runner this is no longer required
2022-09-23 10:40:26 -04:00
Alistair Leslie-Hughes
78837ecadc Rebase against 52a83ffe4ef1ef58520b09f8d2144dcf291b622b. 2022-09-23 14:18:51 +10:00
Alistair Leslie-Hughes
626e3d77cd Rebase against e2a5bf7540a3b1f5b3889f6339795e5edf7f590f. 2022-09-22 09:57:30 +10:00
Alistair Leslie-Hughes
5013933ea5 Rebase against b07e06e297dd8bca67fc1ee523fc235cecebbf1e. 2022-09-21 09:21:47 +10:00
Alistair Leslie-Hughes
c10d599428 Rebase against cb0e4f5f4f7dc10a0933349ad780a11405cd736e. 2022-09-20 08:49:48 +10:00
Alistair Leslie-Hughes
1d75f6950a Rebase against f5b92137257b9564dca623ee9578c49b4495e220. 2022-09-17 08:35:46 +10:00
Zebediah Figura
ffaf883b19 Rebase against 7feaa6795a26c97b5ce4327a23129eb20a049859. 2022-09-14 17:30:59 -05:00
Zebediah Figura
19c062dbc7 dwrite-FontFallback: Remove remaining patches.
Per Nikolay, these are upstream now.

They would appear to be obviated by a10ae49292 and b783100773.
2022-09-14 10:34:47 -05:00
Zebediah Figura
1ed196f0ef ntdll-Junction_Points: Updates from Erich E. Hoover.
Includes a fundamental rewrite of the way reparse points are stored.
2022-09-12 10:58:36 -05:00
Zebediah Figura
533337e25e server-unix_name: Rebase and re-enable. 2022-09-11 17:05:58 -05:00
Zebediah Figura
7e2f1d392c mfplat-streaming-support: Remove patch 0080.
Per private correspondence with Rémi, this is correctly implemented upstream in
a different way, on the wg_transform side.
2022-09-11 17:05:58 -05:00
Zebediah Figura
129ce257fd mfplat-streaming-support: Remove patch 0041.
Per private correspondence with Rémi, this will probably be submitted a
different way upstream. Since it's only API cleanup, there's no reason to keep
it around in wine-staging.
2022-09-11 17:05:58 -05:00
Zebediah Figura
a27ba94091 mfplat-streaming-support: Remove patch 0042.
This patch looks questionable and, per private correspondence with Rémi, was probably a red herring.
2022-09-11 17:05:58 -05:00
Zebediah Figura
d490a981e1 mfplat-streaming-support: Remove patch 0083.
Per private correspondence with Rémi, this doesn't seem to be necessary.
2022-09-11 17:05:58 -05:00
Zebediah Figura
092bc29352 mfplat-streaming-support: Remove more patches which were already implemented upstream.
I missed these the first time; thanks Rémi for pointing them out.
2022-09-11 17:05:58 -05:00
Zebediah Figura
2ee26de43f dwrite-FontFallback: Drop some patches.
These are superseded and/or no longer useful upstream, per private correspondence with Nikolay.
2022-09-11 17:05:58 -05:00
104 changed files with 3217 additions and 8029 deletions

View File

@@ -64,60 +64,3 @@ jobs:
run: |
cd $GITHUB_WORKSPACE/wine
make -j$(sysctl -n hw.ncpu 2>/dev/null)
wine-devel:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
brew update
brew install --cask xquartz
brew install bison \
gphoto2 \
gst-plugins-base \
mingw-w64 \
molten-vk \
mpg123
- name: Add bison & krb5 to $PATH
run: |
set -eu
echo "$(brew --prefix bison)/bin" >> $GITHUB_PATH
echo "$(brew --prefix krb5)/bin" >> $GITHUB_PATH
- name: Get upstream-commit
run: |
mkdir $GITHUB_WORKSPACE/wine
cd wine
git init
git fetch git://source.winehq.org/git/wine.git $($GITHUB_WORKSPACE/patches/patchinstall.sh --upstream-commit) --depth=1
git checkout $($GITHUB_WORKSPACE/patches/patchinstall.sh --upstream-commit)
- name: Configure wine64
env:
LDFLAGS: "-Wl,-rpath,/opt/X11/lib"
# Avoid weird linker errors with Xcode 10 and later
MACOSX_DEPLOYMENT_TARGET: "10.14"
run: |
cd $GITHUB_WORKSPACE/wine
cd $GITHUB_WORKSPACE/wine
./configure --enable-win64 \
--without-alsa \
--without-capi \
--without-dbus \
--without-inotify \
--without-oss \
--without-pulse \
--without-udev \
--without-v4l2 \
--x-include=/opt/X11/include \
--x-lib=/opt/X11/lib
- name: Build wine64
run: |
cd $GITHUB_WORKSPACE/wine
make -j$(sysctl -n hw.ncpu 2>/dev/null)

View File

@@ -1,4 +1,4 @@
From 12a9a9cb506aede4748611c8fa3339afcee7c070 Mon Sep 17 00:00:00 2001
From eddc40dbf4048ceea1fda7f842adad340865723b Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Fri, 5 Jul 2019 13:20:23 +0800
Subject: [PATCH] cryptext: Implement CryptExtOpenCER.
@@ -17,29 +17,29 @@ Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
create mode 100644 dlls/cryptext/tests/cryptext.c
diff --git a/configure b/configure
index 20bcb96a2a6..b8fd60dbb53 100755
index 6425e4da5f8..c97671cdfc6 100755
--- a/configure
+++ b/configure
@@ -20910,6 +20910,7 @@ wine_fn_config_makefile dlls/crypt32/tests enable_tests
@@ -21346,6 +21346,7 @@ wine_fn_config_makefile dlls/crypt32/tests enable_tests
wine_fn_config_makefile dlls/cryptdlg enable_cryptdlg
wine_fn_config_makefile dlls/cryptdll enable_cryptdll
wine_fn_config_makefile dlls/cryptext enable_cryptext
+wine_fn_config_makefile dlls/cryptext/tests enable_tests
wine_fn_config_makefile dlls/cryptnet enable_cryptnet
wine_fn_config_makefile dlls/cryptnet/tests enable_tests
wine_fn_config_makefile dlls/cryptsp enable_cryptsp
wine_fn_config_makefile dlls/cryptowinrt enable_cryptowinrt
diff --git a/configure.ac b/configure.ac
index 6cbd947bf31..c68c5975e63 100644
index b5a3b0069fb..73b1b1c8c2b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2361,6 +2361,7 @@ WINE_CONFIG_MAKEFILE(dlls/crypt32/tests)
@@ -2450,6 +2450,7 @@ WINE_CONFIG_MAKEFILE(dlls/crypt32/tests)
WINE_CONFIG_MAKEFILE(dlls/cryptdlg)
WINE_CONFIG_MAKEFILE(dlls/cryptdll)
WINE_CONFIG_MAKEFILE(dlls/cryptext)
+WINE_CONFIG_MAKEFILE(dlls/cryptext/tests)
WINE_CONFIG_MAKEFILE(dlls/cryptnet)
WINE_CONFIG_MAKEFILE(dlls/cryptnet/tests)
WINE_CONFIG_MAKEFILE(dlls/cryptsp)
WINE_CONFIG_MAKEFILE(dlls/cryptowinrt)
diff --git a/dlls/cryptext/Makefile.in b/dlls/cryptext/Makefile.in
index 0ec2b8a2045..76accca43eb 100644
--- a/dlls/cryptext/Makefile.in
@@ -67,7 +67,7 @@ index ee3e155f457..24b4794c198 100644
@ stub CryptExtOpenCRLW
@ stub CryptExtOpenCTL
diff --git a/dlls/cryptext/cryptext_main.c b/dlls/cryptext/cryptext_main.c
index 537ba66cd3b..f9e34d1f8c5 100644
index 537ba66cd3b..a4314518eac 100644
--- a/dlls/cryptext/cryptext_main.c
+++ b/dlls/cryptext/cryptext_main.c
@@ -22,10 +22,29 @@
@@ -161,7 +161,7 @@ index 00000000000..522fc60a4af
+ cryptext.c
diff --git a/dlls/cryptext/tests/cryptext.c b/dlls/cryptext/tests/cryptext.c
new file mode 100644
index 00000000000..cc62a772b59
index 00000000000..ab1007dbd82
--- /dev/null
+++ b/dlls/cryptext/tests/cryptext.c
@@ -0,0 +1,61 @@
@@ -227,5 +227,5 @@ index 00000000000..cc62a772b59
+ test_CryptExtOpenCER();
+}
--
2.34.1
2.35.1

View File

@@ -1,69 +0,0 @@
From b1690a5bc6ea4cf670f3117f8caf9e229cd1f47d Mon Sep 17 00:00:00 2001
From: Lucian Poston <lucianposton@pm.me>
Date: Sun, 20 May 2018 21:40:39 -0700
Subject: [PATCH] dwrite: Test IDWriteTextFormat with nonexistent font
Signed-off-by: Lucian Poston <lucianposton@pm.me>
---
dlls/dwrite/tests/layout.c | 45 ++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index d19f91311db..d89ccc9d995 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -3290,6 +3290,51 @@ todo_wine
ok(metrics.lineCount == 1, "Unexpected line count %u.\n", metrics.lineCount);
IDWriteTextLayout_Release(layout);
+ IDWriteTextFormat_Release(format);
+
+ /* nonexistent font */
+ hr = IDWriteFactory_CreateTextFormat(factory, L"Blah!", NULL, DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, 10.0, L"en-us", &format);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 500.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ count = 0;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+todo_wine
+ ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth);
+todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+
+ IDWriteTextLayout_Release(layout);
+
IDWriteTextFormat_Release(format);
IDWriteFactory_Release(factory);
}
--
2.17.1

View File

@@ -1,332 +0,0 @@
From 79b9dda91ac0e33add2252f9ad5c10ba752ddabb Mon Sep 17 00:00:00 2001
From: Lucian Poston <lucianposton@pm.me>
Date: Wed, 23 May 2018 00:01:42 -0700
Subject: [PATCH] dwrite: Test GetMetrics with custom fontcollection
Signed-off-by: Lucian Poston <lucianposton@pm.me>
---
dlls/dwrite/tests/layout.c | 280 ++++++++++++++++++++++++++++++++++++-
1 file changed, 279 insertions(+), 1 deletion(-)
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 9a450495146..9f1051b4905 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -3363,7 +3363,7 @@ todo_wine
DWRITE_FONT_STRETCH_NORMAL, 10.0, L"en-us", &format);
ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IDWriteFactory_CreateTextLayout(factory, strW, 4, format, 500.0, 1000.0, &layout);
+ hr = IDWriteFactory_CreateTextLayout(factory, L"A", 4, format, 500.0, 1000.0, &layout);
ok(hr == S_OK, "got 0x%08x\n", hr);
count = 0;
@@ -4546,6 +4546,7 @@ static void test_SetWordWrapping(void)
/* Collection dedicated to fallback testing */
static const WCHAR g_blahfontW[] = {'B','l','a','h',0};
+static const WCHAR g_fontNotInCollectionW[] = {'n','o','t','B','l','a','h',0};
static HRESULT WINAPI fontcollection_QI(IDWriteFontCollection *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IDWriteFontCollection) || IsEqualIID(riid, &IID_IUnknown)) {
@@ -4607,6 +4608,9 @@ static HRESULT WINAPI fontcollection_FindFamilyName(IDWriteFontCollection *iface
*index = 123456;
*exists = TRUE;
return S_OK;
+ } else if (!lstrcmpW(name, g_fontNotInCollectionW)) {
+ *exists = FALSE;
+ return S_OK;
}
ok(0, "unexpected call, name %s\n", wine_dbgstr_w(name));
return E_NOTIMPL;
@@ -6405,6 +6409,279 @@ static void test_layout_range_length(void)
IDWriteFactory_Release(factory);
}
+static void test_GetMetrics_with_custom_fontcollection(void)
+{
+ static const WCHAR emptystringW[] = {0};
+ static const WCHAR mappedW[] = {'a','b','c','d',0};
+ static const WCHAR notmappedW[] = {'a',0xffff,'b',0}; // u+ffff = not a unicode character
+ DWRITE_CLUSTER_METRICS clusters[4];
+ DWRITE_TEXT_METRICS metrics;
+ IDWriteTextFormat *format;
+ IDWriteTextLayout *layout;
+ IDWriteFactory *factory;
+ UINT32 count, i;
+ FLOAT width;
+ HRESULT hr;
+
+ factory = create_factory();
+
+ /* font is in font collection */
+ hr = IDWriteFactory_CreateTextFormat(factory, g_blahfontW, &fallbackcollection,
+ DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, 10.0, L"en-us", &format);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* text is mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* text is not mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* zero-length empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 0, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ IDWriteTextFormat_Release(format);
+
+ /* font not in font collection */
+ hr = IDWriteFactory_CreateTextFormat(factory, g_fontNotInCollectionW, &fallbackcollection,
+ DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STYLE_NORMAL,
+ DWRITE_FONT_STRETCH_NORMAL, 10.0, L"en-us", &format);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+
+ /* text is mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, mappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* text is not mapped by fontfallback */
+ hr = IDWriteFactory_CreateTextLayout(factory, notmappedW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 4, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(count == 4, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ /* zero-length empty string */
+ hr = IDWriteFactory_CreateTextLayout(factory, emptystringW, 0, format, 1000.0, 1000.0, &layout);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ count = 9999;
+ hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok(count == 0, "got %u\n", count);
+ for (i = 0, width = 0.0; i < count; i++)
+ width += clusters[i].width;
+ memset(&metrics, 0xcc, sizeof(metrics));
+ hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
+ todo_wine
+ ok(hr == S_OK, "got 0x%08x\n", hr);
+ todo_wine
+ ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
+ todo_wine
+ ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
+ todo_wine
+ ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
+ todo_wine
+ ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
+ metrics.widthIncludingTrailingWhitespace, width);
+ todo_wine
+ ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
+ todo_wine
+ ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
+ todo_wine
+ ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
+ todo_wine
+ ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
+ todo_wine
+ ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
+ IDWriteTextLayout_Release(layout);
+
+ IDWriteTextFormat_Release(format);
+
+ IDWriteFactory_Release(factory);
+}
+
START_TEST(layout)
{
IDWriteFactory *factory;
@@ -6438,6 +6715,7 @@ START_TEST(layout)
test_SetFontStretch();
test_SetStrikethrough();
test_GetMetrics();
+ test_GetMetrics_with_custom_fontcollection();
test_SetFlowDirection();
test_SetDrawingEffect();
test_GetLineMetrics();
--
2.20.1

View File

@@ -1,311 +0,0 @@
From bf4cc6cfca946ff719763bb7be25fe268577f0d3 Mon Sep 17 00:00:00 2001
From: Lucian Poston <lucianposton@pm.me>
Date: Mon, 21 May 2018 18:13:00 -0700
Subject: [PATCH] dwrite: Use font fallback when mapping characters
Signed-off-by: Lucian Poston <lucianposton@pm.me>
---
dlls/dwrite/analyzer.c | 77 +++++++++++++++++++++++++++++---------
dlls/dwrite/layout.c | 6 +++
dlls/dwrite/tests/layout.c | 54 ++++----------------------
3 files changed, 73 insertions(+), 64 deletions(-)
diff --git a/dlls/dwrite/analyzer.c b/dlls/dwrite/analyzer.c
index 7ffcfa8070c..aab309c2a8c 100644
--- a/dlls/dwrite/analyzer.c
+++ b/dlls/dwrite/analyzer.c
@@ -2094,6 +2094,7 @@ static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback,
IDWriteFont **mapped_font)
{
const struct fallback_mapping *mapping;
+ IDWriteFontCollection *collection;
HRESULT hr;
UINT32 i;
@@ -2105,9 +2106,15 @@ static HRESULT fallback_get_fallback_font(struct dwrite_fontfallback *fallback,
return E_FAIL;
}
+ if (mapping->collection) {
+ collection = mapping->collection;
+ } else {
+ collection = (IDWriteFontCollection *)fallback->systemcollection;
+ }
+
/* Now let's see what fallback can handle. Pick first font that could be created. */
for (i = 0; i < mapping->families_count; i++) {
- hr = create_matching_font((IDWriteFontCollection *)fallback->systemcollection, mapping->families[i],
+ hr = create_matching_font(collection, mapping->families[i],
weight, style, stretch, mapped_font);
if (hr == S_OK) {
TRACE("Created fallback font using family %s.\n", debugstr_w(mapping->families[i]));
@@ -2164,32 +2171,66 @@ static HRESULT WINAPI fontfallback_MapCharacters(IDWriteFontFallback1 *iface, ID
if (basefamily && *basefamily) {
hr = create_matching_font(basecollection, basefamily, weight, style, stretch, ret_font);
- if (FAILED(hr))
- goto done;
-
- hr = fallback_map_characters(*ret_font, text, length, mapped_length);
- if (FAILED(hr))
- goto done;
+ if (SUCCEEDED(hr)) {
+ hr = fallback_map_characters(*ret_font, text, length, mapped_length);
+ if (FAILED(hr)) {
+ IDWriteFont_Release(*ret_font);
+ *ret_font = NULL;
+ WARN("Mapping with requested family %s failed, hr %#x.\n", debugstr_w(basefamily), hr);
+ }
+ }
}
if (!*mapped_length) {
- IDWriteFont *mapped_font;
+ if (*ret_font) {
+ IDWriteFont_Release(*ret_font);
+ *ret_font = NULL;
+ }
- hr = fallback_get_fallback_font(fallback, text, length, weight, style, stretch, mapped_length, &mapped_font);
+ hr = fallback_get_fallback_font(fallback, text, length, weight, style, stretch, mapped_length, ret_font);
if (FAILED(hr)) {
- /* fallback wasn't found, keep base font if any, so we can get at least some visual output */
- if (*ret_font) {
- *mapped_length = length;
- hr = S_OK;
- }
+ WARN("Mapping with fallback families failed, hr %#x.\n", hr);
}
- else {
- if (*ret_font)
- IDWriteFont_Release(*ret_font);
- *ret_font = mapped_font;
+ }
+
+ /**
+ * This is a rough hack. We search the system font collection because
+ * the system fontfallback, which would have been searched above, is not
+ * fully implemented as it isn't populated with any system fonts. Once
+ * implemented, the block below can be removed.
+ * */
+ if (!*mapped_length) {
+ IDWriteFontFamily *family;
+ IDWriteFont *font;
+ UINT32 i, count = IDWriteFontCollection_GetFontFamilyCount((IDWriteFontCollection *)fallback->systemcollection);
+ for (i = 0; i < count; i++) {
+ hr = IDWriteFontCollection_GetFontFamily((IDWriteFontCollection *)fallback->systemcollection, i, &family);
+ if (FAILED(hr)) {
+ ERR("Failed to get font family.\n");
+ continue;
+ }
+
+ hr = IDWriteFontFamily_GetFirstMatchingFont(family, weight, stretch, style, &font);
+ IDWriteFontFamily_Release(family);
+ if (FAILED(hr)) {
+ continue;
+ }
+
+ hr = fallback_map_characters(font, text, length, mapped_length);
+ if (SUCCEEDED(hr) && mapped_length > 0) {
+ *ret_font = font;
+ break;
+ }
+
+ IDWriteFont_Release(font);
}
}
+ if (!*mapped_length) {
+ *mapped_length = length == 0 ? 0 : 1;
+ hr = S_OK;
+ }
+
done:
free(buff);
return hr;
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index ba80c3f70e8..c7845f9b675 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -725,6 +725,12 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout)
goto fatal;
}
+ if (!font) {
+ hr = E_FAIL;
+ WARN("Failed to create font face, hr %#x.\n", hr);
+ goto fatal;
+ }
+
hr = IDWriteFont_CreateFontFace(font, &run->run.fontFace);
IDWriteFont_Release(font);
if (FAILED(hr)) {
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 3efedd3df95..07687c76c60 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -3366,35 +3366,23 @@ static void test_GetMetrics(void)
count = 0;
hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
-todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
-todo_wine
ok(count == 4, "got %u\n", count);
for (i = 0, width = 0.0; i < count; i++)
width += clusters[i].width;
memset(&metrics, 0xcc, sizeof(metrics));
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
-todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
-todo_wine
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
-todo_wine
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
-todo_wine
ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
-todo_wine
ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
metrics.widthIncludingTrailingWhitespace, width);
-todo_wine
ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
-todo_wine
ok(metrics.layoutWidth == 500.0, "got %.2f\n", metrics.layoutWidth);
-todo_wine
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
-todo_wine
ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
-todo_wine
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
IDWriteTextLayout_Release(layout);
@@ -4688,16 +4676,12 @@ static void test_MapCharacters(void)
font = NULL;
hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 1, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale);
-todo_wine {
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(mappedlength == 1, "got %u\n", mappedlength);
-}
ok(scale == 1.0f, "got %f\n", scale);
- todo_wine
ok(font != NULL, "got %p\n", font);
-if (font) {
IDWriteFont_Release(font);
-}
+
/* same Latin text, full length */
g_source = L"abc";
mappedlength = 0;
@@ -4705,16 +4689,12 @@ if (font) {
font = NULL;
hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 3, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale);
-todo_wine {
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(mappedlength == 3, "got %u\n", mappedlength);
-}
ok(scale == 1.0f, "got %f\n", scale);
- todo_wine
ok(font != NULL, "got %p\n", font);
-if (font) {
IDWriteFont_Release(font);
-}
+
/* string 'a\x3058b' */
g_source = str2W;
mappedlength = 0;
@@ -4722,32 +4702,24 @@ if (font) {
font = NULL;
hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 0, 3, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale);
-todo_wine {
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(mappedlength == 1, "got %u\n", mappedlength);
-}
ok(scale == 1.0f, "got %f\n", scale);
- todo_wine
ok(font != NULL, "got %p\n", font);
-if (font) {
IDWriteFont_Release(font);
-}
+
g_source = str2W;
mappedlength = 0;
scale = 0.0f;
font = NULL;
hr = IDWriteFontFallback_MapCharacters(fallback, &analysissource, 1, 2, NULL, NULL, DWRITE_FONT_WEIGHT_NORMAL,
DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, &mappedlength, &font, &scale);
-todo_wine {
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(mappedlength == 1, "got %u\n", mappedlength);
-}
ok(scale == 1.0f, "got %f\n", scale);
- todo_wine
ok(font != NULL, "got %p\n", font);
-if (font) {
IDWriteFont_Release(font);
-}
+
/* Try with explicit collection, Tahoma will be forced. */
/* 1. Latin part */
g_source = str2W;
@@ -4770,7 +4742,10 @@ if (font) {
IDWriteLocalizedStrings_Release(strings);
IDWriteFont_Release(font);
- /* 2. Hiragana character, force Tahoma font does not support Japanese */
+ /**
+ * 2. Hiragana character. Tahoma is requested, but it doesn't support
+ * Japanese. A NULL font is returned if there is no fallback for Japanese.
+ */
g_source = str2W;
mappedlength = 0;
scale = 0.0f;
@@ -4780,7 +4755,6 @@ if (font) {
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
ok(mappedlength == 1, "got %u\n", mappedlength);
ok(scale == 1.0f, "got %f\n", scale);
- ok(font != NULL, "got %p\n", font);
exists = FALSE;
hr = IDWriteFont_GetInformationalStrings(font, DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES, &strings, &exists);
@@ -6667,34 +6641,22 @@ static void test_GetMetrics_with_custom_fontcollection(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
count = 9999;
hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
- todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine
ok(count == 4, "got %u\n", count);
for (i = 0, width = 0.0; i < count; i++)
width += clusters[i].width;
memset(&metrics, 0xcc, sizeof(metrics));
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
- todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
- todo_wine
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
- todo_wine
ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
- todo_wine
ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
metrics.widthIncludingTrailingWhitespace, width);
- todo_wine
ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
- todo_wine
ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
- todo_wine
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
- todo_wine
ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
- todo_wine
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
IDWriteTextLayout_Release(layout);
--
2.35.1

View File

@@ -1,128 +0,0 @@
From 838b8a5edeca6c06c20bdc301f4d5d658e835cc9 Mon Sep 17 00:00:00 2001
From: Lucian Poston <lucianposton@pm.me>
Date: Wed, 23 May 2018 05:59:20 -0700
Subject: [PATCH 5/6] dwrite: Use MapCharacters for non-visual characters
Signed-off-by: Lucian Poston <lucianposton@pm.me>
---
dlls/dwrite/layout.c | 22 +++++++++++++++-------
dlls/dwrite/tests/layout.c | 24 ------------------------
2 files changed, 15 insertions(+), 31 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index df3f3beabb..5d06bf9348 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -822,7 +822,8 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout)
LIST_FOR_EACH_ENTRY(r, &layout->runs, struct layout_run, entry) {
struct regular_layout_run *run = &r->u.regular;
IDWriteFont *font;
- UINT32 length;
+ UINT32 length, mapped_length;
+ FLOAT scale;
if (r->kind == LAYOUT_RUN_INLINE)
continue;
@@ -830,12 +831,19 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout)
range = get_layout_range_by_pos(layout, run->descr.textPosition);
if (run->sa.shapes == DWRITE_SCRIPT_SHAPES_NO_VISUAL) {
- IDWriteFontCollection *collection;
-
- collection = range->collection ? range->collection : sys_collection;
-
- if (FAILED(hr = create_matching_font(collection, range->fontfamily, range->weight, range->style,
- range->stretch, &font))) {
+ hr = IDWriteFontFallback_MapCharacters(fallback,
+ (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface,
+ run->descr.textPosition,
+ run->descr.stringLength,
+ range->collection,
+ range->fontfamily,
+ range->weight,
+ range->style,
+ range->stretch,
+ &mapped_length,
+ &font,
+ &scale);
+ if (FAILED(hr)) {
WARN("%s: failed to create matching font for non visual run, family %s, collection %p\n",
debugstr_rundescr(&run->descr), debugstr_w(range->fontfamily), range->collection);
break;
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index 430bb1f0eb..cf1d5d7060 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -5713,34 +5713,22 @@ static void test_GetMetrics_with_custom_fontcollection(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
count = 9999;
hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
- todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine
ok(count == 4, "got %u\n", count);
for (i = 0, width = 0.0; i < count; i++)
width += clusters[i].width;
memset(&metrics, 0xcc, sizeof(metrics));
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
- todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
- todo_wine
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
- todo_wine
ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
- todo_wine
ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
metrics.widthIncludingTrailingWhitespace, width);
- todo_wine
ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
- todo_wine
ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
- todo_wine
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
- todo_wine
ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
- todo_wine
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
IDWriteTextLayout_Release(layout);
@@ -5749,34 +5737,22 @@ static void test_GetMetrics_with_custom_fontcollection(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
count = 9999;
hr = IDWriteTextLayout_GetClusterMetrics(layout, clusters, 4, &count);
- todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine
ok(count == 4, "got %u\n", count);
for (i = 0, width = 0.0; i < count; i++)
width += clusters[i].width;
memset(&metrics, 0xcc, sizeof(metrics));
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
- todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
- todo_wine
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
- todo_wine
ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
- todo_wine
ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
metrics.widthIncludingTrailingWhitespace, width);
- todo_wine
ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
- todo_wine
ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
- todo_wine
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
- todo_wine
ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
- todo_wine
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
IDWriteTextLayout_Release(layout);
--
2.18.0

View File

@@ -1,96 +0,0 @@
From a0f4bde380003f7a8e3b713028215bf985dbb3c0 Mon Sep 17 00:00:00 2001
From: Lucian Poston <lucianposton@pm.me>
Date: Wed, 23 May 2018 07:03:44 -0700
Subject: [PATCH 6/6] dwrite: Use MapCharacters for dummy line metrics
Fixes: https://bugs.winehq.org/show_bug.cgi?id=44052
Signed-off-by: Lucian Poston <lucianposton@pm.me>
---
dlls/dwrite/layout.c | 29 +++++++++++++++++++++++++++++
dlls/dwrite/tests/layout.c | 8 --------
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index 5d06bf9348..2213717f92 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -1808,8 +1808,11 @@ static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, U
DWRITE_FONT_METRICS fontmetrics;
struct layout_range *range;
IDWriteFontFace *fontface;
+ IDWriteFontFallback *fallback;
IDWriteFont *font;
HRESULT hr;
+ UINT32 mapped_length;
+ FLOAT scale;
range = get_layout_range_by_pos(layout, pos);
hr = create_matching_font(range->collection,
@@ -1818,8 +1821,34 @@ static HRESULT layout_set_dummy_line_metrics(struct dwrite_textlayout *layout, U
range->style,
range->stretch,
&font);
+
+ if (FAILED(hr)) {
+ if (layout->format.fallback) {
+ fallback = layout->format.fallback;
+ IDWriteFontFallback_AddRef(fallback);
+ } else if (FAILED(hr = IDWriteFactory7_GetSystemFontFallback(layout->factory, &fallback))) {
+ WARN("Failed to get system fallback, hr %#x.\n", hr);
+ return hr;
+ }
+
+ hr = IDWriteFontFallback_MapCharacters(fallback,
+ (IDWriteTextAnalysisSource *)&layout->IDWriteTextAnalysisSource1_iface,
+ pos,
+ layout->len,
+ range->collection,
+ range->fontfamily,
+ range->weight,
+ range->style,
+ range->stretch,
+ &mapped_length,
+ &font,
+ &scale);
+ IDWriteFontFallback_Release(fallback);
+ }
if (FAILED(hr))
return hr;
+ if (font == NULL)
+ return S_OK;
hr = IDWriteFont_CreateFontFace(font, &fontface);
IDWriteFont_Release(font);
if (FAILED(hr))
diff --git a/dlls/dwrite/tests/layout.c b/dlls/dwrite/tests/layout.c
index cf1d5d7060..6ed7b3c334 100644
--- a/dlls/dwrite/tests/layout.c
+++ b/dlls/dwrite/tests/layout.c
@@ -5767,24 +5767,16 @@ static void test_GetMetrics_with_custom_fontcollection(void)
width += clusters[i].width;
memset(&metrics, 0xcc, sizeof(metrics));
hr = IDWriteTextLayout_GetMetrics(layout, &metrics);
- todo_wine
ok(hr == S_OK, "got 0x%08x\n", hr);
- todo_wine
ok(metrics.left == 0.0, "got %.2f\n", metrics.left);
- todo_wine
ok(metrics.top == 0.0, "got %.2f\n", metrics.top);
- todo_wine
ok(metrics.width == width, "got %.2f, expected %.2f\n", metrics.width, width);
- todo_wine
ok(metrics.widthIncludingTrailingWhitespace == width, "got %.2f, expected %.2f\n",
metrics.widthIncludingTrailingWhitespace, width);
todo_wine
ok(metrics.height > 0.0, "got %.2f\n", metrics.height);
- todo_wine
ok(metrics.layoutWidth == 1000.0, "got %.2f\n", metrics.layoutWidth);
- todo_wine
ok(metrics.layoutHeight == 1000.0, "got %.2f\n", metrics.layoutHeight);
- todo_wine
ok(metrics.maxBidiReorderingDepth == 1, "got %u\n", metrics.maxBidiReorderingDepth);
todo_wine
ok(metrics.lineCount == 1, "got %u\n", metrics.lineCount);
--
2.18.0

View File

@@ -1,2 +0,0 @@
Fixes: [44052] - Support for font fallback.
Disabled: True

View File

@@ -1,4 +1,4 @@
From a791c331b23e717a5f6c0397e4c290e8e8abd2f2 Mon Sep 17 00:00:00 2001
From 9829e3c307e8019a3a2b9204d1133833863da5f1 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sat, 7 Jul 2018 12:57:47 +0200
Subject: [PATCH] server: Create eventfd descriptors for pseudo-fd objects and
@@ -11,10 +11,10 @@ Subject: [PATCH] server: Create eventfd descriptors for pseudo-fd objects and
3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/server/fd.c b/server/fd.c
index 880a5037925..c6db8d13265 100644
index 6a1b89b0e54..8ba704344cf 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -102,6 +102,7 @@
@@ -97,6 +97,7 @@
#include "handle.h"
#include "process.h"
#include "request.h"
@@ -22,7 +22,7 @@ index 880a5037925..c6db8d13265 100644
#include "winternl.h"
#include "winioctl.h"
@@ -205,6 +206,7 @@ struct fd
@@ -198,6 +199,7 @@ struct fd
struct completion *completion; /* completion object attached to this fd */
apc_param_t comp_key; /* completion key to set in completion events */
unsigned int comp_flags; /* completion flags */
@@ -30,8 +30,8 @@ index 880a5037925..c6db8d13265 100644
};
static void fd_dump( struct object *obj, int verbose );
@@ -1606,6 +1608,9 @@ static void fd_destroy( struct object *obj )
free( fd->unlink_name );
@@ -1668,6 +1670,9 @@ static void fd_destroy( struct object *obj )
if (fd->unix_fd != -1) close( fd->unix_fd );
free( fd->unix_name );
}
+
@@ -40,7 +40,7 @@ index 880a5037925..c6db8d13265 100644
}
/* check if the desired access is possible without violating */
@@ -1723,6 +1728,7 @@ static struct fd *alloc_fd_object(void)
@@ -1784,6 +1789,7 @@ static struct fd *alloc_fd_object(void)
fd->poll_index = -1;
fd->completion = NULL;
fd->comp_flags = 0;
@@ -48,7 +48,7 @@ index 880a5037925..c6db8d13265 100644
init_async_queue( &fd->read_q );
init_async_queue( &fd->write_q );
init_async_queue( &fd->wait_q );
@@ -1763,11 +1769,15 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
@@ -1823,11 +1829,15 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
fd->completion = NULL;
fd->comp_flags = 0;
fd->no_fd_status = STATUS_BAD_DEVICE_TYPE;
@@ -64,7 +64,7 @@ index 880a5037925..c6db8d13265 100644
return fd;
}
@@ -2293,6 +2303,9 @@ void set_fd_signaled( struct fd *fd, int signaled )
@@ -2268,6 +2278,9 @@ void set_fd_signaled( struct fd *fd, int signaled )
if (fd->comp_flags & FILE_SKIP_SET_EVENT_ON_HANDLE) return;
fd->signaled = signaled;
if (signaled) wake_up( fd->user, 0 );
@@ -74,7 +74,7 @@ index 880a5037925..c6db8d13265 100644
}
/* check if events are pending and if yes return which one(s) */
@@ -2318,6 +2331,15 @@ int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry )
@@ -2293,6 +2306,15 @@ int default_fd_signaled( struct object *obj, struct wait_queue_entry *entry )
return ret;
}
@@ -91,7 +91,7 @@ index 880a5037925..c6db8d13265 100644
{
int events = 0;
diff --git a/server/file.h b/server/file.h
index 80f2191c050..224048a4292 100644
index 0ffe0e2c8dc..b5b1e2a1077 100644
--- a/server/file.h
+++ b/server/file.h
@@ -106,6 +106,7 @@ extern char *dup_fd_name( struct fd *root, const char *name );
@@ -103,7 +103,7 @@ index 80f2191c050..224048a4292 100644
extern void default_poll_event( struct fd *fd, int event );
extern void fd_cancel_async( struct fd *fd, struct async *async );
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 6b4401810dc..27f4497bfe2 100644
index b8ec17a787a..e01b28f725a 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -168,7 +168,7 @@ static const struct object_ops pipe_server_ops =
@@ -125,5 +125,5 @@ index 6b4401810dc..27f4497bfe2 100644
no_signal, /* signal */
pipe_end_get_fd, /* get_fd */
--
2.33.0
2.35.1

View File

@@ -1,73 +0,0 @@
From 7e5a1d66b93df6e2dd29a753190bbe9c0c31993e Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Wed, 17 Mar 2021 15:37:17 -0400
Subject: [PATCH 29/88] winegstreamer: Register the color conversion transform.
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
---
dlls/winegstreamer/mfplat.c | 35 +++++++++++++++++++++++++++++++++--
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 6f6ec956b2b..54874ad43ee 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -465,6 +465,26 @@ static const GUID *const wma_decoder_output_types[] =
&MFAudioFormat_Float,
};
+static WCHAR color_converterW[] = L"Color Converter";
+static const GUID *color_converter_supported_types[] =
+{
+ &MFVideoFormat_RGB24,
+ &MFVideoFormat_RGB32,
+ &MFVideoFormat_RGB555,
+ &MFVideoFormat_RGB8,
+ &MFVideoFormat_AYUV,
+ &MFVideoFormat_I420,
+ &MFVideoFormat_IYUV,
+ &MFVideoFormat_NV11,
+ &MFVideoFormat_NV12,
+ &MFVideoFormat_UYVY,
+ &MFVideoFormat_v216,
+ &MFVideoFormat_v410,
+ &MFVideoFormat_YUY2,
+ &MFVideoFormat_YVYU,
+ &MFVideoFormat_YVYU,
+};
+
static WCHAR h264_decoderW[] = L"H.264 Decoder";
static const GUID *h264_decoder_input_types[] =
{
@@ -516,7 +536,18 @@ mfts[] =
wma_decoder_output_types,
},
{
- &CLSID_MSH264DecoderMFT,
+ &CLSID_CColorConvertDMO,
+ &MFT_CATEGORY_VIDEO_EFFECT,
+ color_converterW,
+ MFT_ENUM_FLAG_SYNCMFT,
+ &MFMediaType_Video,
+ ARRAY_SIZE(color_converter_supported_types),
+ color_converter_supported_types,
+ ARRAY_SIZE(color_converter_supported_types),
+ color_converter_supported_types,
+ },
+ {
+ &CLSID_MSAACDecMFT,
&MFT_CATEGORY_VIDEO_DECODER,
h264_decoderW,
MFT_ENUM_FLAG_SYNCMFT,
@@ -532,7 +563,7 @@ HRESULT mfplat_DllRegisterServer(void)
{
unsigned int i, j;
HRESULT hr;
- MFT_REGISTER_TYPE_INFO input_types[4], output_types[2];
+ MFT_REGISTER_TYPE_INFO input_types[15], output_types[15];
for (i = 0; i < ARRAY_SIZE(mfts); i++)
{
--
2.34.1

View File

@@ -1,190 +0,0 @@
From 6cc6888966a9d0d7da6ed866ece791ca0e6afd61 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 15 Dec 2021 11:26:41 +0100
Subject: [PATCH 41/88] winegstreamer: Add an explicit result to
wg_parser_push_data.
---
dlls/winegstreamer/gst_private.h | 2 +-
dlls/winegstreamer/main.c | 3 ++-
dlls/winegstreamer/media_source.c | 4 ++--
dlls/winegstreamer/quartz_parser.c | 2 +-
dlls/winegstreamer/unixlib.h | 9 +++++++++
dlls/winegstreamer/wg_parser.c | 19 ++++++++++++++++++-
dlls/winegstreamer/wm_reader.c | 8 ++++----
7 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 6149ae5959c..c156d87450c 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -74,7 +74,7 @@ void wg_parser_begin_flush(struct wg_parser *parser);
void wg_parser_end_flush(struct wg_parser *parser);
bool wg_parser_get_next_read_offset(struct wg_parser *parser, uint64_t *offset, uint32_t *size);
-void wg_parser_push_data(struct wg_parser *parser, const void *data, uint32_t size);
+void wg_parser_push_data(struct wg_parser *parser, enum wg_read_result result, const void *data, uint32_t size);
uint32_t wg_parser_get_stream_count(struct wg_parser *parser);
struct wg_parser_stream *wg_parser_get_stream(struct wg_parser *parser, uint32_t index);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 66b7a1195ee..db05594f464 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -120,11 +120,12 @@ bool wg_parser_get_next_read_offset(struct wg_parser *parser, uint64_t *offset,
return true;
}
-void wg_parser_push_data(struct wg_parser *parser, const void *data, uint32_t size)
+void wg_parser_push_data(struct wg_parser *parser, enum wg_read_result result, const void *data, uint32_t size)
{
struct wg_parser_push_data_params params =
{
.parser = parser,
+ .result = result,
.data = data,
.size = size,
};
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index c97348cc2d6..fd6479d9879 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -644,7 +644,7 @@ static DWORD CALLBACK read_thread(void *arg)
* an error when reading past the file size. */
if (!size)
{
- wg_parser_push_data(source->wg_parser, data, 0);
+ wg_parser_push_data(source->wg_parser, WG_READ_SUCCESS, data, 0);
continue;
}
@@ -662,7 +662,7 @@ static DWORD CALLBACK read_thread(void *arg)
ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
else if (ret_size != size)
ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size);
- wg_parser_push_data(source->wg_parser, SUCCEEDED(hr) ? data : NULL, ret_size);
+ wg_parser_push_data(source->wg_parser, SUCCEEDED(hr) ? WG_READ_SUCCESS : WG_READ_FAILURE, data, ret_size);
}
free(data);
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
index 8ea9291904e..c44bd141c56 100644
--- a/dlls/winegstreamer/quartz_parser.c
+++ b/dlls/winegstreamer/quartz_parser.c
@@ -876,7 +876,7 @@ static DWORD CALLBACK read_thread(void *arg)
if (FAILED(hr))
ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
- wg_parser_push_data(filter->wg_parser, SUCCEEDED(hr) ? data : NULL, size);
+ wg_parser_push_data(filter->wg_parser, SUCCEEDED(hr) ? WG_READ_SUCCESS : WG_READ_FAILURE, data, size);
}
free(data);
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index fc9d0c3c80d..f20ee5bb52f 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -125,6 +125,14 @@ enum wg_parser_event_type
WG_PARSER_EVENT_SEGMENT,
};
+enum wg_read_result
+{
+ WG_READ_SUCCESS,
+ WG_READ_FAILURE,
+ WG_READ_FLUSHING,
+ WG_READ_EOS,
+};
+
struct wg_parser_event
{
enum wg_parser_event_type type;
@@ -177,6 +185,7 @@ struct wg_parser_get_next_read_offset_params
struct wg_parser_push_data_params
{
struct wg_parser *parser;
+ enum wg_read_result result;
const void *data;
UINT32 size;
};
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index f70c1a449c7..df4dca4a69f 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -647,16 +647,33 @@ static NTSTATUS wg_parser_get_next_read_offset(void *args)
return S_OK;
}
+static GstFlowReturn wg_read_result_to_gst(enum wg_read_result result)
+{
+ switch (result)
+ {
+ case WG_READ_SUCCESS: return GST_FLOW_OK;
+ case WG_READ_FAILURE: return GST_FLOW_ERROR;
+ case WG_READ_FLUSHING: return GST_FLOW_FLUSHING;
+ case WG_READ_EOS: return GST_FLOW_EOS;
+ }
+ return GST_FLOW_ERROR;
+}
+
static NTSTATUS wg_parser_push_data(void *args)
{
const struct wg_parser_push_data_params *params = args;
struct wg_parser *parser = params->parser;
+ enum wg_read_result result = params->result;
const void *data = params->data;
uint32_t size = params->size;
pthread_mutex_lock(&parser->mutex);
- if (data)
+ if (result != WG_READ_SUCCESS)
+ {
+ parser->read_request.ret = wg_read_result_to_gst(result);
+ }
+ else if (data)
{
if (size)
{
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index d40afb66afd..ee37abee811 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -573,7 +573,7 @@ static DWORD CALLBACK read_thread(void *arg)
if (!size)
{
- wg_parser_push_data(reader->wg_parser, data, 0);
+ wg_parser_push_data(reader->wg_parser, WG_READ_SUCCESS, data, 0);
continue;
}
@@ -592,7 +592,7 @@ static DWORD CALLBACK read_thread(void *arg)
|| !ReadFile(file, data, size, &ret_size, NULL))
{
ERR("Failed to read %u bytes at offset %I64u, error %lu.\n", size, offset, GetLastError());
- wg_parser_push_data(reader->wg_parser, NULL, 0);
+ wg_parser_push_data(reader->wg_parser, WG_READ_FAILURE, NULL, 0);
continue;
}
}
@@ -603,14 +603,14 @@ static DWORD CALLBACK read_thread(void *arg)
if (FAILED(hr))
{
ERR("Failed to read %u bytes at offset %I64u, hr %#lx.\n", size, offset, hr);
- wg_parser_push_data(reader->wg_parser, NULL, 0);
+ wg_parser_push_data(reader->wg_parser, WG_READ_FAILURE, NULL, 0);
continue;
}
}
if (ret_size != size)
ERR("Unexpected short read: requested %u bytes, got %lu.\n", size, ret_size);
- wg_parser_push_data(reader->wg_parser, data, ret_size);
+ wg_parser_push_data(reader->wg_parser, WG_READ_SUCCESS, data, ret_size);
}
free(data);
--
2.34.1

View File

@@ -1,26 +0,0 @@
From e6f2e0b82e251f650c00c6e270fb615a19a16e19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 15 Dec 2021 11:51:33 +0100
Subject: [PATCH 42/88] winegstreamer: Unblock wg_parser_get_next_read_offset
on read errors too.
---
dlls/winegstreamer/wg_parser.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index df4dca4a69f..a11fc8c4f68 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -631,7 +631,7 @@ static NTSTATUS wg_parser_get_next_read_offset(void *args)
pthread_mutex_lock(&parser->mutex);
- while (parser->sink_connected && !parser->read_request.size)
+ while (parser->sink_connected && (!parser->read_request.size || parser->read_request.done))
pthread_cond_wait(&parser->read_cond, &parser->mutex);
if (!parser->sink_connected)
--
2.34.1

View File

@@ -1,376 +0,0 @@
From 4f6593d81e43fc0b8e06019e1931f9791856c184 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 15 Dec 2021 10:30:26 +0100
Subject: [PATCH 52/88] winegstreamer: Add videobox element and aperture
support.
---
dlls/winegstreamer/audioconvert.c | 4 +--
dlls/winegstreamer/colorconvert.c | 4 +--
dlls/winegstreamer/decode_transform.c | 23 ++++++++++++++-
dlls/winegstreamer/gst_private.h | 4 +--
dlls/winegstreamer/main.c | 6 ++--
dlls/winegstreamer/media_source.c | 2 +-
dlls/winegstreamer/quartz_parser.c | 2 +-
dlls/winegstreamer/unixlib.h | 10 +++++++
dlls/winegstreamer/wg_parser.c | 42 +++++++++++++++++++++++++--
dlls/winegstreamer/wm_reader.c | 6 ++--
10 files changed, 86 insertions(+), 17 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index f8d5833aa22..28d449e9f9b 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -417,7 +417,7 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
struct wg_format output_format;
mf_media_type_to_wg_format(converter->output_type, &output_format);
- if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &format, 1, &output_format)))
+ if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &format, 1, &output_format, NULL)))
converter->stream = wg_parser_get_stream(converter->parser, 0);
}
@@ -513,7 +513,7 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
struct wg_format input_format;
mf_media_type_to_wg_format(converter->input_type, &input_format);
- if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &input_format, 1, &format)))
+ if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &input_format, 1, &format, NULL)))
converter->stream = wg_parser_get_stream(converter->parser, 0);
}
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index 6cad0c1706d..476851fa43a 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -423,7 +423,7 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
struct wg_format output_format;
mf_media_type_to_wg_format(converter->output_type, &output_format);
- if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &format, 1, &output_format)))
+ if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &format, 1, &output_format, NULL)))
converter->stream = wg_parser_get_stream(converter->parser, 0);
}
@@ -533,7 +533,7 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
struct wg_format input_format;
mf_media_type_to_wg_format(converter->input_type, &input_format);
- if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &input_format, 1, &format)))
+ if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &input_format, 1, &format, NULL)))
converter->stream = wg_parser_get_stream(converter->parser, 0);
}
diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c
index 6f1363ff1f3..04d46a73c3d 100644
--- a/dlls/winegstreamer/decode_transform.c
+++ b/dlls/winegstreamer/decode_transform.c
@@ -641,6 +641,9 @@ static DWORD CALLBACK helper_thread_func(PVOID ctx)
case HELP_REQ_START_PARSER:
{
struct wg_format input_format, output_format;
+ struct wg_rect wg_aperture = {0};
+ MFVideoArea *aperture = NULL;
+ UINT32 aperture_size;
decoder->help_request.type = HELP_REQ_NONE;
LeaveCriticalSection(&decoder->help_cs);
@@ -648,7 +651,25 @@ static DWORD CALLBACK helper_thread_func(PVOID ctx)
mf_media_type_to_wg_format(decoder->input_type, &input_format);
mf_media_type_to_wg_format(decoder->output_type, &output_format);
- wg_parser_connect_unseekable(decoder->wg_parser, &input_format, 1, &output_format);
+ if (SUCCEEDED(IMFMediaType_GetAllocatedBlob(decoder->output_type,
+ &MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8 **) &aperture, &aperture_size)))
+ {
+ TRACE("Decoded media's aperture: x: %u %u/65536, y: %u %u/65536, area: %u x %u\n",
+ aperture->OffsetX.value, aperture->OffsetX.fract,
+ aperture->OffsetY.value, aperture->OffsetY.fract, aperture->Area.cx, aperture->Area.cy);
+
+ /* TODO: verify aperture params? */
+
+ wg_aperture.left = aperture->OffsetX.value;
+ wg_aperture.top = aperture->OffsetY.value;
+ wg_aperture.right = aperture->Area.cx;
+ wg_aperture.bottom = aperture->Area.cy;
+
+ CoTaskMemFree(aperture);
+ }
+
+ wg_parser_connect_unseekable(decoder->wg_parser,
+ &input_format, 1, &output_format, aperture ? &wg_aperture : NULL);
EnterCriticalSection(&decoder->event_cs);
while (!decoder->helper_thread_shutdown && decoder->event.type != PIPELINE_EVENT_NONE)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 49879fe416d..f1c7bc60428 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -69,7 +69,7 @@ void wg_parser_destroy(struct wg_parser *parser);
HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size);
HRESULT wg_parser_connect_unseekable(struct wg_parser *parser, const struct wg_format *in_format,
- uint32_t stream_count, const struct wg_format *out_formats);
+ uint32_t stream_count, const struct wg_format *out_formats, const struct wg_rect *apertures);
void wg_parser_disconnect(struct wg_parser *parser);
void wg_parser_begin_flush(struct wg_parser *parser);
@@ -82,7 +82,7 @@ uint32_t wg_parser_get_stream_count(struct wg_parser *parser);
struct wg_parser_stream *wg_parser_get_stream(struct wg_parser *parser, uint32_t index);
void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, struct wg_format *format);
-void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format);
+void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format, const struct wg_rect *aperture);
void wg_parser_stream_disable(struct wg_parser_stream *stream);
bool wg_parser_stream_get_event(struct wg_parser_stream *stream, struct wg_parser_event *event);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index a9a9c72136d..74f0dd04e83 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -92,7 +92,7 @@ HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size)
}
HRESULT wg_parser_connect_unseekable(struct wg_parser *parser, const struct wg_format *in_format,
- uint32_t stream_count, const struct wg_format *out_formats)
+ uint32_t stream_count, const struct wg_format *out_formats, const struct wg_rect *apertures)
{
struct wg_parser_connect_unseekable_params params =
{
@@ -100,6 +100,7 @@ HRESULT wg_parser_connect_unseekable(struct wg_parser *parser, const struct wg_f
.in_format = in_format,
.stream_count = stream_count,
.out_formats = out_formats,
+ .apertures = apertures,
};
return __wine_unix_call(unix_handle, unix_wg_parser_connect_unseekable, &params);
@@ -181,12 +182,13 @@ void wg_parser_stream_get_preferred_format(struct wg_parser_stream *stream, stru
__wine_unix_call(unix_handle, unix_wg_parser_stream_get_preferred_format, &params);
}
-void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format)
+void wg_parser_stream_enable(struct wg_parser_stream *stream, const struct wg_format *format, const struct wg_rect *aperture)
{
struct wg_parser_stream_enable_params params =
{
.stream = stream,
.format = format,
+ .aperture = aperture,
};
__wine_unix_call(unix_handle, unix_wg_parser_stream_enable, &params);
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index 11040ac159a..e5f25eed63a 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -358,7 +358,7 @@ static void start_pipeline(struct media_source *source, struct source_async_comm
IMFMediaTypeHandler_GetCurrentMediaType(mth, &current_mt);
mf_media_type_to_wg_format(current_mt, &format);
- wg_parser_stream_enable(stream->wg_stream, &format);
+ wg_parser_stream_enable(stream->wg_stream, &format, NULL);
IMFMediaType_Release(current_mt);
IMFMediaTypeHandler_Release(mth);
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
index c44bd141c56..c03f4deca30 100644
--- a/dlls/winegstreamer/quartz_parser.c
+++ b/dlls/winegstreamer/quartz_parser.c
@@ -1528,7 +1528,7 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface,
ret = amt_to_wg_format(&pin->pin.pin.mt, &format);
assert(ret);
- wg_parser_stream_enable(pin->wg_stream, &format);
+ wg_parser_stream_enable(pin->wg_stream, &format, NULL);
/* We do need to drop any buffers that might have been sent with the old
* caps, but this will be handled in parser_init_stream(). */
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index fdcecfc96d5..5946621fb9d 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -117,6 +117,14 @@ struct wg_format
} u;
};
+struct wg_rect
+{
+ uint32_t left;
+ uint32_t right;
+ uint32_t top;
+ uint32_t bottom;
+};
+
enum wg_parser_event_type
{
WG_PARSER_EVENT_NONE = 0,
@@ -183,6 +191,7 @@ struct wg_parser_connect_unseekable_params
const struct wg_format *in_format;
UINT32 stream_count;
const struct wg_format *out_formats;
+ const struct wg_rect *apertures;
};
struct wg_parser_get_next_read_offset_params
@@ -223,6 +232,7 @@ struct wg_parser_stream_enable_params
{
struct wg_parser_stream *stream;
const struct wg_format *format;
+ const struct wg_rect *aperture;
};
struct wg_parser_stream_get_event_params
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index dc655b275bd..f699ab21837 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -98,9 +98,10 @@ struct wg_parser_stream
struct wg_parser *parser;
GstPad *their_src, *post_sink, *post_src, *my_sink;
- GstElement *flip;
+ GstElement *flip, *box;
GstSegment segment;
struct wg_format preferred_format, current_format;
+ struct wg_rect aperture;
pthread_cond_t event_cond, event_empty_cond;
struct wg_parser_event event;
@@ -730,6 +731,7 @@ static NTSTATUS wg_parser_stream_enable(void *args)
const struct wg_parser_stream_enable_params *params = args;
struct wg_parser_stream *stream = params->stream;
const struct wg_format *format = params->format;
+ const struct wg_rect *aperture = params->aperture;
if (!stream->parser->seekable)
return S_OK;
@@ -765,6 +767,18 @@ static NTSTATUS wg_parser_stream_enable(void *args)
}
gst_util_set_object_arg(G_OBJECT(stream->flip), "method", flip ? "vertical-flip" : "none");
+
+ if (aperture)
+ {
+ if (aperture->left)
+ g_object_set(G_OBJECT(stream->box), "left", -aperture->left, NULL);
+ if (aperture->top)
+ g_object_set(G_OBJECT(stream->box), "top", -aperture->top, NULL);
+ if (aperture->right)
+ g_object_set(G_OBJECT(stream->box), "right", aperture->right - format->u.video.width, NULL);
+ if (aperture->bottom)
+ g_object_set(G_OBJECT(stream->box), "bottom", aperture->bottom - format->u.video.height, NULL);
+ }
}
gst_pad_push_event(stream->my_sink, gst_event_new_reconfigure());
@@ -1357,7 +1371,7 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
if (!strcmp(name, "video/x-raw"))
{
- GstElement *capssetter, *deinterlace, *vconv, *flip, *vconv2;
+ GstElement *capssetter, *deinterlace, *vconv, *flip, *box, *vconv2;
/* Hack?: Flatten down the colorimetry to default values, without
* actually modifying the video at all.
@@ -1423,11 +1437,26 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
if (!(flip = create_element("videoflip", "good")))
goto out;
+ if (!(box = create_element("videbox", "base")))
+ goto out;
+
/* videoflip does not support 15 and 16-bit RGB so add a second videoconvert
* to do the final conversion. */
if (!(vconv2 = create_element("videoconvert", "base")))
goto out;
+ if (!parser->seekable)
+ {
+ if (stream->aperture.left)
+ g_object_set(G_OBJECT(box), "left", -stream->aperture.left, NULL);
+ if (stream->aperture.bottom)
+ g_object_set(G_OBJECT(box), "top", -stream->aperture.top, NULL);
+ if (stream->aperture.right)
+ g_object_set(G_OBJECT(box), "right", stream->aperture.right - stream->current_format.u.video.width, NULL);
+ if (stream->aperture.bottom)
+ g_object_set(G_OBJECT(box), "bottom", stream->aperture.bottom - stream->current_format.u.video.height, NULL);
+ }
+
/* The bin takes ownership of these elements. */
gst_bin_add(GST_BIN(parser->container), capssetter);
gst_element_sync_state_with_parent(capssetter);
@@ -1437,17 +1466,21 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
gst_element_sync_state_with_parent(vconv);
gst_bin_add(GST_BIN(parser->container), flip);
gst_element_sync_state_with_parent(flip);
+ gst_bin_add(GST_BIN(parser->container), box);
+ gst_element_sync_state_with_parent(box);
gst_bin_add(GST_BIN(parser->container), vconv2);
gst_element_sync_state_with_parent(vconv2);
gst_element_link(capssetter, deinterlace);
gst_element_link(deinterlace, vconv);
gst_element_link(vconv, flip);
- gst_element_link(flip, vconv2);
+ gst_element_link(flip, box);
+ gst_element_link(box, vconv2);
stream->post_sink = gst_element_get_static_pad(capssetter, "sink");
stream->post_src = gst_element_get_static_pad(vconv2, "src");
stream->flip = flip;
+ stream->box = box;
}
else if (!strcmp(name, "audio/x-raw"))
{
@@ -2138,6 +2171,7 @@ static NTSTATUS wg_parser_connect_unseekable(void *args)
const struct wg_parser_connect_unseekable_params *params = args;
const struct wg_format *out_formats = params->out_formats;
const struct wg_format *in_format = params->in_format;
+ const struct wg_rect *apertures = params->apertures;
uint32_t stream_count = params->stream_count;
struct wg_parser *parser = params->parser;
unsigned int i;
@@ -2160,6 +2194,8 @@ static NTSTATUS wg_parser_connect_unseekable(void *args)
{
parser->streams[i] = calloc(1, sizeof(*parser->streams[i]));
parser->streams[i]->current_format = out_formats[i];
+ if (apertures)
+ parser->streams[i]->aperture = apertures[i];
parser->streams[i]->enabled = true;
}
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index ee37abee811..569560d054e 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -1509,7 +1509,7 @@ static HRESULT init_stream(struct wm_reader *reader, QWORD file_size)
* video type will be BGR. */
stream->format.u.video.format = WG_VIDEO_FORMAT_BGR;
}
- wg_parser_stream_enable(stream->wg_stream, &stream->format);
+ wg_parser_stream_enable(stream->wg_stream, &stream->format, NULL);
}
wg_parser_end_flush(reader->wg_parser);
@@ -1776,7 +1776,7 @@ HRESULT wm_reader_set_output_props(struct wm_reader *reader, DWORD output,
}
stream->format = format;
- wg_parser_stream_enable(stream->wg_stream, &format);
+ wg_parser_stream_enable(stream->wg_stream, &format, NULL);
/* Re-decode any buffers that might have been generated with the old format.
*
@@ -1989,7 +1989,7 @@ HRESULT wm_reader_set_streams_selected(struct wm_reader *reader, WORD count,
FIXME("Ignoring selection %#x for stream %u; treating as enabled.\n",
selections[i], stream_numbers[i]);
TRACE("Enabling stream %u.\n", stream_numbers[i]);
- wg_parser_stream_enable(stream->wg_stream, &stream->format);
+ wg_parser_stream_enable(stream->wg_stream, &stream->format, NULL);
}
}
--
2.34.1

View File

@@ -1,89 +0,0 @@
From 1c85ff3c7891c80fac65add4706243bb8fbc9110 Mon Sep 17 00:00:00 2001
From: Derek Lesho <dlesho@codeweavers.com>
Date: Thu, 18 Mar 2021 16:20:50 -0400
Subject: [PATCH 53/88] winegstreamer: Only require videobox element for parser
when needed.
---
dlls/winegstreamer/wg_parser.c | 38 ++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c
index f699ab21837..833671df20c 100644
--- a/dlls/winegstreamer/wg_parser.c
+++ b/dlls/winegstreamer/wg_parser.c
@@ -770,6 +770,15 @@ static NTSTATUS wg_parser_stream_enable(void *args)
if (aperture)
{
+ if (!stream->box && (stream->aperture.left || stream->aperture.top ||
+ (stream->aperture.right && stream->aperture.right != stream->current_format.u.video.width) ||
+ (stream->aperture.bottom && stream->aperture.bottom != stream->current_format.u.video.height)))
+ {
+ fprintf(stderr, "winegstreamer: failed to create videobox, are %u-bit GStreamer \"good\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ return E_FAIL;
+ }
+
if (aperture->left)
g_object_set(G_OBJECT(stream->box), "left", -aperture->left, NULL);
if (aperture->top)
@@ -1437,8 +1446,7 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
if (!(flip = create_element("videoflip", "good")))
goto out;
- if (!(box = create_element("videbox", "base")))
- goto out;
+ box = gst_element_factory_make("videobox", NULL);
/* videoflip does not support 15 and 16-bit RGB so add a second videoconvert
* to do the final conversion. */
@@ -1447,6 +1455,14 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
if (!parser->seekable)
{
+ if (!box && (stream->aperture.left || stream->aperture.top ||
+ (stream->aperture.right && stream->aperture.right != stream->current_format.u.video.width) ||
+ (stream->aperture.bottom && stream->aperture.bottom != stream->current_format.u.video.height)))
+ {
+ fprintf(stderr, "winegstreamer: failed to create videobox, are %u-bit GStreamer \"good\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ goto out;
+ }
if (stream->aperture.left)
g_object_set(G_OBJECT(box), "left", -stream->aperture.left, NULL);
if (stream->aperture.bottom)
@@ -1466,16 +1482,26 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user)
gst_element_sync_state_with_parent(vconv);
gst_bin_add(GST_BIN(parser->container), flip);
gst_element_sync_state_with_parent(flip);
- gst_bin_add(GST_BIN(parser->container), box);
- gst_element_sync_state_with_parent(box);
+ if (box)
+ {
+ gst_bin_add(GST_BIN(parser->container), box);
+ gst_element_sync_state_with_parent(box);
+ }
gst_bin_add(GST_BIN(parser->container), vconv2);
gst_element_sync_state_with_parent(vconv2);
gst_element_link(capssetter, deinterlace);
gst_element_link(deinterlace, vconv);
gst_element_link(vconv, flip);
- gst_element_link(flip, box);
- gst_element_link(box, vconv2);
+ if (box)
+ {
+ gst_element_link(flip, box);
+ gst_element_link(box, vconv2);
+ }
+ else
+ {
+ gst_element_link(flip, vconv2);
+ }
stream->post_sink = gst_element_get_static_pad(capssetter, "sink");
stream->post_src = gst_element_get_static_pad(vconv2, "src");
--
2.34.1

View File

@@ -1,37 +0,0 @@
From 30e5e0e405af8f99885727687dbcdfbda3e57f08 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 18 Jan 2022 13:33:36 +0100
Subject: [PATCH 67/88] winegstreamer: Return S_OK from H264 decoder
GetAttributes.
For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2,
Yakuza 4 Remastered, Hard Reset Redux.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183
CW-Bug-Id: #16839
CW-Bug-Id: #18678
CW-Bug-Id: #19362
---
dlls/winegstreamer/h264_decoder.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index 5db72c55151..f46d6d77f8e 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -120,7 +120,8 @@ static HRESULT WINAPI h264_decoder_GetOutputStreamInfo(IMFTransform *iface, DWOR
static HRESULT WINAPI h264_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
{
FIXME("iface %p, attributes %p stub!\n", iface, attributes);
- return E_NOTIMPL;
+
+ return MFCreateAttributes(attributes, 0);
}
static HRESULT WINAPI h264_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
--
2.34.1

View File

@@ -1,112 +0,0 @@
From db138323808ecd9938a0f40b810ad68fc39b389c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 10 Feb 2022 09:58:20 +0100
Subject: [PATCH 80/88] winegstreamer: Fixup H264 decoder NV12 plane alignment.
To match what native does. Many games that use the H264 decoder directly
rely on this as they hardcode various aspects of the alignment in their
logic (and each game a different one).
Note: There may be a way to have it done by GStreamer, as libav natively
decode H264 into aligned planes, but somehow and somewhere in the chain
the planes are re-aligned.
Hard Reset Redux crashes if MF_MT_MINIMUM_DISPLAY_APERTURE attribute is
set (and it doesn't need it as its videos are 720p).
For: Call of Duty III, Shadow Warrior 2.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183
CW-Bug-Id: #16839
CW-Bug-Id: #18678
CW-Bug-Id: #19362
---
dlls/winegstreamer/h264_decoder.c | 40 +++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index 219790128da..66ecfad84de 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -86,6 +86,7 @@ static HRESULT try_create_wg_transform(struct h264_decoder *decoder)
static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *default_type)
{
UINT32 value, width, height;
+ MFVideoArea aperture = {0};
UINT64 value64;
GUID subtype;
HRESULT hr;
@@ -177,6 +178,17 @@ static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *de
return hr;
}
+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL)))
+ {
+ if (default_type && SUCCEEDED(hr = IMFMediaType_GetBlob(default_type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
+ (BYTE *)&aperture, sizeof(aperture), NULL)))
+ {
+ if (FAILED(hr = IMFMediaType_SetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
+ (BYTE *)&aperture, sizeof(aperture))))
+ return hr;
+ }
+ }
+
return S_OK;
}
@@ -551,7 +563,9 @@ static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flag
struct wg_sample wg_sample = {0};
IMFMediaBuffer *media_buffer;
MFT_OUTPUT_STREAM_INFO info;
+ MFVideoArea aperture = {0};
IMFMediaType *media_type;
+ UINT32 align, offset;
DWORD buffer_size;
HRESULT hr;
@@ -593,6 +607,17 @@ static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flag
IMFSample_SetSampleTime(samples[0].pSample, wg_sample.pts);
if (wg_sample.flags & WG_SAMPLE_FLAG_HAS_DURATION)
IMFSample_SetSampleDuration(samples[0].pSample, wg_sample.duration);
+
+ if (decoder->wg_format.u.video.format == WG_VIDEO_FORMAT_NV12 &&
+ (align = decoder->wg_format.u.video.height & 15))
+ {
+ offset = decoder->wg_format.u.video.width * decoder->wg_format.u.video.height;
+ align = (16 - align) * decoder->wg_format.u.video.width;
+ memmove(wg_sample.data + offset + align, wg_sample.data + offset,
+ wg_sample.size - offset);
+ wg_sample.size += align;
+ }
+
hr = IMFMediaBuffer_SetCurrentLength(media_buffer, wg_sample.size);
}
else if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
@@ -603,6 +628,21 @@ static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flag
IMFMediaType_DeleteItem(decoder->output_type, &MF_MT_DEFAULT_STRIDE);
fill_output_media_type(media_type, decoder->output_type);
+ if (decoder->wg_format.u.video.format == WG_VIDEO_FORMAT_NV12 &&
+ (align = decoder->wg_format.u.video.height & 15))
+ {
+ aperture.Area.cx = decoder->wg_format.u.video.width;
+ aperture.Area.cy = decoder->wg_format.u.video.height;
+ IMFMediaType_SetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
+ (BYTE *)&aperture, sizeof(aperture));
+
+ aperture.Area.cy += 16 - align;
+ IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE,
+ (UINT64)aperture.Area.cx << 32 | aperture.Area.cy);
+ IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE,
+ aperture.Area.cx * aperture.Area.cy * 3 / 2);
+ }
+
IMFMediaType_Release(decoder->output_type);
decoder->output_type = media_type;
--
2.34.1

View File

@@ -1,49 +0,0 @@
From 0f2c90c60d6ec76f5339dd891e5a3160ce9dea2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 8 Feb 2022 11:21:39 +0100
Subject: [PATCH 83/88] winegstreamer: Reset internal format on BEGIN_STREAMING
message.
In order to regenerate a MF_E_TRANSFORM_STREAM_CHANGE status on next
successful ProcessOutput. CoD: Black Ops 3 depends on this, or crashes
if MF_E_TRANSFORM_STREAM_CHANGE isn't returned when the campaign intro
video begins to play.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183
CW-Bug-Id: #16839
CW-Bug-Id: #18678
CW-Bug-Id: #19362
---
dlls/winegstreamer/h264_decoder.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index ba6e681890b..ede0bd36bce 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -522,7 +522,19 @@ static HRESULT WINAPI h264_decoder_ProcessEvent(IMFTransform *iface, DWORD id, I
static HRESULT WINAPI h264_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
{
+ struct h264_decoder *decoder = impl_from_IMFTransform(iface);
+
FIXME("iface %p, message %#x, param %p stub!\n", iface, message, (void *)param);
+
+ switch (message)
+ {
+ case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING:
+ memset(&decoder->wg_format, 0, sizeof(decoder->wg_format));
+ break;
+ default:
+ break;
+ }
+
return S_OK;
}
--
2.34.1

View File

@@ -1,4 +1,4 @@
From 217794090443a96e712ffe3970e4a70ded2277dc Mon Sep 17 00:00:00 2001
From 27019592a4f4aa7134f605093b5d83fe3764dcf5 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 5 Aug 2017 03:39:37 +0200
Subject: [PATCH] ntdll: Use fast CS functions for threadpool locking.
@@ -8,19 +8,19 @@ Subject: [PATCH] ntdll: Use fast CS functions for threadpool locking.
1 file changed, 45 insertions(+), 45 deletions(-)
diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index ca323919d05..581d503b6a4 100644
index 421d1ade133..71771dd2987 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -1053,7 +1053,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
@@ -1063,7 +1063,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
TRACE( "starting timer queue thread\n" );
set_thread_name(L"wine_threadpool_timerqueue");
- RtlEnterCriticalSection( &timerqueue.cs );
+ enter_critical_section( &timerqueue.cs );
for (;;)
{
NtQuerySystemTime( &now );
@@ -1126,7 +1126,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
@@ -1136,7 +1136,7 @@ static void CALLBACK timerqueue_thread_proc( void *param )
}
timerqueue.thread_running = FALSE;
@@ -29,7 +29,7 @@ index ca323919d05..581d503b6a4 100644
TRACE( "terminating timer queue thread\n" );
RtlExitUserThread( 0 );
@@ -1171,7 +1171,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
@@ -1181,7 +1181,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
timer->u.timer.period = 0;
timer->u.timer.window_length = 0;
@@ -38,7 +38,7 @@ index ca323919d05..581d503b6a4 100644
/* Make sure that the timerqueue thread is running. */
if (!timerqueue.thread_running)
@@ -1192,7 +1192,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
@@ -1202,7 +1202,7 @@ static NTSTATUS tp_timerqueue_lock( struct threadpool_object *timer )
timerqueue.objcount++;
}
@@ -47,7 +47,7 @@ index ca323919d05..581d503b6a4 100644
return status;
}
@@ -1205,7 +1205,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
@@ -1215,7 +1215,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
{
assert( timer->type == TP_OBJECT_TYPE_TIMER );
@@ -56,7 +56,7 @@ index ca323919d05..581d503b6a4 100644
if (timer->u.timer.timer_initialized)
{
/* If timer was pending, remove it. */
@@ -1224,7 +1224,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
@@ -1234,7 +1234,7 @@ static void tp_timerqueue_unlock( struct threadpool_object *timer )
timer->u.timer.timer_initialized = FALSE;
}
@@ -65,16 +65,16 @@ index ca323919d05..581d503b6a4 100644
}
/***********************************************************************
@@ -1242,7 +1242,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
@@ -1253,7 +1253,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
TRACE( "starting wait queue thread\n" );
set_thread_name(L"wine_threadpool_waitqueue");
- RtlEnterCriticalSection( &waitqueue.cs );
+ enter_critical_section( &waitqueue.cs );
for (;;)
{
@@ -1291,10 +1291,10 @@ static void CALLBACK waitqueue_thread_proc( void *param )
@@ -1302,10 +1302,10 @@ static void CALLBACK waitqueue_thread_proc( void *param )
/* All wait objects have been destroyed, if no new wait objects are created
* within some amount of time, then we can shutdown this thread. */
assert( num_handles == 0 );
@@ -87,7 +87,7 @@ index ca323919d05..581d503b6a4 100644
if (status == STATUS_TIMEOUT && !bucket->objcount)
break;
@@ -1304,7 +1304,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
@@ -1315,7 +1315,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
handles[num_handles] = bucket->update_event;
RtlLeaveCriticalSection( &waitqueue.cs );
status = NtWaitForMultipleObjects( num_handles + 1, handles, TRUE, bucket->alertable, &timeout );
@@ -96,7 +96,7 @@ index ca323919d05..581d503b6a4 100644
if (status >= STATUS_WAIT_0 && status < STATUS_WAIT_0 + num_handles)
{
@@ -1388,7 +1388,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
@@ -1399,7 +1399,7 @@ static void CALLBACK waitqueue_thread_proc( void *param )
if (!--waitqueue.num_buckets)
assert( list_empty( &waitqueue.buckets ) );
@@ -105,7 +105,7 @@ index ca323919d05..581d503b6a4 100644
TRACE( "terminating wait queue thread\n" );
@@ -1418,7 +1418,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
@@ -1429,7 +1429,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
wait->u.wait.timeout = 0;
wait->u.wait.handle = INVALID_HANDLE_VALUE;
@@ -114,7 +114,7 @@ index ca323919d05..581d503b6a4 100644
/* Try to assign to existing bucket if possible. */
LIST_FOR_EACH_ENTRY( bucket, &waitqueue.buckets, struct waitqueue_bucket, bucket_entry )
@@ -1475,7 +1475,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
@@ -1486,7 +1486,7 @@ static NTSTATUS tp_waitqueue_lock( struct threadpool_object *wait )
}
out:
@@ -123,7 +123,7 @@ index ca323919d05..581d503b6a4 100644
return status;
}
@@ -1486,7 +1486,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
@@ -1497,7 +1497,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
{
assert( wait->type == TP_OBJECT_TYPE_WAIT );
@@ -132,7 +132,7 @@ index ca323919d05..581d503b6a4 100644
if (wait->u.wait.bucket)
{
struct waitqueue_bucket *bucket = wait->u.wait.bucket;
@@ -1498,7 +1498,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
@@ -1509,7 +1509,7 @@ static void tp_waitqueue_unlock( struct threadpool_object *wait )
NtSetEvent( bucket->update_event, NULL );
}
@@ -141,7 +141,7 @@ index ca323919d05..581d503b6a4 100644
}
static void CALLBACK ioqueue_thread_proc( void *param )
@@ -1775,7 +1775,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
@@ -1787,7 +1787,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
pool = default_threadpool;
}
@@ -150,7 +150,7 @@ index ca323919d05..581d503b6a4 100644
/* Make sure that the threadpool has at least one thread. */
if (!pool->num_workers)
@@ -1789,7 +1789,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
@@ -1801,7 +1801,7 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
pool->objcount++;
}
@@ -159,7 +159,7 @@ index ca323919d05..581d503b6a4 100644
if (status != STATUS_SUCCESS)
return status;
@@ -1805,9 +1805,9 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
@@ -1817,9 +1817,9 @@ static NTSTATUS tp_threadpool_lock( struct threadpool **out, TP_CALLBACK_ENVIRON
*/
static void tp_threadpool_unlock( struct threadpool *pool )
{
@@ -171,7 +171,7 @@ index ca323919d05..581d503b6a4 100644
tp_threadpool_release( pool );
}
@@ -1945,10 +1945,10 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
@@ -1957,10 +1957,10 @@ static void tp_object_initialize( struct threadpool_object *object, struct threa
struct threadpool_group *group = object->group;
InterlockedIncrement( &group->refcount );
@@ -184,7 +184,7 @@ index ca323919d05..581d503b6a4 100644
}
if (is_simple_callback)
@@ -1975,7 +1975,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
@@ -1987,7 +1987,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
assert( !object->shutdown );
assert( !pool->shutdown );
@@ -193,7 +193,7 @@ index ca323919d05..581d503b6a4 100644
/* Start new worker threads if required. */
if (pool->num_busy_workers >= pool->num_workers &&
@@ -1998,7 +1998,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
@@ -2010,7 +2010,7 @@ static void tp_object_submit( struct threadpool_object *object, BOOL signaled )
RtlWakeConditionVariable( &pool->update_event );
}
@@ -202,7 +202,7 @@ index ca323919d05..581d503b6a4 100644
}
/***********************************************************************
@@ -2011,7 +2011,7 @@ static void tp_object_cancel( struct threadpool_object *object )
@@ -2023,7 +2023,7 @@ static void tp_object_cancel( struct threadpool_object *object )
struct threadpool *pool = object->pool;
LONG pending_callbacks = 0;
@@ -211,7 +211,7 @@ index ca323919d05..581d503b6a4 100644
if (object->num_pending_callbacks)
{
pending_callbacks = object->num_pending_callbacks;
@@ -2026,7 +2026,7 @@ static void tp_object_cancel( struct threadpool_object *object )
@@ -2038,7 +2038,7 @@ static void tp_object_cancel( struct threadpool_object *object )
object->u.io.skipped_count += object->u.io.pending_count;
object->u.io.pending_count = 0;
}
@@ -220,7 +220,7 @@ index ca323919d05..581d503b6a4 100644
while (pending_callbacks--)
tp_object_release( object );
@@ -2055,7 +2055,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
@@ -2067,7 +2067,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
{
struct threadpool *pool = object->pool;
@@ -229,7 +229,7 @@ index ca323919d05..581d503b6a4 100644
while (!object_is_finished( object, group_wait ))
{
if (group_wait)
@@ -2063,7 +2063,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
@@ -2075,7 +2075,7 @@ static void tp_object_wait( struct threadpool_object *object, BOOL group_wait )
else
RtlSleepConditionVariableCS( &object->finished_event, &pool->cs, NULL );
}
@@ -238,7 +238,7 @@ index ca323919d05..581d503b6a4 100644
}
static void tp_ioqueue_unlock( struct threadpool_object *io )
@@ -2117,13 +2117,13 @@ static BOOL tp_object_release( struct threadpool_object *object )
@@ -2129,13 +2129,13 @@ static BOOL tp_object_release( struct threadpool_object *object )
{
struct threadpool_group *group = object->group;
@@ -254,16 +254,16 @@ index ca323919d05..581d503b6a4 100644
tp_group_release( group );
}
@@ -2324,7 +2324,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -2337,7 +2337,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
TRACE( "starting worker thread for pool %p\n", pool );
set_thread_name(L"wine_threadpool_worker");
- RtlEnterCriticalSection( &pool->cs );
+ enter_critical_section( &pool->cs );
for (;;)
{
while ((ptr = threadpool_get_next_item( pool )))
@@ -2364,7 +2364,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
@@ -2377,7 +2377,7 @@ static void CALLBACK threadpool_worker_proc( void *param )
}
}
pool->num_workers--;
@@ -272,7 +272,7 @@ index ca323919d05..581d503b6a4 100644
TRACE( "terminating worker thread for pool %p\n", pool );
tp_threadpool_release( pool );
@@ -2612,7 +2612,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
@@ -2625,7 +2625,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
return STATUS_SUCCESS;
pool = object->pool;
@@ -281,7 +281,7 @@ index ca323919d05..581d503b6a4 100644
/* Start new worker threads if required. */
if (pool->num_busy_workers >= pool->num_workers)
@@ -2627,7 +2627,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
@@ -2640,7 +2640,7 @@ NTSTATUS WINAPI TpCallbackMayRunLong( TP_CALLBACK_INSTANCE *instance )
}
}
@@ -290,7 +290,7 @@ index ca323919d05..581d503b6a4 100644
this->may_run_long = TRUE;
return status;
}
@@ -2708,13 +2708,13 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance )
@@ -2721,13 +2721,13 @@ VOID WINAPI TpDisassociateCallback( TP_CALLBACK_INSTANCE *instance )
return;
pool = object->pool;
@@ -306,7 +306,7 @@ index ca323919d05..581d503b6a4 100644
this->associated = FALSE;
}
@@ -2766,7 +2766,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
@@ -2779,7 +2779,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
TRACE( "%p %u %p\n", group, cancel_pending, userdata );
@@ -315,7 +315,7 @@ index ca323919d05..581d503b6a4 100644
/* Unset group, increase references, and mark objects for shutdown */
LIST_FOR_EACH_ENTRY_SAFE( object, next, &this->members, struct threadpool_object, group_entry )
@@ -2792,7 +2792,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
@@ -2805,7 +2805,7 @@ VOID WINAPI TpReleaseCleanupGroupMembers( TP_CLEANUP_GROUP *group, BOOL cancel_p
list_init( &members );
list_move_tail( &members, &this->members );
@@ -324,7 +324,7 @@ index ca323919d05..581d503b6a4 100644
/* Cancel pending callbacks if requested */
if (cancel_pending)
@@ -2915,10 +2915,10 @@ VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum )
@@ -2928,10 +2928,10 @@ VOID WINAPI TpSetPoolMaxThreads( TP_POOL *pool, DWORD maximum )
TRACE( "%p %u\n", pool, maximum );
@@ -337,7 +337,7 @@ index ca323919d05..581d503b6a4 100644
}
/***********************************************************************
@@ -2931,7 +2931,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
@@ -2944,7 +2944,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
TRACE( "%p %u\n", pool, minimum );
@@ -346,7 +346,7 @@ index ca323919d05..581d503b6a4 100644
while (this->num_workers < minimum)
{
@@ -2946,7 +2946,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
@@ -2959,7 +2959,7 @@ BOOL WINAPI TpSetPoolMinThreads( TP_POOL *pool, DWORD minimum )
this->max_workers = max( this->min_workers, this->max_workers );
}
@@ -355,7 +355,7 @@ index ca323919d05..581d503b6a4 100644
return !status;
}
@@ -2962,7 +2962,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
@@ -2975,7 +2975,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
TRACE( "%p %p %u %u\n", timer, timeout, period, window_length );
@@ -364,7 +364,7 @@ index ca323919d05..581d503b6a4 100644
assert( this->u.timer.timer_initialized );
this->u.timer.timer_set = timeout != NULL;
@@ -3022,7 +3022,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
@@ -3035,7 +3035,7 @@ VOID WINAPI TpSetTimer( TP_TIMER *timer, LARGE_INTEGER *timeout, LONG period, LO
this->u.timer.timer_pending = TRUE;
}
@@ -373,7 +373,7 @@ index ca323919d05..581d503b6a4 100644
if (submit_timer)
tp_object_submit( this, FALSE );
@@ -3038,7 +3038,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
@@ -3051,7 +3051,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
TRACE( "%p %p %p\n", wait, handle, timeout );
@@ -382,7 +382,7 @@ index ca323919d05..581d503b6a4 100644
assert( this->u.wait.bucket );
this->u.wait.handle = handle;
@@ -3077,7 +3077,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
@@ -3090,7 +3090,7 @@ VOID WINAPI TpSetWait( TP_WAIT *wait, HANDLE handle, LARGE_INTEGER *timeout )
NtSetEvent( bucket->update_event, NULL );
}
@@ -392,5 +392,5 @@ index ca323919d05..581d503b6a4 100644
/***********************************************************************
--
2.30.2
2.37.2

View File

@@ -1,122 +0,0 @@
From 80cb1bf9077b1e754fc2f3426229733c3417c397 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 19 Aug 2014 22:10:49 -0600
Subject: [PATCH] ntdll: Implement retrieving DOS attributes in
[fd_]get_file_info().
---
configure.ac | 12 ++++++++++++
dlls/ntdll/unix/file.c | 39 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index c68c5975e63..84efc670ca4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,6 +64,7 @@ AC_ARG_WITH(unwind, AS_HELP_STRING([--without-unwind],[do not use the libunwi
AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb library]))
AC_ARG_WITH(v4l2, AS_HELP_STRING([--without-v4l2],[do not use v4l2 (video capture)]))
AC_ARG_WITH(vulkan, AS_HELP_STRING([--without-vulkan],[do not use Vulkan]))
+AC_ARG_WITH(xattr, AS_HELP_STRING([--without-xattr],[do not use xattr (security attributes support)]))
AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
[if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]),
@@ -634,6 +635,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
#include <sys/queue.h>
#endif])
+if test "x$with_xattr" != "xno"
+then
+ AC_CHECK_HEADERS(attr/xattr.h, [HAVE_XATTR=1])
+fi
+if test "x$with_xattr" = "xyes"
+then
+ WINE_ERROR_WITH(xattr,[test "x$HAVE_XATTR" = "x"],[xattr ${notice_platform}development files \
+not found. Wine will be built without extended attribute support, which probably isn't what you \
+want. You will need to install ${notice_platform}development packages of libattr at the very least.])
+fi
+
dnl **** Check for working dll ****
AC_SUBST(DLLFLAGS,"")
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index a29b5cbb980..1ae4645c6fb 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -98,6 +98,9 @@
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
#include <time.h>
#include <unistd.h>
@@ -355,6 +358,20 @@ NTSTATUS errno_to_status( int err )
}
}
+#ifndef XATTR_USER_PREFIX
+#define XATTR_USER_PREFIX "user."
+#endif
+
+static int xattr_get( const char *path, const char *name, void *value, size_t size )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return getxattr( path, name, value, size );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
/* get space from the current directory data buffer, allocating a new one if necessary */
static void *get_dir_data_space( struct dir_data *data, unsigned int size )
{
@@ -1436,6 +1453,22 @@ static BOOL append_entry( struct dir_data *data, const char *long_name,
}
+/* Match the Samba conventions for storing DOS file attributes */
+#define SAMBA_XATTR_DOS_ATTRIB XATTR_USER_PREFIX "DOSATTRIB"
+/* We are only interested in some attributes, the others have corresponding Unix attributes */
+#define XATTR_ATTRIBS_MASK (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)
+
+/* decode the xattr-stored DOS attributes */
+static inline int get_file_xattr( char *hexattr, int attrlen )
+{
+ if (attrlen > 2 && hexattr[0] == '0' && hexattr[1] == 'x')
+ {
+ hexattr[attrlen] = 0;
+ return strtol( hexattr+2, NULL, 16 ) & XATTR_ATTRIBS_MASK;
+ }
+ return 0;
+}
+
/* fetch the attributes of a file */
static inline ULONG get_file_attributes( const struct stat *st )
{
@@ -1479,7 +1512,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
static int get_file_info( const char *path, struct stat *st, ULONG *attr )
{
char *parent_path;
- int ret;
+ char hexattr[11];
+ int len, ret;
*attr = 0;
ret = lstat( path, st );
@@ -1505,6 +1539,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
free( parent_path );
}
*attr |= get_file_attributes( st );
+ len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
+ if (len == -1) return ret;
+ *attr |= get_file_xattr( hexattr, len );
return ret;
}
--
2.34.1

Some files were not shown because too many files have changed in this diff Show More