You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
41a3c56c50 | ||
|
5be23b8ae8 | ||
|
769ddd9f00 | ||
|
aabde22767 | ||
|
ca3220cbd6 | ||
|
ff6cef5d72 | ||
|
d2b7b686f1 | ||
|
c5c29f9395 | ||
|
08ad410761 | ||
|
e6f9a449cd | ||
|
0ea57a0262 | ||
|
4f75966580 | ||
|
9f9285256f | ||
|
21009111bd | ||
|
fe476e7241 | ||
|
29e810ed54 | ||
|
1dc3666fd0 | ||
|
78837ecadc | ||
|
626e3d77cd | ||
|
5013933ea5 | ||
|
c10d599428 | ||
|
1d75f6950a | ||
|
ffaf883b19 | ||
|
19c062dbc7 | ||
|
1ed196f0ef | ||
|
533337e25e | ||
|
7e2f1d392c | ||
|
129ce257fd | ||
|
a27ba94091 | ||
|
d490a981e1 | ||
|
092bc29352 | ||
|
2ee26de43f |
57
.github/workflows/macOS.yml
vendored
57
.github/workflows/macOS.yml
vendored
@@ -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)
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -1,2 +0,0 @@
|
||||
Fixes: [44052] - Support for font fallback.
|
||||
Disabled: True
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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, ¶ms);
|
||||
@@ -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, ¶ms);
|
||||
}
|
||||
|
||||
-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, ¶ms);
|
||||
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, ¤t_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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
|
@@ -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
Reference in New Issue
Block a user