diff --git a/.gitignore b/.gitignore index 9cb84f4..fd8c1c6 100644 --- a/.gitignore +++ b/.gitignore @@ -513,3 +513,237 @@ firefox-3.6.4.source.tar.bz2 /firefox-langpacks-100.0.2-20220520.tar.xz /firefox-101.0.source.tar.xz /firefox-langpacks-101.0-20220530.tar.xz +/firefox-101.0.1.source.tar.xz +/firefox-langpacks-101.0.1-20220609.tar.xz +/firefox-102.0.source.tar.xz +/firefox-langpacks-102.0-20220628.tar.xz +/firefox-103.0.source.tar.xz +/firefox-langpacks-103.0-20220721.tar.xz +/firefox-103.0.1.source.tar.xz +/firefox-langpacks-103.0.1-20220802.tar.xz +/firefox-103.0.2.source.tar.xz +/firefox-langpacks-103.0.2-20220812.tar.xz +/firefox-104.0.source.tar.xz +/firefox-langpacks-104.0-20220816.tar.xz +/firefox-langpacks-104.0-20220822.tar.xz +/firefox-langpacks-104.0.1-20220830.tar.xz +/firefox-104.0.1.source.tar.xz +/firefox-104.0.2.source.tar.xz +/firefox-langpacks-104.0.2-20220906.tar.xz +/firefox-langpacks-105.0-20220920.tar.xz +/firefox-105.0.source.tar.xz +/firefox-105.0.1.source.tar.xz +/firefox-langpacks-105.0.1-20220922.tar.xz +/firefox-105.0.2.source.tar.xz +/firefox-langpacks-105.0.2-20221005.tar.xz +/firefox-langpacks-106.0-20221014.tar.xz +/firefox-106.0.source.tar.xz +/firefox-106.0.1.source.tar.xz +/firefox-langpacks-106.0.1-20221023.tar.xz +/firefox-106.0.3.source.tar.xz +/firefox-langpacks-106.0.3-20221031.tar.xz +/firefox-langpacks-107.0-20221114.tar.xz +/firefox-107.0.source.tar.xz +/firefox-107.0.1.source.tar.xz +/firefox-langpacks-107.0.1-20221206.tar.xz +/firefox-108.0.source.tar.xz +/firefox-langpacks-108.0-20221206.tar.xz +/firefox-langpacks-108.0-20221214.tar.xz +/firefox-108.0.1.source.tar.xz +/firefox-langpacks-108.0.1-20221218.tar.xz +/firefox-108.0.2.source.tar.xz +/firefox-langpacks-108.0.2-20230112.tar.xz +/firefox-109.0.source.tar.xz +/firefox-langpacks-109.0-20230111.tar.xz +/firefox-109.0.1.source.tar.xz +/firefox-langpacks-109.0.1-20230201.tar.xz +/firefox-110.0.source.tar.xz +/firefox-langpacks-110.0-20230210.tar.xz +/firefox-langpacks-110.0-20230214.tar.xz +/firefox-111.0.source.tar.xz +/firefox-langpacks-111.0-20230320.tar.xz +/firefox-langpacks-111.0.1-20230322.tar.xz +/firefox-111.0.1.source.tar.xz +/firefox-112.0.source.tar.xz +/firefox-langpacks-112.0-20230405.tar.xz +/firefox-langpacks-112.0-20230406.tar.xz +/firefox-langpacks-112.0.1-20230417.tar.xz +/firefox-112.0.1.source.tar.xz +/firefox-langpacks-112.0.2-20230427.tar.xz +/firefox-112.0.2.source.tar.xz +/firefox-langpacks-113.0-20230509.tar.xz +/firefox-113.0.source.tar.xz +/firefox-langpacks-113.0.1-20230515.tar.xz +/firefox-113.0.1.source.tar.xz +/firefox-114.0.source.tar.xz +/firefox-langpacks-114.0-20230605.tar.xz +/firefox-langpacks-114.0.2-20230620.tar.xz +/firefox-114.0.2.source.tar.xz +/firefox-langpacks-115.0-20230629.tar.xz +/firefox-115.0.source.tar.xz +/firefox-langpacks-115.0-20230703.tar.xz +/firefox-115.0.2.source.tar.xz +/firefox-langpacks-115.0.2-20230717.tar.xz +/firefox-116.0.source.tar.xz +/firefox-langpacks-116.0-20230725.tar.xz +/firefox-langpacks-116.0-20230731.tar.xz +/firefox-116.0.1.source.tar.xz +/firefox-langpacks-116.0.1-20230804.tar.xz +/firefox-langpacks-116.0.2-20230807.tar.xz +/firefox-116.0.2.source.tar.xz +/firefox-langpacks-116.0.3-20230817.tar.xz +/firefox-116.0.3.source.tar.xz +/firefox-117.0.source.tar.xz +/firefox-langpacks-117.0-20230828.tar.xz +/firefox-117.0.1.source.tar.xz +/firefox-langpacks-117.0.1-20230913.tar.xz +/firefox-118.0.source.tar.xz +/firefox-langpacks-118.0-20230925.tar.xz +/firefox-langpacks-118.0.1-20230929.tar.xz +/firefox-118.0.1.source.tar.xz +/firefox-118.0.2.source.tar.xz +/firefox-langpacks-118.0.2-20231010.tar.xz +/dump_syms-vendor.tar.xz +/firefox-langpacks-119.0.1-20231110.tar.xz +/firefox-119.0.1.source.tar.xz +/firefox-120.0.source.tar.xz +/firefox-langpacks-120.0-20231114.tar.xz +/firefox-langpacks-120.0-20231120.tar.xz +/firefox-120.0.1.source.tar.xz +/firefox-langpacks-120.0.1-20231201.tar.xz +/firefox-121.0.source.tar.xz +/firefox-langpacks-121.0-20231218.tar.xz +/firefox-121.0.1.source.tar.xz +/firefox-langpacks-121.0.1-20240112.tar.xz +/firefox-122.0.source.tar.xz +/firefox-langpacks-122.0-20240119.tar.xz +/firefox-langpacks-122.0.1-20240213.tar.xz +/firefox-122.0.1.source.tar.xz +/firefox-langpacks-123.0-20240219.tar.xz +/firefox-123.0.source.tar.xz +/firefox-123.0.1.source.tar.xz +/firefox-langpacks-123.0.1-20240307.tar.xz +/firefox-124.0.source.tar.xz +/firefox-langpacks-124.0-20240313.tar.xz +/firefox-124.0.1.source.tar.xz +/firefox-langpacks-124.0.1-20240322.tar.xz +/wasi-sdk-20.tar.gz +/wasi-sdk-20-1.fc39.src.rpm +/firefox-124.0.2.source.tar.xz +/firefox-langpacks-124.0.2-20240404.tar.xz +/firefox-langpacks-125.0-20240409.tar.xz +/firefox-125.0.source.tar.xz +/firefox-125.0.2.source.tar.xz +/firefox-langpacks-125.0.2-20240420.tar.xz +/firefox-125.0.3.source.tar.xz +/firefox-langpacks-125.0.3-20240429.tar.xz +/firefox-126.0.source.tar.xz +/firefox-langpacks-126.0-20240507.tar.xz +/firefox-127.0.source.tar.xz +/firefox-langpacks-127.0-20240610.tar.xz +/firefox-langpacks-127.0.2-20240625.tar.xz +/firefox-127.0.2.source.tar.xz +/firefox-128.0.source.tar.xz +/firefox-langpacks-128.0-20240702.tar.xz +/firefox-langpacks-128.0-20240708.tar.xz +/firefox-128.0.3.source.tar.xz +/firefox-langpacks-128.0.3-20240729.tar.xz +/firefox-129.0.source.tar.xz +/firefox-langpacks-129.0-20240730.tar.xz +/firefox-langpacks-129.0-20240802.tar.xz +/firefox-129.0.2.source.tar.xz +/firefox-langpacks-192.0.2-20240820.tar.xz +/firefox-langpacks-129.0.2-20240820.tar.xz +/firefox-langpacks-130.0-20240828.tar.xz +/firefox-130.0.source.tar.xz +/firefox-130.0.1.source.tar.xz +/firefox-langpacks-130.0.1-20240918.tar.xz +/firefox-langpacks-131.0-20240924.tar.xz +/firefox-131.0.source.tar.xz +/firefox-131.0.2.source.tar.xz +/firefox-langpacks-131.0.2-20241009.tar.xz +/firefox-131.0.3.source.tar.xz +/firefox-langpacks-131.0.3-20241015.tar.xz +/firefox-132.0.source.tar.xz +/firefox-langpacks-132.0-20241023.tar.xz +/firefox-132.0.1.source.tar.xz +/firefox-langpacks-132.0.1-20241105.tar.xz +/firefox-langpacks-132.0.2-20241115.tar.xz +/firefox-132.0.2.source.tar.xz +/firefox-133.0.source.tar.xz +/firefox-langpacks-133.0-20241122.tar.xz +/firefox-langpacks-133.0.3-20241211.tar.xz +/firefox-133.0.3.source.tar.xz +/firefox-langpacks-134.0-20250102.tar.xz +/firefox-134.0.source.tar.xz +/firefox-langpacks-134.0.1-20250115.tar.xz +/firefox-134.0.1.source.tar.xz +/firefox-134.0.2.source.tar.xz +/firefox-langpacks-134.0.2-20250122.tar.xz +/wasi-sdk-25.tar.gz +/wasm-component-ld-vendor.tar.xz +/firefox-135.0.source.tar.xz +/firefox-langpacks-135.0-20250204.tar.xz +/firefox-136.0.source.tar.xz +/firefox-langpacks-136.0-20250225.tar.xz +/firefox-langpacks-136.0-20250228.tar.xz +/firefox-136.0.1.source.tar.xz +/firefox-langpacks-136.0.1-20250312.tar.xz +/firefox-langpacks-136.0.2-20250319.tar.xz +/firefox-136.0.2.source.tar.xz +/firefox-136.0.3.source.tar.xz +/firefox-langpacks-136.0.3-20250325.tar.xz +/firefox-langpacks-137.0-20250326.tar.xz +/firefox-137.0.source.tar.xz +/firefox-langpacks-137.0-20250331.tar.xz +/firefox-137.0.1.source.tar.xz +/firefox-langpacks-137.0.1-20250414.tar.xz +/firefox-138.0.source.tar.xz +/firefox-langpacks-138.0-20250422.tar.xz +/firefox-langpacks-138.0.1-20250501.tar.xz +/firefox-138.0.1.source.tar.xz +/firefox-138.0.3.source.tar.xz +/firefox-langpacks-138.0.3-20250512.tar.xz +/firefox-langpacks-138.0.4-20250519.tar.xz +/firefox-138.0.4.source.tar.xz +/firefox-139.0.source.tar.xz +/firefox-langpacks-139.0-20250527.tar.xz +/firefox-langpacks-139.0.4-20250610.tar.xz +/firefox-139.0.4.source.tar.xz +/firefox-140.0.source.tar.xz +/firefox-langpacks-140.0-20250617.tar.xz +/firefox-140.0.1.source.tar.xz +/firefox-langpacks-140.0.1-20250627.tar.xz +/firefox-140.0.4.source.tar.xz +/firefox-langpacks-140.0.4-20250708.tar.xz +/firefox-141.0.source.tar.xz +/firefox-langpacks-141.0-20250717.tar.xz +/firefox-langpacks-141.0-20250718.tar.xz +/firefox-langpacks-141.2.0-20250806.tar.xz +/firefox-141.0.2.source.tar.xz +/firefox-langpacks-141.0.2-20250806.tar.xz +/firefox-langpacks-141.0.3-20250811.tar.xz +/firefox-141.0.3.source.tar.xz +/firefox-142.0.source.tar.xz +/firefox-langpacks-142.0-20250812.tar.xz +/firefox-langpacks-142.0.1-20250827.tar.xz +/firefox-142.0.1.source.tar.xz +/firefox-143.0.1.source.tar.xz +/firefox-langpacks-143.0.1-20250919.tar.xz +/firefox-langpacks-143.0.3-20250930.tar.xz +/firefox-143.0.3.source.tar.xz +/firefox-langpacks-144.0-20251009.tar.xz +/firefox-144.0.source.tar.xz +/firefox-langpacks-144.0-20251010.tar.xz +/firefox-145.0.source.tar.xz +/firefox-langpacks-145.0-20251105.tar.xz +/firefox-langpacks-145.0-20251111.tar.xz +/firefox-145.0.1.source.tar.xz +/firefox-langpacks-145.0.1-20251119.tar.xz +/firefox-146.0.source.tar.xz +/firefox-langpacks-146.0-20251202.tar.xz +/firefox-langpacks-146.0-20251208.tar.xz +/firefox-146.0.1.source.tar.xz +/firefox-langpacks-146.0.1-20251219.tar.xz +/firefox-langpacks-147.0-20260106.tar.xz +/firefox-147.0.source.tar.xz diff --git a/0001-GLIBCXX-fix-for-GCC-12.patch b/0001-GLIBCXX-fix-for-GCC-12.patch index 37d6f50..55153a1 100644 --- a/0001-GLIBCXX-fix-for-GCC-12.patch +++ b/0001-GLIBCXX-fix-for-GCC-12.patch @@ -1,16 +1,6 @@ -From efd5bc0715e5477318be95a76811cda0a89e8289 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= -Date: Fri, 4 Mar 2022 12:00:26 +0100 -Subject: [PATCH] GLIBCXX fix for GCC 12? - ---- - build/unix/stdc++compat/stdc++compat.cpp | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/build/unix/stdc++compat/stdc++compat.cpp b/build/unix/stdc++compat/stdc++compat.cpp -index 0180f6bcfa998..8d7a542ff11f0 100644 ---- a/build/unix/stdc++compat/stdc++compat.cpp -+++ b/build/unix/stdc++compat/stdc++compat.cpp +diff -up firefox-142.0/build/unix/stdc++compat/stdc++compat.cpp.0001-GLIBCXX-fix-for-GCC-12 firefox-142.0/build/unix/stdc++compat/stdc++compat.cpp +--- firefox-142.0/build/unix/stdc++compat/stdc++compat.cpp.0001-GLIBCXX-fix-for-GCC-12 2025-08-11 20:04:27.000000000 +0200 ++++ firefox-142.0/build/unix/stdc++compat/stdc++compat.cpp 2025-08-14 15:02:05.496137133 +0200 @@ -24,6 +24,7 @@ GLIBCXX_3.4.27 is from gcc 10 GLIBCXX_3.4.28 is from gcc 10 @@ -19,9 +9,9 @@ index 0180f6bcfa998..8d7a542ff11f0 100644 This file adds the necessary compatibility tricks to avoid symbols with version GLIBCXX_3.4.20 and bigger, keeping binary compatibility with -@@ -69,6 +70,19 @@ void __attribute__((weak)) __throw_bad_array_new_length() { MOZ_CRASH(); } - } // namespace std - #endif +@@ -94,6 +95,19 @@ void operator delete(void* ptr, size_t s + } + # endif +#if _GLIBCXX_RELEASE >= 12 +namespace std { @@ -39,6 +29,3 @@ index 0180f6bcfa998..8d7a542ff11f0 100644 /* While we generally don't build with exceptions, we have some host tools * that do use them. libstdc++ from GCC 5.0 added exception constructors with * char const* argument. Older versions only have a constructor with --- -2.35.1 - diff --git a/0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch b/0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch new file mode 100644 index 0000000..bd543b3 --- /dev/null +++ b/0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch @@ -0,0 +1,1343 @@ +diff -up firefox-119.0/modules/libpref/moz.build.integration firefox-119.0/modules/libpref/moz.build +--- firefox-119.0/modules/libpref/moz.build.integration 2023-10-19 21:54:34.000000000 +0200 ++++ firefox-119.0/modules/libpref/moz.build 2023-10-31 08:59:03.719124766 +0100 +@@ -126,6 +126,10 @@ UNIFIED_SOURCES += [ + "SharedPrefMap.cpp", + ] + ++LOCAL_INCLUDES += [ ++ '/toolkit/xre' ++] ++ + gen_all_tuple = tuple(gen_h + gen_cpp + gen_rs) + + GeneratedFile( +diff -up firefox-119.0/modules/libpref/Preferences.cpp.integration firefox-119.0/modules/libpref/Preferences.cpp +--- firefox-119.0/modules/libpref/Preferences.cpp.integration 2023-10-19 21:54:34.000000000 +0200 ++++ firefox-119.0/modules/libpref/Preferences.cpp 2023-10-31 08:59:03.719124766 +0100 +@@ -95,6 +95,7 @@ + #ifdef MOZ_BACKGROUNDTASKS + # include "mozilla/BackgroundTasks.h" + #endif ++#include "nsKDEUtils.h" + + #ifdef DEBUG + # include +diff -up firefox-119.0/python/mozbuild/mozpack/chrome/flags.py.integration firefox-119.0/python/mozbuild/mozpack/chrome/flags.py +--- firefox-119.0/python/mozbuild/mozpack/chrome/flags.py.integration 2023-10-19 21:54:34.000000000 +0200 ++++ firefox-119.0/python/mozbuild/mozpack/chrome/flags.py 2023-10-31 08:59:03.719124766 +0100 +@@ -234,6 +234,7 @@ class Flags(OrderedDict): + "tablet": Flag, + "process": StringFlag, + "backgroundtask": StringFlag, ++ "desktop": StringFlag, + } + RE = re.compile(r"([!<>=]+)") + +diff -up firefox-119.0/python/mozbuild/mozpack/chrome/manifest.py.integration firefox-119.0/python/mozbuild/mozpack/chrome/manifest.py +--- firefox-119.0/python/mozbuild/mozpack/chrome/manifest.py.integration 2023-10-19 21:54:34.000000000 +0200 ++++ firefox-119.0/python/mozbuild/mozpack/chrome/manifest.py 2023-10-31 08:59:03.719124766 +0100 +@@ -43,6 +43,7 @@ class ManifestEntry(object): + "process", + "contentaccessible", + "backgroundtask", ++ "desktop", + ] + + def __init__(self, base, *flags): +diff -up firefox-119.0/toolkit/components/downloads/moz.build.integration firefox-119.0/toolkit/components/downloads/moz.build +--- firefox-119.0/toolkit/components/downloads/moz.build.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/toolkit/components/downloads/moz.build 2023-10-31 08:59:03.720124801 +0100 +@@ -51,5 +51,9 @@ if CONFIG["MOZ_PLACES"]: + + FINAL_LIBRARY = "xul" + ++LOCAL_INCLUDES += [ ++ '/toolkit/xre' ++] ++ + with Files("**"): + BUG_COMPONENT = ("Toolkit", "Downloads API") +diff -up firefox-119.0/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs.integration firefox-119.0/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs +--- firefox-119.0/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/toolkit/mozapps/downloads/HelperAppDlg.sys.mjs 2023-10-31 08:59:03.720124801 +0100 +@@ -1246,26 +1246,56 @@ nsUnknownContentTypeDialog.prototype = { + this.chosenApp = params.handlerApp; + } + } else if ("@mozilla.org/applicationchooser;1" in Cc) { +- var nsIApplicationChooser = Ci.nsIApplicationChooser; +- var appChooser = Cc["@mozilla.org/applicationchooser;1"].createInstance( +- nsIApplicationChooser +- ); +- appChooser.init( +- this.mDialog, +- this.dialogElement("strings").getString("chooseAppFilePickerTitle") +- ); +- var contentTypeDialogObj = this; +- let appChooserCallback = function appChooserCallback_done(aResult) { +- if (aResult) { +- contentTypeDialogObj.chosenApp = aResult.QueryInterface( +- Ci.nsILocalHandlerApp +- ); +- } +- contentTypeDialogObj.finishChooseApp(); +- }; +- appChooser.open(this.mLauncher.MIMEInfo.MIMEType, appChooserCallback); +- // The finishChooseApp is called from appChooserCallback +- return; ++ // handle the KDE case which is implemented in the filepicker ++ // therefore falling back to Gtk2 like behaviour if KDE is running ++ // FIXME this should be better handled in the nsIApplicationChooser ++ // interface ++ var env = Components.classes["@mozilla.org/process/environment;1"] ++ .getService(Components.interfaces.nsIEnvironment); ++ if (env.get('KDE_FULL_SESSION') == "true") ++ { ++ var nsIFilePicker = Ci.nsIFilePicker; ++ var fp = Cc["@mozilla.org/filepicker;1"] ++ .createInstance(nsIFilePicker); ++ fp.init(this.mDialog, ++ this.dialogElement("strings").getString("chooseAppFilePickerTitle"), ++ nsIFilePicker.modeOpen); ++ ++ fp.appendFilters(nsIFilePicker.filterApps); ++ ++ fp.open(aResult => { ++ if (aResult == nsIFilePicker.returnOK && fp.file) { ++ // Remember the file they chose to run. ++ var localHandlerApp = ++ Cc["@mozilla.org/uriloader/local-handler-app;1"]. ++ createInstance(Ci.nsILocalHandlerApp); ++ localHandlerApp.executable = fp.file; ++ this.chosenApp = localHandlerApp; ++ } ++ this.finishChooseApp(); ++ }); ++ } else { ++ var nsIApplicationChooser = Ci.nsIApplicationChooser; ++ var appChooser = Cc["@mozilla.org/applicationchooser;1"].createInstance( ++ nsIApplicationChooser ++ ); ++ appChooser.init( ++ this.mDialog, ++ this.dialogElement("strings").getString("chooseAppFilePickerTitle") ++ ); ++ var contentTypeDialogObj = this; ++ let appChooserCallback = function appChooserCallback_done(aResult) { ++ if (aResult) { ++ contentTypeDialogObj.chosenApp = aResult.QueryInterface( ++ Ci.nsILocalHandlerApp ++ ); ++ } ++ contentTypeDialogObj.finishChooseApp(); ++ }; ++ appChooser.open(this.mLauncher.MIMEInfo.MIMEType, appChooserCallback); ++ // The finishChooseApp is called from appChooserCallback ++ return; ++ } + } else { + var nsIFilePicker = Ci.nsIFilePicker; + var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); +diff -up firefox-119.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.integration firefox-119.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp +--- firefox-119.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp 2023-10-31 08:59:03.720124801 +0100 +@@ -16,6 +16,8 @@ + #include "nsISupportsPrimitives.h" + #include "nsIGSettingsService.h" + #include "nsReadableUtils.h" ++#include "nsPrintfCString.h" ++#include "nsKDEUtils.h" + + using namespace mozilla; + +@@ -39,6 +41,8 @@ class nsUnixSystemProxySettings final : + nsACString& aResult); + nsresult SetProxyResultFromGSettings(const char* aKeyBase, const char* aType, + nsACString& aResult); ++ nsresult GetProxyFromKDE(const nsACString& aScheme, const nsACString& aHost, ++ PRInt32 aPort, nsACString& aResult); + }; + + NS_IMPL_ISUPPORTS(nsUnixSystemProxySettings, nsISystemProxySettings) +@@ -393,6 +397,9 @@ nsresult nsUnixSystemProxySettings::GetP + const nsACString& aHost, + const int32_t aPort, + nsACString& aResult) { ++ if (nsKDEUtils::kdeSupport()) ++ return GetProxyFromKDE(aScheme, aHost, aPort, aResult); ++ + if (mProxySettings) { + nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult); + if (NS_SUCCEEDED(rv)) return rv; +@@ -401,6 +408,28 @@ nsresult nsUnixSystemProxySettings::GetP + return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult); + } + ++nsresult nsUnixSystemProxySettings::GetProxyFromKDE(const nsACString& aScheme, ++ const nsACString& aHost, ++ PRInt32 aPort, ++ nsACString& aResult) { ++ nsAutoCString url; ++ url = aScheme; ++ url += "://"; ++ url += aHost; ++ if (aPort >= 0) { ++ url += ":"; ++ url += nsPrintfCString("%d", aPort); ++ } ++ nsTArray command; ++ command.AppendElement("GETPROXY"_ns); ++ command.AppendElement(url); ++ nsTArray result; ++ if (!nsKDEUtils::command(command, &result) || result.Length() != 1) ++ return NS_ERROR_FAILURE; ++ aResult = result[0]; ++ return NS_OK; ++} ++ + NS_IMPL_COMPONENT_FACTORY(nsUnixSystemProxySettings) { + auto result = MakeRefPtr(); + result->Init(); +diff -up firefox-119.0/toolkit/xre/moz.build.integration firefox-119.0/toolkit/xre/moz.build +--- firefox-119.0/toolkit/xre/moz.build.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/toolkit/xre/moz.build 2023-10-31 08:59:03.720124801 +0100 +@@ -96,7 +96,9 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "ui + "UIKitDirProvider.mm", + ] + elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": ++ EXPORTS += ['nsKDEUtils.h'] + UNIFIED_SOURCES += [ ++ "nsKDEUtils.cpp", + "nsNativeAppSupportUnix.cpp", + ] + CXXFLAGS += CONFIG["MOZ_X11_SM_CFLAGS"] +diff -up firefox-119.0/toolkit/xre/nsKDEUtils.cpp.integration firefox-119.0/toolkit/xre/nsKDEUtils.cpp +--- firefox-119.0/toolkit/xre/nsKDEUtils.cpp.integration 2023-10-31 08:59:03.721124836 +0100 ++++ firefox-119.0/toolkit/xre/nsKDEUtils.cpp 2023-10-31 08:59:03.721124836 +0100 +@@ -0,0 +1,286 @@ ++/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#include "nsKDEUtils.h" ++#include "nsIWidget.h" ++#include "nsISupportsPrimitives.h" ++#include "nsIMutableArray.h" ++#include "nsComponentManagerUtils.h" ++#include "nsArrayUtils.h" ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++// copied from X11/X.h as a hack since for an unknown ++// reason it's not picked up from X11/X.h ++#ifndef None ++# define None 0L /* universal null resource or null atom */ ++#endif ++ ++// #define DEBUG_KDE ++#ifdef DEBUG_KDE ++# define KMOZILLAHELPER "kmozillahelper" ++#else ++// not need for lib64, it's a binary ++# define KMOZILLAHELPER "/usr/lib/mozilla/kmozillahelper" ++#endif ++ ++#define KMOZILLAHELPER_VERSION 6 ++#define MAKE_STR2(n) #n ++#define MAKE_STR(n) MAKE_STR2(n) ++ ++static bool getKdeSession() { ++ if (PR_GetEnv("KDE_FULL_SESSION")) { ++ return true; ++ } ++ return false; ++} ++ ++static bool getKdeSupport() { ++ nsTArray command; ++ command.AppendElement("CHECK"_ns); ++ command.AppendElement("KMOZILLAHELPER_VERSION"_ns); ++ bool kde = nsKDEUtils::command(command); ++#ifdef DEBUG_KDE ++ fprintf(stderr, "KDE RUNNING %d\n", kde); ++#endif ++ return kde; ++} ++ ++nsKDEUtils::nsKDEUtils() : commandFile(NULL), replyFile(NULL) {} ++ ++nsKDEUtils::~nsKDEUtils() { ++ // closeHelper(); not actually useful, exiting will close the fd too ++} ++ ++nsKDEUtils* nsKDEUtils::self() { ++ static nsKDEUtils s; ++ return &s; ++} ++ ++static bool helperRunning = false; ++static bool helperFailed = false; ++ ++bool nsKDEUtils::kdeSession() { ++ static bool session = getKdeSession(); ++ return session; ++} ++ ++bool nsKDEUtils::kdeSupport() { ++ static bool support = kdeSession() && getKdeSupport(); ++ return support && helperRunning; ++} ++ ++struct nsKDECommandData { ++ FILE* file; ++ nsTArray* output; ++ GMainLoop* loop; ++ bool success; ++}; ++ ++static gboolean kdeReadFunc(GIOChannel*, GIOCondition, gpointer data) { ++ nsKDECommandData* p = static_cast(data); ++ char buf[8192]; // TODO big enough ++ bool command_done = false; ++ bool command_failed = false; ++ while (!command_done && !command_failed && ++ fgets(buf, 8192, p->file) != ++ NULL) { // TODO what if the kernel splits a line into two chunks? ++ // #ifdef DEBUG_KDE ++ // fprintf( stderr, "READ: %s %d\n", buf, feof( p->file )); ++ // #endif ++ if (char* eol = strchr(buf, '\n')) *eol = '\0'; ++ command_done = (strcmp(buf, "\\1") == 0); ++ command_failed = (strcmp(buf, "\\0") == 0); ++ nsAutoCString line(buf); ++ line.ReplaceSubstring("\\n", "\n"); ++ line.ReplaceSubstring( ++ "\\" ++ "\\", ++ "\\"); // \\ -> \ , i.e. unescape ++ if (p->output && !(command_done || command_failed)) ++ p->output->AppendElement(nsCString(buf)); // TODO utf8? ++ } ++ bool quit = false; ++ if (feof(p->file) || command_failed) { ++ quit = true; ++ p->success = false; ++ } ++ if (command_done) { // reading one reply finished ++ quit = true; ++ p->success = true; ++ } ++ if (quit) { ++ if (p->loop) g_main_loop_quit(p->loop); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++bool nsKDEUtils::command(const nsTArray& command, ++ nsTArray* output) { ++ return self()->internalCommand(command, NULL, false, output); ++} ++ ++bool nsKDEUtils::command(nsIArray* command, nsIArray** output) { ++ nsTArray in; ++ PRUint32 length; ++ command->GetLength(&length); ++ for (PRUint32 i = 0; i < length; i++) { ++ nsCOMPtr str = do_QueryElementAt(command, i); ++ if (str) { ++ nsAutoCString s; ++ str->GetData(s); ++ in.AppendElement(s); ++ } ++ } ++ ++ nsTArray out; ++ bool ret = self()->internalCommand(in, NULL, false, &out); ++ ++ if (!output) return ret; ++ ++ nsCOMPtr result = do_CreateInstance(NS_ARRAY_CONTRACTID); ++ if (!result) return false; ++ ++ for (PRUint32 i = 0; i < out.Length(); i++) { ++ nsCOMPtr rstr = ++ do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID); ++ if (!rstr) return false; ++ ++ rstr->SetData(out[i]); ++ result->AppendElement(rstr); ++ } ++ ++ NS_ADDREF(*output = result); ++ return ret; ++} ++ ++bool nsKDEUtils::commandBlockUi(const nsTArray& command, ++ GtkWindow* parent, ++ nsTArray* output) { ++ return self()->internalCommand(command, parent, true, output); ++} ++ ++bool nsKDEUtils::internalCommand(const nsTArray& command, ++ GtkWindow* parent, bool blockUi, ++ nsTArray* output) { ++ if (!startHelper()) return false; ++ feedCommand(command); ++ // do not store the data in 'this' but in extra structure, just in case there ++ // is reentrancy (can there be? the event loop is re-entered) ++ nsKDECommandData data; ++ data.file = replyFile; ++ data.output = output; ++ data.success = false; ++ if (blockUi) { ++ data.loop = g_main_loop_new(NULL, FALSE); ++ GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); ++ if (parent && gtk_window_get_group(parent)) ++ gtk_window_group_add_window(gtk_window_get_group(parent), ++ GTK_WINDOW(window)); ++ gtk_widget_realize(window); ++ gtk_widget_set_sensitive(window, TRUE); ++ gtk_grab_add(window); ++ GIOChannel* channel = g_io_channel_unix_new(fileno(data.file)); ++ g_io_add_watch(channel, ++ static_cast(G_IO_IN | G_IO_ERR | G_IO_HUP), ++ kdeReadFunc, &data); ++ g_io_channel_unref(channel); ++ g_main_loop_run(data.loop); ++ g_main_loop_unref(data.loop); ++ gtk_grab_remove(window); ++ gtk_widget_destroy(window); ++ } else { ++ data.loop = NULL; ++ while (kdeReadFunc(NULL, static_cast(0), &data)) ++ ; ++ } ++ return data.success; ++} ++ ++bool nsKDEUtils::startHelper() { ++ if (helperRunning) return true; ++ if (helperFailed) return false; ++ helperFailed = true; ++ int fdcommand[2]; ++ int fdreply[2]; ++ if (pipe(fdcommand) < 0) return false; ++ if (pipe(fdreply) < 0) { ++ close(fdcommand[0]); ++ close(fdcommand[1]); ++ return false; ++ } ++ char* args[2] = {const_cast(KMOZILLAHELPER), NULL}; ++ switch (fork()) { ++ case -1: { ++ close(fdcommand[0]); ++ close(fdcommand[1]); ++ close(fdreply[0]); ++ close(fdreply[1]); ++ return false; ++ } ++ case 0: // child ++ { ++ if (dup2(fdcommand[0], STDIN_FILENO) < 0) _exit(1); ++ if (dup2(fdreply[1], STDOUT_FILENO) < 0) _exit(1); ++ int maxfd = 1024; // close all other fds ++ struct rlimit rl; ++ if (getrlimit(RLIMIT_NOFILE, &rl) == 0) maxfd = rl.rlim_max; ++ for (int i = 3; i < maxfd; ++i) close(i); ++#ifdef DEBUG_KDE ++ execvp(KMOZILLAHELPER, args); ++#else ++ execv(KMOZILLAHELPER, args); ++#endif ++ _exit(1); // failed ++ } ++ default: // parent ++ { ++ commandFile = fdopen(fdcommand[1], "w"); ++ replyFile = fdopen(fdreply[0], "r"); ++ close(fdcommand[0]); ++ close(fdreply[1]); ++ if (commandFile == NULL || replyFile == NULL) { ++ closeHelper(); ++ return false; ++ } ++ // ok, helper ready, getKdeRunning() will check if it works ++ } ++ } ++ helperFailed = false; ++ helperRunning = true; ++ return true; ++} ++ ++void nsKDEUtils::closeHelper() { ++ if (commandFile != NULL) ++ fclose(commandFile); // this will also make the helper quit ++ if (replyFile != NULL) fclose(replyFile); ++ helperRunning = false; ++} ++ ++void nsKDEUtils::feedCommand(const nsTArray& command) { ++ for (int i = 0; i < command.Length(); ++i) { ++ nsCString line = command[i]; ++ line.ReplaceSubstring("\\", ++ "\\" ++ "\\"); // \ -> \\ , i.e. escape ++ line.ReplaceSubstring("\n", "\\n"); ++#ifdef DEBUG_KDE ++ fprintf(stderr, "COMM: %s\n", line.get()); ++#endif ++ fputs(line.get(), commandFile); ++ fputs("\n", commandFile); ++ } ++ fputs("\\E\n", ++ commandFile); // done as \E, so it cannot happen in normal data ++ fflush(commandFile); ++} +diff -up firefox-119.0/toolkit/xre/nsKDEUtils.h.integration firefox-119.0/toolkit/xre/nsKDEUtils.h +--- firefox-119.0/toolkit/xre/nsKDEUtils.h.integration 2023-10-31 08:59:03.721124836 +0100 ++++ firefox-119.0/toolkit/xre/nsKDEUtils.h 2023-10-31 08:59:03.721124836 +0100 +@@ -0,0 +1,53 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#ifndef nsKDEUtils_h__ ++#define nsKDEUtils_h__ ++ ++#include "nsString.h" ++#include "nsTArray.h" ++#include ++ ++typedef struct _GtkWindow GtkWindow; ++ ++class nsIArray; ++ ++class NS_EXPORT nsKDEUtils { ++ public: ++ /* Returns true if running inside a KDE session (regardless of whether there ++ is KDE support available for Firefox). This should be used e.g. when ++ determining dialog button order but not for code that requires the KDE ++ support. */ ++ static bool kdeSession(); ++ /* Returns true if running inside a KDE session and KDE support is available ++ for Firefox. This should be used everywhere where the external helper is ++ needed. */ ++ static bool kdeSupport(); ++ /* Executes the given helper command, returns true if helper returned success. ++ */ ++ static bool command(const nsTArray& command, ++ nsTArray* output = NULL); ++ static bool command(nsIArray* command, nsIArray** output = NULL); ++ /* Like command(), but additionally blocks the parent widget like if there was ++ a modal dialog shown and enters the event loop (i.e. there are still paint ++ updates, this is for commands that take long). */ ++ static bool commandBlockUi(const nsTArray& command, ++ GtkWindow* parent, ++ nsTArray* output = NULL); ++ ++ private: ++ nsKDEUtils(); ++ ~nsKDEUtils(); ++ static nsKDEUtils* self(); ++ bool startHelper(); ++ void closeHelper(); ++ void feedCommand(const nsTArray& command); ++ bool internalCommand(const nsTArray& command, GtkWindow* parent, ++ bool isParent, nsTArray* output); ++ FILE* commandFile; ++ FILE* replyFile; ++}; ++ ++#endif // nsKDEUtils +diff -up firefox-119.0/uriloader/exthandler/HandlerServiceParent.cpp.integration firefox-119.0/uriloader/exthandler/HandlerServiceParent.cpp +--- firefox-119.0/uriloader/exthandler/HandlerServiceParent.cpp.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/uriloader/exthandler/HandlerServiceParent.cpp 2023-10-31 08:59:03.721124836 +0100 +@@ -18,7 +18,7 @@ + #include "nsComponentManagerUtils.h" + #include "nsServiceManagerUtils.h" + #ifdef MOZ_WIDGET_GTK +-# include "unix/nsGNOMERegistry.h" ++# include "unix/nsCommonRegistry.h" + #endif + + using mozilla::dom::ContentHandlerService; +@@ -310,8 +310,8 @@ mozilla::ipc::IPCResult HandlerServicePa + } + #ifdef MOZ_WIDGET_GTK + // Check the GNOME registry for a protocol handler +- *aHandlerExists = +- nsGNOMERegistry::HandlerExists(PromiseFlatCString(aProtocolScheme).get()); ++ *aHandlerExists = nsCommonRegistry::HandlerExists( ++ PromiseFlatCString(aProtocolScheme).get()); + #else + *aHandlerExists = false; + #endif +diff -up firefox-119.0/uriloader/exthandler/moz.build.integration firefox-119.0/uriloader/exthandler/moz.build +--- firefox-119.0/uriloader/exthandler/moz.build.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/uriloader/exthandler/moz.build 2023-10-31 08:59:03.721124836 +0100 +@@ -86,7 +86,9 @@ else: + + if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": + UNIFIED_SOURCES += [ ++ "unix/nsCommonRegistry.cpp", + "unix/nsGNOMERegistry.cpp", ++ "unix/nsKDERegistry.cpp", + "unix/nsMIMEInfoUnix.cpp", + ] + elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "android": +@@ -134,6 +136,7 @@ LOCAL_INCLUDES += [ + "/dom/ipc", + "/netwerk/base", + "/netwerk/protocol/http", ++ "/toolkit/xre", + ] + + if CONFIG["MOZ_ENABLE_DBUS"]: +diff -up firefox-119.0/uriloader/exthandler/unix/nsCommonRegistry.cpp.integration firefox-119.0/uriloader/exthandler/unix/nsCommonRegistry.cpp +--- firefox-119.0/uriloader/exthandler/unix/nsCommonRegistry.cpp.integration 2023-10-31 08:59:03.721124836 +0100 ++++ firefox-119.0/uriloader/exthandler/unix/nsCommonRegistry.cpp 2023-10-31 08:59:03.721124836 +0100 +@@ -0,0 +1,42 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#include "nsCommonRegistry.h" ++ ++#include "nsGNOMERegistry.h" ++#include "nsKDERegistry.h" ++#include "nsString.h" ++#include "nsKDEUtils.h" ++ ++/* static */ bool nsCommonRegistry::HandlerExists(const char* aProtocolScheme) { ++ if (nsKDEUtils::kdeSupport()) ++ return nsKDERegistry::HandlerExists(aProtocolScheme); ++ return nsGNOMERegistry::HandlerExists(aProtocolScheme); ++} ++ ++/* static */ nsresult nsCommonRegistry::LoadURL(nsIURI* aURL) { ++ if (nsKDEUtils::kdeSupport()) return nsKDERegistry::LoadURL(aURL); ++ return nsGNOMERegistry::LoadURL(aURL); ++} ++ ++/* static */ void nsCommonRegistry::GetAppDescForScheme( ++ const nsACString& aScheme, nsAString& aDesc) { ++ if (nsKDEUtils::kdeSupport()) ++ return nsKDERegistry::GetAppDescForScheme(aScheme, aDesc); ++ return nsGNOMERegistry::GetAppDescForScheme(aScheme, aDesc); ++} ++ ++/* static */ already_AddRefed ++nsCommonRegistry::GetFromExtension(const nsACString& aFileExt) { ++ if (nsKDEUtils::kdeSupport()) ++ return nsKDERegistry::GetFromExtension(aFileExt); ++ return nsGNOMERegistry::GetFromExtension(aFileExt); ++} ++ ++/* static */ already_AddRefed nsCommonRegistry::GetFromType( ++ const nsACString& aMIMEType) { ++ if (nsKDEUtils::kdeSupport()) return nsKDERegistry::GetFromType(aMIMEType); ++ return nsGNOMERegistry::GetFromType(aMIMEType); ++} +diff -up firefox-119.0/uriloader/exthandler/unix/nsCommonRegistry.h.integration firefox-119.0/uriloader/exthandler/unix/nsCommonRegistry.h +--- firefox-119.0/uriloader/exthandler/unix/nsCommonRegistry.h.integration 2023-10-31 08:59:03.721124836 +0100 ++++ firefox-119.0/uriloader/exthandler/unix/nsCommonRegistry.h 2023-10-31 08:59:03.721124836 +0100 +@@ -0,0 +1,28 @@ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#ifndef nsCommonRegistry_h__ ++#define nsCommonRegistry_h__ ++ ++#include "nsIURI.h" ++#include "nsCOMPtr.h" ++ ++class nsMIMEInfoBase; ++ ++class nsCommonRegistry { ++ public: ++ static bool HandlerExists(const char* aProtocolScheme); ++ ++ static nsresult LoadURL(nsIURI* aURL); ++ ++ static void GetAppDescForScheme(const nsACString& aScheme, nsAString& aDesc); ++ ++ static already_AddRefed GetFromExtension( ++ const nsACString& aFileExt); ++ ++ static already_AddRefed GetFromType( ++ const nsACString& aMIMEType); ++}; ++ ++#endif +diff -up firefox-119.0/uriloader/exthandler/unix/nsKDERegistry.cpp.integration firefox-119.0/uriloader/exthandler/unix/nsKDERegistry.cpp +--- firefox-119.0/uriloader/exthandler/unix/nsKDERegistry.cpp.integration 2023-10-31 08:59:03.722124870 +0100 ++++ firefox-119.0/uriloader/exthandler/unix/nsKDERegistry.cpp 2023-10-31 08:59:03.722124870 +0100 +@@ -0,0 +1,75 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#include "mozilla/StaticPrefs_browser.h" ++#include "nsKDERegistry.h" ++#include "prlink.h" ++#include "prmem.h" ++#include "nsString.h" ++#include "nsMIMEInfoUnix.h" ++#include "nsKDEUtils.h" ++ ++/* static */ bool nsKDERegistry::HandlerExists(const char* aProtocolScheme) { ++ nsTArray command; ++ command.AppendElement("HANDLEREXISTS"_ns); ++ command.AppendElement(nsAutoCString(aProtocolScheme)); ++ return nsKDEUtils::command(command); ++} ++ ++/* static */ nsresult nsKDERegistry::LoadURL(nsIURI* aURL) { ++ nsTArray command; ++ command.AppendElement("OPEN"_ns); ++ nsCString url; ++ aURL->GetSpec(url); ++ command.AppendElement(url); ++ bool rv = nsKDEUtils::command(command); ++ if (!rv) return NS_ERROR_FAILURE; ++ ++ return NS_OK; ++} ++ ++/* static */ void nsKDERegistry::GetAppDescForScheme(const nsACString& aScheme, ++ nsAString& aDesc) { ++ nsTArray command; ++ command.AppendElement("GETAPPDESCFORSCHEME"_ns); ++ command.AppendElement(aScheme); ++ nsTArray output; ++ if (nsKDEUtils::command(command, &output) && output.Length() == 1) ++ CopyUTF8toUTF16(output[0], aDesc); ++} ++ ++/* static */ already_AddRefed nsKDERegistry::GetFromExtension( ++ const nsACString& aFileExt) { ++ NS_ASSERTION(aFileExt[0] != '.', "aFileExt shouldn't start with a dot"); ++ nsTArray command; ++ command.AppendElement("GETFROMEXTENSION"_ns); ++ command.AppendElement(aFileExt); ++ return GetFromHelper(command); ++} ++ ++/* static */ already_AddRefed nsKDERegistry::GetFromType( ++ const nsACString& aMIMEType) { ++ nsTArray command; ++ command.AppendElement("GETFROMTYPE"_ns); ++ command.AppendElement(aMIMEType); ++ return GetFromHelper(command); ++} ++ ++/* static */ already_AddRefed nsKDERegistry::GetFromHelper( ++ const nsTArray& command) { ++ nsTArray output; ++ if (nsKDEUtils::command(command, &output) && output.Length() == 3) { ++ nsCString mimetype = output[0]; ++ RefPtr mimeInfo = new nsMIMEInfoUnix(mimetype); ++ NS_ENSURE_TRUE(mimeInfo, nullptr); ++ nsCString description = output[1]; ++ mimeInfo->SetDescription(NS_ConvertUTF8toUTF16(description)); ++ nsCString handlerAppName = output[2]; ++ mimeInfo->SetPreferredAction(nsIMIMEInfo::saveToDisk); ++ mimeInfo->SetDefaultDescription(NS_ConvertUTF8toUTF16(handlerAppName)); ++ return mimeInfo.forget(); ++ } ++ return nullptr; ++} +diff -up firefox-119.0/uriloader/exthandler/unix/nsKDERegistry.h.integration firefox-119.0/uriloader/exthandler/unix/nsKDERegistry.h +--- firefox-119.0/uriloader/exthandler/unix/nsKDERegistry.h.integration 2023-10-31 08:59:03.722124870 +0100 ++++ firefox-119.0/uriloader/exthandler/unix/nsKDERegistry.h 2023-10-31 08:59:03.722124870 +0100 +@@ -0,0 +1,35 @@ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#ifndef nsKDERegistry_h__ ++#define nsKDERegistry_h__ ++ ++#include "nsIURI.h" ++#include "nsCOMPtr.h" ++#include "nsTArray.h" ++ ++class nsMIMEInfoBase; ++// class nsAutoCString; ++// class nsCString; ++ ++class nsKDERegistry { ++ public: ++ static bool HandlerExists(const char* aProtocolScheme); ++ ++ static nsresult LoadURL(nsIURI* aURL); ++ ++ static void GetAppDescForScheme(const nsACString& aScheme, nsAString& aDesc); ++ ++ static already_AddRefed GetFromExtension( ++ const nsACString& aFileExt); ++ ++ static already_AddRefed GetFromType( ++ const nsACString& aMIMEType); ++ ++ private: ++ static already_AddRefed GetFromHelper( ++ const nsTArray& command); ++}; ++ ++#endif // nsKDERegistry_h__ +diff -up firefox-119.0/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp.integration firefox-119.0/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp +--- firefox-119.0/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp 2023-10-31 08:59:03.722124870 +0100 +@@ -5,16 +5,19 @@ + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + #include "nsMIMEInfoUnix.h" +-#include "nsGNOMERegistry.h" ++#include "nsCommonRegistry.h" + #include "nsIGIOService.h" + #include "nsNetCID.h" + #include "nsIIOService.h" + #ifdef MOZ_ENABLE_DBUS + # include "nsDBusHandlerApp.h" + #endif ++#if defined(XP_UNIX) && !defined(XP_MACOSX) ++# include "nsKDEUtils.h" ++#endif + + nsresult nsMIMEInfoUnix::LoadUriInternal(nsIURI* aURI) { +- return nsGNOMERegistry::LoadURL(aURI); ++ return nsCommonRegistry::LoadURL(aURI); + } + + NS_IMETHODIMP +@@ -29,15 +32,15 @@ nsMIMEInfoUnix::GetHasDefaultHandler(boo + *_retval = false; + + if (mClass == eProtocolInfo) { +- *_retval = nsGNOMERegistry::HandlerExists(mSchemeOrType.get()); ++ *_retval = nsCommonRegistry::HandlerExists(mSchemeOrType.get()); + } else { + RefPtr mimeInfo = +- nsGNOMERegistry::GetFromType(mSchemeOrType); ++ nsCommonRegistry::GetFromType(mSchemeOrType); + if (!mimeInfo) { + nsAutoCString ext; + nsresult rv = GetPrimaryExtension(ext); + if (NS_SUCCEEDED(rv)) { +- mimeInfo = nsGNOMERegistry::GetFromExtension(ext); ++ mimeInfo = nsCommonRegistry::GetFromExtension(ext); + } + } + if (mimeInfo) *_retval = true; +@@ -59,6 +62,21 @@ nsresult nsMIMEInfoUnix::LaunchDefaultWi + nsAutoCString nativePath; + aFile->GetNativePath(nativePath); + ++ if (nsKDEUtils::kdeSupport()) { ++ bool supports; ++ if (NS_SUCCEEDED(GetHasDefaultHandler(&supports)) && supports) { ++ nsTArray command; ++ command.AppendElement("OPEN"_ns); ++ command.AppendElement(nativePath); ++ command.AppendElement("MIMETYPE"_ns); ++ command.AppendElement(mSchemeOrType); ++ if (nsKDEUtils::command(command)) return NS_OK; ++ } ++ if (!GetDefaultApplication()) return NS_ERROR_FILE_NOT_FOUND; ++ ++ return LaunchWithIProcess(GetDefaultApplication(), nativePath); ++ } ++ + nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); + if (!giovfs) { + return NS_ERROR_FAILURE; +diff -up firefox-119.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp.integration firefox-119.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp +--- firefox-119.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp.integration 2023-10-19 21:54:42.000000000 +0200 ++++ firefox-119.0/uriloader/exthandler/unix/nsOSHelperAppService.cpp 2023-10-31 08:59:03.722124870 +0100 +@@ -10,7 +10,7 @@ + #include "nsOSHelperAppService.h" + #include "nsMIMEInfoUnix.h" + #ifdef MOZ_WIDGET_GTK +-# include "nsGNOMERegistry.h" ++# include "nsCommonRegistry.h" + # ifdef MOZ_BUILD_APP_IS_BROWSER + # include "nsIToolkitShellService.h" + # include "nsIGNOMEShellService.h" +@@ -1106,7 +1106,7 @@ nsresult nsOSHelperAppService::OSProtoco + if (!XRE_IsContentProcess()) { + #ifdef MOZ_WIDGET_GTK + // Check the GNOME registry for a protocol handler +- *aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme); ++ *aHandlerExists = nsCommonRegistry::HandlerExists(aProtocolScheme); + #else + *aHandlerExists = false; + #endif +@@ -1126,7 +1126,7 @@ nsresult nsOSHelperAppService::OSProtoco + NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription( + const nsACString& aScheme, nsAString& _retval) { + #ifdef MOZ_WIDGET_GTK +- nsGNOMERegistry::GetAppDescForScheme(aScheme, _retval); ++ nsCommonRegistry::GetAppDescForScheme(aScheme, _retval); + return _retval.IsEmpty() ? NS_ERROR_NOT_AVAILABLE : NS_OK; + #else + return NS_ERROR_NOT_AVAILABLE; +@@ -1231,7 +1231,7 @@ already_AddRefed nsOSHel + #ifdef MOZ_WIDGET_GTK + LOG("Looking in GNOME registry\n"); + RefPtr gnomeInfo = +- nsGNOMERegistry::GetFromExtension(aFileExt); ++ nsCommonRegistry::GetFromExtension(aFileExt); + if (gnomeInfo) { + LOG("Got MIMEInfo from GNOME registry\n"); + return gnomeInfo.forget(); +@@ -1344,7 +1344,7 @@ already_AddRefed nsOSHel + + #ifdef MOZ_WIDGET_GTK + if (handler.IsEmpty()) { +- RefPtr gnomeInfo = nsGNOMERegistry::GetFromType(aMIMEType); ++ RefPtr gnomeInfo = nsCommonRegistry::GetFromType(aMIMEType); + if (gnomeInfo) { + LOG("Got MIMEInfo from GNOME registry without extensions; setting them " + "to %s\n", +diff -up firefox-119.0/widget/gtk/moz.build.integration firefox-119.0/widget/gtk/moz.build +--- firefox-119.0/widget/gtk/moz.build.integration 2023-10-31 08:59:03.704124244 +0100 ++++ firefox-119.0/widget/gtk/moz.build 2023-10-31 08:59:03.723124906 +0100 +@@ -161,6 +161,7 @@ LOCAL_INCLUDES += [ + "/layout/xul", + "/other-licenses/atk-1.0", + "/third_party/cups/include", ++ "/toolkit/xre", + "/widget", + "/widget/headless", + "/widget/x11", +diff -up firefox-119.0/widget/gtk/nsFilePicker.cpp.integration firefox-119.0/widget/gtk/nsFilePicker.cpp +--- firefox-119.0/widget/gtk/nsFilePicker.cpp.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/widget/gtk/nsFilePicker.cpp 2023-10-31 08:59:03.723124906 +0100 +@@ -5,6 +5,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -30,6 +31,8 @@ + #include "WidgetUtilsGtk.h" + + #include "nsFilePicker.h" ++#include "nsKDEUtils.h" ++#include "nsURLHelper.h" + + #undef LOG + #ifdef MOZ_LOGGING +@@ -310,7 +313,8 @@ NS_IMETHODIMP + nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter) { + if (aFilter.EqualsLiteral("..apps")) { + // No platform specific thing we can do here, really.... +- return NS_OK; ++ // Unless it's KDE. ++ if (mMode != modeOpen || !nsKDEUtils::kdeSupport()) return NS_OK; + } + + nsAutoCString filter, name; +@@ -420,6 +424,31 @@ nsFilePicker::Open(nsIFilePickerShownCal + // Can't show two dialogs concurrently with the same filepicker + if (mRunning) return NS_ERROR_NOT_AVAILABLE; + ++ // KDE file picker is not handled via callback ++ if (nsKDEUtils::kdeSupport()) { ++ mCallback = aCallback; ++ mRunning = true; ++ NS_ADDREF_THIS(); ++ g_idle_add( ++ [](gpointer data) -> gboolean { ++ nsFilePicker* queuedPicker = (nsFilePicker*)data; ++ nsIFilePicker::ResultCode result; ++ queuedPicker->kdeFileDialog(&result); ++ if (queuedPicker->mCallback) { ++ queuedPicker->mCallback->Done(result); ++ queuedPicker->mCallback = nullptr; ++ } else { ++ queuedPicker->mResult = result; ++ } ++ queuedPicker->mRunning = false; ++ NS_RELEASE(queuedPicker); ++ return G_SOURCE_REMOVE; ++ }, ++ this); ++ ++ return NS_OK; ++ } ++ + NS_ConvertUTF16toUTF8 title(mTitle); + + GtkWindow* parent_widget = +@@ -701,6 +730,205 @@ void nsFilePicker::Done(void* file_choos + NS_RELEASE_THIS(); + } + ++nsCString nsFilePicker::kdeMakeFilter(int index) { ++ nsCString buf = mFilters[index]; ++ for (PRUint32 i = 0; i < buf.Length(); ++i) ++ if (buf[i] == ';') // KDE separates just using spaces ++ buf.SetCharAt(' ', i); ++ if (!mFilterNames[index].IsEmpty()) { ++ buf += "|"; ++ buf += mFilterNames[index].get(); ++ } ++ return buf; ++} ++ ++static PRInt32 windowToXid(nsIWidget* widget) { ++ GtkWindow* parent_widget = ++ GTK_WINDOW(widget->GetNativeData(NS_NATIVE_SHELLWIDGET)); ++ GdkWindow* gdk_window = ++ gtk_widget_get_window(gtk_widget_get_toplevel(GTK_WIDGET(parent_widget))); ++ return GDK_WINDOW_XID(gdk_window); ++} ++ ++NS_IMETHODIMP nsFilePicker::kdeFileDialog(nsIFilePicker::ResultCode* aReturn) { ++ NS_ENSURE_ARG_POINTER(aReturn); ++ ++ if (mMode == modeOpen && mFilters.Length() == 1 && ++ mFilters[0].EqualsLiteral("..apps")) ++ return kdeAppsDialog(aReturn); ++ ++ nsCString title; ++ title.Adopt(ToNewUTF8String(mTitle)); ++ ++ const char* arg = NULL; ++ if (mAllowURLs) { ++ switch (mMode) { ++ case nsIFilePicker::modeOpen: ++ case nsIFilePicker::modeOpenMultiple: ++ arg = "GETOPENURL"; ++ break; ++ case nsIFilePicker::modeSave: ++ arg = "GETSAVEURL"; ++ break; ++ case nsIFilePicker::modeGetFolder: ++ arg = "GETDIRECTORYURL"; ++ break; ++ } ++ } else { ++ switch (mMode) { ++ case nsIFilePicker::modeOpen: ++ case nsIFilePicker::modeOpenMultiple: ++ arg = "GETOPENFILENAME"; ++ break; ++ case nsIFilePicker::modeSave: ++ arg = "GETSAVEFILENAME"; ++ break; ++ case nsIFilePicker::modeGetFolder: ++ arg = "GETDIRECTORYFILENAME"; ++ break; ++ } ++ } ++ ++ nsAutoCString directory; ++ if (mDisplayDirectory) { ++ mDisplayDirectory->GetNativePath(directory); ++ } else if (mPrevDisplayDirectory) { ++ mPrevDisplayDirectory->GetNativePath(directory); ++ } ++ ++ nsAutoCString startdir; ++ if (!directory.IsEmpty()) { ++ startdir = directory; ++ } ++ if (mMode == nsIFilePicker::modeSave) { ++ if (!startdir.IsEmpty()) { ++ startdir += "/"; ++ startdir += ToNewUTF8String(mDefault); ++ } else ++ startdir = ToNewUTF8String(mDefault); ++ } ++ ++ nsAutoCString filters; ++ PRInt32 count = mFilters.Length(); ++ if (count == 0) // just in case ++ filters = "*"; ++ else { ++ filters = kdeMakeFilter(0); ++ for (PRInt32 i = 1; i < count; ++i) { ++ filters += "\n"; ++ filters += kdeMakeFilter(i); ++ } ++ } ++ ++ nsTArray command; ++ command.AppendElement(nsAutoCString(arg)); ++ command.AppendElement(startdir); ++ if (mMode != nsIFilePicker::modeGetFolder) { ++ command.AppendElement(filters); ++ nsAutoCString selected; ++ selected.AppendInt(mSelectedType); ++ command.AppendElement(selected); ++ } ++ command.AppendElement(title); ++ if (mMode == nsIFilePicker::modeOpenMultiple) ++ command.AppendElement("MULTIPLE"_ns); ++ if (PRInt32 xid = windowToXid(mParentWidget)) { ++ command.AppendElement("PARENT"_ns); ++ nsAutoCString parent; ++ parent.AppendInt(xid); ++ command.AppendElement(parent); ++ } ++ ++ nsTArray output; ++ if (nsKDEUtils::commandBlockUi( ++ command, ++ GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)), ++ &output)) { ++ *aReturn = nsIFilePicker::returnOK; ++ mFiles.Clear(); ++ if (mMode != nsIFilePicker::modeGetFolder) { ++ mSelectedType = atoi(output[0].get()); ++ output.RemoveElementAt(0); ++ } ++ if (mMode == nsIFilePicker::modeOpenMultiple) { ++ mFileURL.Truncate(); ++ PRUint32 count = output.Length(); ++ for (PRUint32 i = 0; i < count; ++i) { ++ nsCOMPtr localfile; ++ nsresult rv = NS_NewNativeLocalFile(output[i], PR_FALSE, ++ getter_AddRefs(localfile)); ++ if (NS_SUCCEEDED(rv)) mFiles.AppendObject(localfile); ++ } ++ } else { ++ if (output.Length() == 0) ++ mFileURL = nsCString(); ++ else if (mAllowURLs) ++ mFileURL = output[0]; ++ else // GetFile() actually requires it to be url even for local files :-/ ++ { ++ nsCOMPtr localfile; ++ nsresult rv = NS_NewNativeLocalFile(output[0], PR_FALSE, ++ getter_AddRefs(localfile)); ++ if (NS_SUCCEEDED(rv)) ++ rv = net_GetURLSpecFromActualFile(localfile, mFileURL); ++ } ++ } ++ // Remember last used directory. ++ nsCOMPtr file; ++ GetFile(getter_AddRefs(file)); ++ if (file) { ++ nsCOMPtr dir; ++ file->GetParent(getter_AddRefs(dir)); ++ nsCOMPtr localDir(dir); ++ if (localDir) { ++ localDir.swap(mPrevDisplayDirectory); ++ } ++ } ++ if (mMode == nsIFilePicker::modeSave) { ++ nsCOMPtr file; ++ GetFile(getter_AddRefs(file)); ++ if (file) { ++ bool exists = false; ++ file->Exists(&exists); ++ if (exists) // TODO do overwrite check in the helper app ++ *aReturn = nsIFilePicker::returnReplace; ++ } ++ } ++ } else { ++ *aReturn = nsIFilePicker::returnCancel; ++ } ++ return NS_OK; ++} ++ ++NS_IMETHODIMP nsFilePicker::kdeAppsDialog(nsIFilePicker::ResultCode* aReturn) { ++ NS_ENSURE_ARG_POINTER(aReturn); ++ ++ nsCString title; ++ title.Adopt(ToNewUTF8String(mTitle)); ++ ++ nsTArray command; ++ command.AppendElement("APPSDIALOG"_ns); ++ command.AppendElement(title); ++ if (PRInt32 xid = windowToXid(mParentWidget)) { ++ command.AppendElement("PARENT"_ns); ++ nsAutoCString parent; ++ parent.AppendInt(xid); ++ command.AppendElement(parent); ++ } ++ ++ nsTArray output; ++ if (nsKDEUtils::commandBlockUi( ++ command, ++ GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET)), ++ &output)) { ++ *aReturn = nsIFilePicker::returnOK; ++ mFileURL = output.Length() > 0 ? output[0] : nsCString(); ++ } else { ++ *aReturn = nsIFilePicker::returnCancel; ++ } ++ return NS_OK; ++} ++ + // All below functions available as of GTK 3.20+ + void* nsFilePicker::GtkFileChooserNew(const gchar* title, GtkWindow* parent, + GtkFileChooserAction action, +diff -up firefox-119.0/widget/gtk/nsFilePicker.h.integration firefox-119.0/widget/gtk/nsFilePicker.h +--- firefox-119.0/widget/gtk/nsFilePicker.h.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/widget/gtk/nsFilePicker.h 2023-10-31 08:59:03.723124906 +0100 +@@ -76,6 +76,12 @@ class nsFilePicker : public nsBaseFilePi + private: + static nsIFile* mPrevDisplayDirectory; + ++ bool kdeRunning(); ++ bool getKdeRunning(); ++ NS_IMETHODIMP kdeFileDialog(nsIFilePicker::ResultCode* aReturn); ++ NS_IMETHODIMP kdeAppsDialog(nsIFilePicker::ResultCode* aReturn); ++ nsCString kdeMakeFilter(int index); ++ + void* GtkFileChooserNew(const gchar* title, GtkWindow* parent, + GtkFileChooserAction action, + const gchar* accept_label); +diff -up firefox-119.0/xpcom/components/ManifestParser.cpp.integration firefox-119.0/xpcom/components/ManifestParser.cpp +--- firefox-119.0/xpcom/components/ManifestParser.cpp.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/xpcom/components/ManifestParser.cpp 2023-10-31 08:59:03.723124906 +0100 +@@ -43,6 +43,7 @@ + #include "nsIScriptError.h" + #include "nsIXULAppInfo.h" + #include "nsIXULRuntime.h" ++#include "nsKDEUtils.h" + + using namespace mozilla; + +@@ -394,6 +395,7 @@ void ParseManifest(NSLocationType aType, + constexpr auto kOs = u"os"_ns; + constexpr auto kOsVersion = u"osversion"_ns; + constexpr auto kABI = u"abi"_ns; ++ constexpr auto kDesktop = u"desktop"_ns; + constexpr auto kProcess = u"process"_ns; + #if defined(MOZ_WIDGET_ANDROID) + constexpr auto kTablet = u"tablet"_ns; +@@ -453,6 +455,7 @@ void ParseManifest(NSLocationType aType, + } + + nsAutoString osVersion; ++ nsAutoString desktop; + #if defined(XP_WIN) + # pragma warning(push) + # pragma warning(disable : 4996) // VC12+ deprecates GetVersionEx +@@ -461,14 +464,17 @@ void ParseManifest(NSLocationType aType, + nsTextFormatter::ssprintf(osVersion, u"%ld.%ld", info.dwMajorVersion, + info.dwMinorVersion); + } ++ desktop = u"win"_ns; + # pragma warning(pop) + #elif defined(MOZ_WIDGET_COCOA) + SInt32 majorVersion = nsCocoaFeatures::macOSVersionMajor(); + SInt32 minorVersion = nsCocoaFeatures::macOSVersionMinor(); + nsTextFormatter::ssprintf(osVersion, u"%ld.%ld", majorVersion, minorVersion); ++ desktop = u"macosx"_ns); + #elif defined(MOZ_WIDGET_GTK) + nsTextFormatter::ssprintf(osVersion, u"%ld.%ld", gtk_major_version, + gtk_minor_version); ++ desktop = nsKDEUtils::kdeSession() ? u"kde"_ns : u"gnome"_ns; + #elif defined(MOZ_WIDGET_ANDROID) + bool isTablet = false; + if (jni::IsAvailable()) { +@@ -476,6 +482,7 @@ void ParseManifest(NSLocationType aType, + osVersion.Assign(release->ToString()); + isTablet = java::GeckoAppShell::IsTablet(); + } ++ desktop = u"android"_ns; + #endif + + if (XRE_IsContentProcess()) { +@@ -576,6 +583,7 @@ void ParseManifest(NSLocationType aType, + : eUnspecified; + #endif + int flags = 0; ++ TriState stDesktop = eUnspecified; + + while ((token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) && + ok) { +@@ -585,6 +593,7 @@ void ParseManifest(NSLocationType aType, + if (CheckStringFlag(kApplication, wtoken, appID, stApp) || + CheckOsFlag(kOs, wtoken, osTarget, stOs) || + CheckStringFlag(kABI, wtoken, abi, stABI) || ++ CheckStringFlag(kDesktop, wtoken, desktop, stDesktop) || + CheckStringFlag(kProcess, wtoken, process, stProcess) || + CheckVersionFlag(kOsVersion, wtoken, osVersion, stOsVersion) || + CheckVersionFlag(kAppVersion, wtoken, appVersion, stAppVersion) || +@@ -644,6 +653,7 @@ void ParseManifest(NSLocationType aType, + + if (!ok || stApp == eBad || stAppVersion == eBad || + stGeckoVersion == eBad || stOs == eBad || stOsVersion == eBad || ++ stDesktop == eBad || + #ifdef MOZ_WIDGET_ANDROID + stTablet == eBad || + #endif +diff -up firefox-119.0/xpcom/components/moz.build.integration firefox-119.0/xpcom/components/moz.build +--- firefox-119.0/xpcom/components/moz.build.integration 2023-10-19 21:54:44.000000000 +0200 ++++ firefox-119.0/xpcom/components/moz.build 2023-10-31 08:59:03.723124906 +0100 +@@ -71,6 +71,7 @@ LOCAL_INCLUDES += [ + "/js/xpconnect/loader", + "/layout/build", + "/modules/libjar", ++ "/toolkit/xre", + ] + + if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": +diff -up firefox-119.0/xpcom/io/nsLocalFileUnix.cpp.integration firefox-119.0/xpcom/io/nsLocalFileUnix.cpp +--- firefox-119.0/xpcom/io/nsLocalFileUnix.cpp.integration 2023-10-19 21:54:43.000000000 +0200 ++++ firefox-119.0/xpcom/io/nsLocalFileUnix.cpp 2023-10-31 08:59:03.724124940 +0100 +@@ -51,6 +51,7 @@ + + #ifdef MOZ_WIDGET_GTK + # include "nsIGIOService.h" ++# include "nsKDEUtils.h" + #endif + + #ifdef MOZ_WIDGET_COCOA +@@ -2172,10 +2173,18 @@ nsLocalFile::Reveal() { + } + + #ifdef MOZ_WIDGET_GTK ++ nsAutoCString url; + nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); +- if (!giovfs) { +- return NS_ERROR_FAILURE; ++ url = mPath; ++ if (nsKDEUtils::kdeSupport()) { ++ nsTArray command; ++ command.AppendElement("REVEAL"_ns); ++ command.AppendElement(mPath); ++ return nsKDEUtils::command(command) ? NS_OK : NS_ERROR_FAILURE; + } ++ ++ if (!giovfs) return NS_ERROR_FAILURE; ++ + return giovfs->RevealFile(this); + #elif defined(MOZ_WIDGET_COCOA) + CFURLRef url; +@@ -2197,6 +2206,13 @@ nsLocalFile::Launch() { + } + + #ifdef MOZ_WIDGET_GTK ++ if (nsKDEUtils::kdeSupport()) { ++ nsTArray command; ++ command.AppendElement("OPEN"_ns); ++ command.AppendElement(mPath); ++ return nsKDEUtils::command(command) ? NS_OK : NS_ERROR_FAILURE; ++ } ++ + nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); + if (!giovfs) { + return NS_ERROR_FAILURE; diff --git a/0026-Add-KDE-integration-to-Firefox.patch b/0026-Add-KDE-integration-to-Firefox.patch new file mode 100644 index 0000000..1e2e938 --- /dev/null +++ b/0026-Add-KDE-integration-to-Firefox.patch @@ -0,0 +1,279 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Martin Sirringhaus +Date: Tue, 8 Aug 2023 16:18:24 +0300 +Subject: [PATCH] Add KDE integration to Firefox + +Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=140751 +Bug: https://bugzilla.suse.com/show_bug.cgi?id=170055 + +How to apply this patch: + +1. Import and apply it +2. cp browser/base/content/browser.xul browser/base/content/browser-kde.xul +3. Find editBookmarkPanelDoneButton +4. Replace #ifndef with #ifdef in the line above (this hanges the button order from Gnome-style to KDE-style) +5. hg qrefresh +--- + browser/components/preferences/main.js | 18 +++ + browser/components/shell/moz.build | 2 + + .../components/shell/nsKDEShellService.cpp | 109 ++++++++++++++++++ + browser/components/shell/nsKDEShellService.h | 32 +++++ + .../components/shell/nsUnixShellService.cpp | 22 ++++ + browser/components/shell/nsUnixShellService.h | 15 +++ + 6 files changed, 198 insertions(+) + create mode 100644 browser/components/shell/nsKDEShellService.cpp + create mode 100644 browser/components/shell/nsKDEShellService.h + create mode 100644 browser/components/shell/nsUnixShellService.cpp + create mode 100644 browser/components/shell/nsUnixShellService.h + +diff --git a/browser/components/preferences/main.js b/browser/components/preferences/main.js +index 820e46fb006567bfdf93e2a46da5e3c07d42bf10..57d1c21bdecc2d55d0bed30246e684d3b97ad7fa 100644 +--- a/browser/components/preferences/main.js ++++ b/browser/components/preferences/main.js +@@ -294,6 +294,13 @@ var gMainPane = { + }, backoffTimes[this._backoffIndex]); + } + ++ var env = Components.classes["@mozilla.org/process/environment;1"] ++ .getService(Components.interfaces.nsIEnvironment); ++ var kde_session = 0; ++ if (env.get('KDE_FULL_SESSION') == "true") { ++ kde_session = 1; ++ } ++ + this.initBrowserContainers(); + this.buildContentProcessCountMenuList(); + +@@ -1727,6 +1734,17 @@ var gMainPane = { + } + try { + shellSvc.setDefaultBrowser(true, false); ++ if (kde_session == 1) { ++ var shellObj = Components.classes["@mozilla.org/file/local;1"] ++ .createInstance(Components.interfaces.nsILocalFile); ++ shellObj.initWithPath("/usr/bin/kwriteconfig"); ++ var process = Components.classes["@mozilla.org/process/util;1"] ++ .createInstance(Components.interfaces.nsIProcess); ++ process.init(shellObj); ++ var args = ["--file", "kdeglobals", "--group", "General", "--key", ++ "BrowserApplication", "firefox"]; ++ process.run(false, args, args.length); ++ } + } catch (ex) { + console.error(ex); + return; +diff --git a/browser/components/shell/moz.build b/browser/components/shell/moz.build +index eb88cb287dc3f04022b74b978666118bbd5fa6b2..95277533781a7224d108e3c45731a6d9a89ba1a0 100644 +--- a/browser/components/shell/moz.build ++++ b/browser/components/shell/moz.build +@@ -36,6 +36,8 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": + + SOURCES += [ + "nsGNOMEShellService.cpp", ++ "nsKDEShellService.cpp", ++ "nsUnixShellService.cpp", + ] + if CONFIG["MOZ_ENABLE_DBUS"]: + SOURCES += [ +diff --git a/browser/components/shell/nsKDEShellService.cpp b/browser/components/shell/nsKDEShellService.cpp +new file mode 100644 +index 0000000000000000000000000000000000000000..152a3aca87ea73477bc75c4e93c01e5a52dda102 +--- /dev/null ++++ b/browser/components/shell/nsKDEShellService.cpp +@@ -0,0 +1,109 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#include "mozilla/ArrayUtils.h" ++ ++#include "nsCOMPtr.h" ++#include "nsKDEShellService.h" ++#include "nsShellService.h" ++#include "nsKDEUtils.h" ++#include "nsIPrefService.h" ++#include "nsIProcess.h" ++#include "nsIFile.h" ++#include "nsServiceManagerUtils.h" ++#include "nsComponentManagerUtils.h" ++#include "nsIMutableArray.h" ++#include "nsISupportsPrimitives.h" ++#include "nsArrayUtils.h" ++ ++using namespace mozilla; ++ ++nsresult ++nsKDEShellService::Init() ++{ ++ if( !nsKDEUtils::kdeSupport()) ++ return NS_ERROR_NOT_AVAILABLE; ++ return NS_OK; ++} ++ ++NS_IMPL_ISUPPORTS(nsKDEShellService, nsIGNOMEShellService, nsIShellService) ++ ++NS_IMETHODIMP ++nsKDEShellService::IsDefaultBrowser(bool aForAllTypes, ++ bool* aIsDefaultBrowser) ++{ ++ *aIsDefaultBrowser = false; ++ ++ nsCOMPtr command = do_CreateInstance( NS_ARRAY_CONTRACTID ); ++ if (!command) ++ return NS_ERROR_FAILURE; ++ ++ nsCOMPtr str = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID ); ++ if (!str) ++ return NS_ERROR_FAILURE; ++ ++ str->SetData("ISDEFAULTBROWSER"_ns); ++ command->AppendElement( str ); ++ ++ if( nsKDEUtils::command( command )) ++ *aIsDefaultBrowser = true; ++ return NS_OK; ++} ++ ++NS_IMETHODIMP ++nsKDEShellService::SetDefaultBrowser(bool aClaimAllTypes, ++ bool aForAllUsers) ++{ ++ nsCOMPtr command = do_CreateInstance( NS_ARRAY_CONTRACTID ); ++ if (!command) ++ return NS_ERROR_FAILURE; ++ ++ nsCOMPtr cmdstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID ); ++ nsCOMPtr paramstr = do_CreateInstance( NS_SUPPORTS_CSTRING_CONTRACTID ); ++ if (!cmdstr || !paramstr) ++ return NS_ERROR_FAILURE; ++ ++ cmdstr->SetData("SETDEFAULTBROWSER"_ns); ++ command->AppendElement( cmdstr ); ++ ++ paramstr->SetData( aClaimAllTypes ? "ALLTYPES"_ns : "NORMAL"_ns ); ++ command->AppendElement( paramstr ); ++ ++ return nsKDEUtils::command( command ) ? NS_OK : NS_ERROR_FAILURE; ++} ++ ++NS_IMETHODIMP ++nsKDEShellService::GetCanSetDesktopBackground(bool* aResult) ++{ ++ *aResult = true; ++ return NS_OK; ++} ++ ++NS_IMETHODIMP ++nsKDEShellService::SetDesktopBackground(dom::Element* aElement, ++ int32_t aPosition, ++ const nsACString& aImageName) ++{ ++ return NS_ERROR_NOT_IMPLEMENTED; ++} ++ ++NS_IMETHODIMP ++nsKDEShellService::GetDesktopBackgroundColor(PRUint32 *aColor) ++{ ++ return NS_ERROR_NOT_IMPLEMENTED; ++} ++ ++NS_IMETHODIMP ++nsKDEShellService::SetDesktopBackgroundColor(PRUint32 aColor) ++{ ++ return NS_ERROR_NOT_IMPLEMENTED; ++} ++ ++NS_IMETHODIMP ++nsKDEShellService::IsDefaultForScheme(nsTSubstring const& aScheme, bool* aIsDefaultBrowser) ++{ ++ return NS_ERROR_NOT_IMPLEMENTED; ++} ++ +diff --git a/browser/components/shell/nsKDEShellService.h b/browser/components/shell/nsKDEShellService.h +new file mode 100644 +index 0000000000000000000000000000000000000000..8b0bb19164352453cfa453dd87c19263160b9ad8 +--- /dev/null ++++ b/browser/components/shell/nsKDEShellService.h +@@ -0,0 +1,32 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#ifndef nskdeshellservice_h____ ++#define nskdeshellservice_h____ ++ ++#include "nsIGNOMEShellService.h" ++#include "nsToolkitShellService.h" ++#include "nsString.h" ++#include "mozilla/Attributes.h" ++ ++class nsKDEShellService final : public nsIGNOMEShellService, ++ public nsToolkitShellService ++{ ++public: ++ nsKDEShellService() : mCheckedThisSession(false) { } ++ ++ NS_DECL_ISUPPORTS ++ NS_DECL_NSISHELLSERVICE ++ NS_DECL_NSIGNOMESHELLSERVICE ++ ++ nsresult Init(); ++ ++private: ++ ~nsKDEShellService() {} ++ ++ bool mCheckedThisSession; ++}; ++ ++#endif // nskdeshellservice_h____ +diff --git a/browser/components/shell/nsUnixShellService.cpp b/browser/components/shell/nsUnixShellService.cpp +new file mode 100644 +index 0000000000000000000000000000000000000000..abf266ebdc52e136f495911da3454e69c770c6db +--- /dev/null ++++ b/browser/components/shell/nsUnixShellService.cpp +@@ -0,0 +1,22 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++ ++#include "nsUnixShellService.h" ++#include "nsGNOMEShellService.h" ++#include "nsKDEShellService.h" ++#include "nsKDEUtils.h" ++#include "mozilla/ModuleUtils.h" ++ ++NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init) ++NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsKDEShellService, Init) ++ ++NS_IMETHODIMP ++nsUnixShellServiceConstructor(REFNSIID aIID, void **aResult) ++{ ++ if( nsKDEUtils::kdeSupport()) ++ return nsKDEShellServiceConstructor( aIID, aResult ); ++ return nsGNOMEShellServiceConstructor( aIID, aResult ); ++} +diff --git a/browser/components/shell/nsUnixShellService.h b/browser/components/shell/nsUnixShellService.h +new file mode 100644 +index 0000000000000000000000000000000000000000..26b5dbac47dd9a8ec1fcb6c93575cca750692735 +--- /dev/null ++++ b/browser/components/shell/nsUnixShellService.h +@@ -0,0 +1,15 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++ ++#ifndef nsunixshellservice_h____ ++#define nsunixshellservice_h____ ++ ++#include "nsIGNOMEShellService.h" ++ ++NS_IMETHODIMP ++nsUnixShellServiceConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult); ++ ++#endif // nsunixshellservice_h____ diff --git a/D147266.diff b/D147266.diff deleted file mode 100644 index 5f8a580..0000000 --- a/D147266.diff +++ /dev/null @@ -1,31 +0,0 @@ -diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp ---- a/widget/gtk/nsWindow.cpp -+++ b/widget/gtk/nsWindow.cpp -@@ -1430,20 +1430,20 @@ - } - #endif - if (popup->mPopupContextMenu && !popup->mPopupAnchored) { - LOG(" popup [%p] is first context menu", popup); - popup->mRelativePopupPosition = popup->mPopupPosition; -- } else if (popup->mPopupAnchored) { -- LOG(" popup [%p] is anchored", popup); -- if (!popup->mPopupMatchesLayout) { -- NS_WARNING("Anchored popup does not match layout!"); -- } -- popup->mRelativePopupPosition = popup->mPopupPosition; - } else if (popup->mWaylandPopupPrev->mWaylandToplevel == nullptr) { - LOG(" popup [%p] has toplevel as parent", popup); - popup->mRelativePopupPosition = popup->mPopupPosition; - } else { -+ if (popup->mPopupAnchored) { -+ LOG(" popup [%p] is anchored", popup); -+ if (!popup->mPopupMatchesLayout) { -+ NS_WARNING("Anchored popup does not match layout!"); -+ } -+ } - GdkPoint parent = WaylandGetParentPosition(); - - LOG(" popup [%p] uses transformed coordinates\n", popup); - LOG(" parent position [%d, %d]\n", parent.x, parent.y); - LOG(" popup position [%d, %d]\n", popup->mPopupPosition.x, - diff --git a/D147267.diff b/D147267.diff deleted file mode 100644 index 1191b85..0000000 --- a/D147267.diff +++ /dev/null @@ -1,19 +0,0 @@ -diff -up firefox-100.0.2/widget/gtk/nsWindow.cpp.D147267 firefox-100.0.2/widget/gtk/nsWindow.cpp ---- firefox-100.0.2/widget/gtk/nsWindow.cpp.D147267 2022-05-25 11:46:48.291005415 +0200 -+++ firefox-100.0.2/widget/gtk/nsWindow.cpp 2022-05-25 11:50:11.447736538 +0200 -@@ -2359,11 +2359,12 @@ void nsWindow::WaylandPopupMove() { - LOG(" popup use move to rect %d\n", mPopupUseMoveToRect); - - if (!mPopupUseMoveToRect) { -- if (mNeedsShow && mPopupType != ePopupTypeTooltip) { -+ if (mPopupHint == ePopupTypeMenu) { - // Workaround for https://gitlab.gnome.org/GNOME/gtk/-/issues/4308 -- // Tooltips are created as subsurfaces with relative position. -+ // Tooltips/Utility popus are created as subsurfaces with relative position. -+ // Menu uses absolute positions. - LOG(" use gtk_window_move(%d, %d) for hidden widget\n", mPopupPosition.x, -- mPopupPosition.y); -+ mPopupPosition.y); - gtk_window_move(GTK_WINDOW(mShell), mPopupPosition.x, mPopupPosition.y); - } else { - LOG(" use gtk_window_move(%d, %d) for visible widget\n", diff --git a/build-aarch64-skia.patch b/build-aarch64-skia.patch index a63e3e8..9223bb8 100644 --- a/build-aarch64-skia.patch +++ b/build-aarch64-skia.patch @@ -1,45 +1,33 @@ -diff -up firefox-72.0/gfx/skia/skia/include/private/SkHalf.h.aarch64-skia firefox-72.0/gfx/skia/skia/include/private/SkHalf.h ---- firefox-72.0/gfx/skia/skia/include/private/SkHalf.h.aarch64-skia 2020-01-02 22:33:02.000000000 +0100 -+++ firefox-72.0/gfx/skia/skia/include/private/SkHalf.h 2020-01-03 09:00:37.537296105 +0100 -@@ -40,7 +40,7 @@ static inline Sk4h SkFloatToHalf_finite_ +diff -up firefox-134.0-build/firefox-134.0/gfx/skia/skia/modules/skcms/src/Transform_inl.h.aarch64-skia firefox-134.0-build/firefox-134.0/gfx/skia/skia/modules/skcms/src/Transform_inl.h +--- firefox-134.0/gfx/skia/skia/modules/skcms/src/Transform_inl.h.aarch64-skia 2024-12-30 19:30:46.000000000 +0100 ++++ firefox-134.0/gfx/skia/skia/modules/skcms/src/Transform_inl.h 2025-01-02 20:51:07.855087265 +0100 +@@ -151,7 +151,7 @@ SI U32 to_fixed(F f) { return (U32)cast - static inline Sk4f SkHalfToFloat_finite_ftz(uint64_t rgba) { - Sk4h hs = Sk4h::Load(&rgba); --#if !defined(SKNX_NO_SIMD) && defined(SK_CPU_ARM64) -+#if 0 // !defined(SKNX_NO_SIMD) && defined(SK_CPU_ARM64) - float32x4_t fs; - asm ("fcvtl %[fs].4s, %[hs].4h \n" // vcvt_f32_f16(...) - : [fs] "=w" (fs) // =w: write-only NEON register -@@ -62,7 +62,7 @@ static inline Sk4f SkHalfToFloat_finite_ - } - static inline Sk4h SkFloatToHalf_finite_ftz(const Sk4f& fs) { --#if !defined(SKNX_NO_SIMD) && defined(SK_CPU_ARM64) -+#if 0 // !defined(SKNX_NO_SIMD) && defined(SK_CPU_ARM64) - float32x4_t vec = fs.fVec; - asm ("fcvtn %[vec].4h, %[vec].4s \n" // vcvt_f16_f32(vec) - : [vec] "+w" (vec)); // +w: read-write NEON register -diff -up firefox-72.0/gfx/skia/skia/src/opts/SkRasterPipeline_opts.h.aarch64-skia firefox-72.0/gfx/skia/skia/src/opts/SkRasterPipeline_opts.h ---- firefox-72.0/gfx/skia/skia/src/opts/SkRasterPipeline_opts.h.aarch64-skia 2020-01-03 09:00:37.538296107 +0100 -+++ firefox-72.0/gfx/skia/skia/src/opts/SkRasterPipeline_opts.h 2020-01-03 10:11:41.259219508 +0100 -@@ -1087,7 +1087,7 @@ SI F from_half(U16 h) { + SI F F_from_Half(U16 half) { +-#if defined(USING_NEON_F16C) ++#if 0 // defined(USING_NEON_F16C) + return vcvt_f32_f16((float16x4_t)half); + #elif defined(USING_AVX512F) + return (F)_mm512_cvtph_ps((__m256i)half); +@@ -178,7 +178,7 @@ SI F F_from_Half(U16 half) { + __attribute__((no_sanitize("unsigned-integer-overflow"))) + #endif + SI U16 Half_from_F(F f) { +-#if defined(USING_NEON_F16C) ++#if 0 //defined(USING_NEON_F16C) + return (U16)vcvt_f16_f32(f); + #elif defined(USING_AVX512F) + return (U16)_mm512_cvtps_ph((__m512 )f, _MM_FROUND_CUR_DIRECTION ); +diff -up firefox-134.0-build/firefox-134.0/gfx/skia/skia/src/opts/SkRasterPipeline_opts.h.aarch64-skia firefox-134.0-build/firefox-134.0/gfx/skia/skia/src/opts/SkRasterPipeline_opts.h +--- firefox-134.0/gfx/skia/skia/src/opts/SkRasterPipeline_opts.h.aarch64-skia 2025-01-02 20:51:07.856087299 +0100 ++++ firefox-134.0/gfx/skia/skia/src/opts/SkRasterPipeline_opts.h 2025-01-02 23:09:47.802283444 +0100 +@@ -1421,7 +1421,7 @@ SI F from_half(U16 h) { } SI U16 to_half(F f) { --#if defined(JUMPER_IS_NEON) && defined(SK_CPU_ARM64) \ -+#if 0 //defined(JUMPER_IS_NEON) && defined(SK_CPU_ARM64) \ - && !defined(SK_BUILD_FOR_GOOGLE3) // Temporary workaround for some Google3 builds. - return vcvt_f16_f32(f); +-#if defined(SKRP_CPU_NEON) && defined(SK_CPU_ARM64) ++#if 0 // defined(SKRP_CPU_NEON) && defined(SK_CPU_ARM64) + return (U16)vcvt_f16_f32(f); -diff -up firefox-72.0/gfx/skia/skia/third_party/skcms/src/Transform_inl.h.aarch64-skia firefox-72.0/gfx/skia/skia/third_party/skcms/src/Transform_inl.h ---- firefox-72.0/gfx/skia/skia/third_party/skcms/src/Transform_inl.h.aarch64-skia 2020-01-03 09:00:37.538296107 +0100 -+++ firefox-72.0/gfx/skia/skia/third_party/skcms/src/Transform_inl.h 2020-01-03 10:11:53.513250979 +0100 -@@ -183,8 +183,6 @@ SI F F_from_Half(U16 half) { - SI U16 Half_from_F(F f) { - #if defined(USING_NEON_FP16) - return bit_pun(f); --#elif defined(USING_NEON_F16C) -- return (U16)vcvt_f16_f32(f); - #elif defined(USING_AVX512F) - return (U16)_mm512_cvtps_ph((__m512 )f, _MM_FROUND_CUR_DIRECTION ); - #elif defined(USING_AVX_F16C) + #elif defined(SKRP_CPU_SKX) diff --git a/build-arm-libaom.patch b/build-arm-libaom.patch deleted file mode 100644 index 985f01d..0000000 --- a/build-arm-libaom.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up firefox-73.0/media/libaom/moz.build.old firefox-73.0/media/libaom/moz.build ---- firefox-73.0/media/libaom/moz.build.old 2020-02-07 23:13:28.000000000 +0200 -+++ firefox-73.0/media/libaom/moz.build 2020-02-17 10:30:08.509805092 +0200 -@@ -55,7 +55,7 @@ elif CONFIG['CPU_ARCH'] == 'arm': - - for f in SOURCES: - if f.endswith('neon.c'): -- SOURCES[f].flags += CONFIG['VPX_ASFLAGS'] -+ SOURCES[f].flags += CONFIG['NEON_FLAGS'] - - if CONFIG['OS_TARGET'] == 'Android': - # For cpu-features.h diff --git a/build-c11-threads-avail.patch b/build-c11-threads-avail.patch new file mode 100644 index 0000000..f627a7b --- /dev/null +++ b/build-c11-threads-avail.patch @@ -0,0 +1,36 @@ +diff -up firefox-146.0/third_party/rust/glslopt/glsl-optimizer/include/c11/threads_posix.h.build-c11-threads-avail firefox-146.0/third_party/rust/glslopt/glsl-optimizer/include/c11/threads_posix.h +--- firefox-146.0/third_party/rust/glslopt/glsl-optimizer/include/c11/threads_posix.h.build-c11-threads-avail 2025-12-05 18:43:20.000000000 +0100 ++++ firefox-146.0/third_party/rust/glslopt/glsl-optimizer/include/c11/threads_posix.h 2025-12-11 13:30:50.463371937 +0100 +@@ -66,7 +66,7 @@ typedef pthread_cond_t cnd_t; + typedef pthread_t thrd_t; + typedef pthread_key_t tss_t; + typedef pthread_mutex_t mtx_t; +-typedef pthread_once_t once_flag; ++//typedef pthread_once_t once_flag; + + + /* +@@ -90,12 +90,13 @@ impl_thrd_routine(void *p) + + /*--------------- 7.25.2 Initialization functions ---------------*/ + // 7.25.2.1 +-static inline void ++// ++/*static inline void + call_once(once_flag *flag, void (*func)(void)) + { + pthread_once(flag, func); + } +- ++*/ + + /*------------- 7.25.3 Condition variable functions -------------*/ + // 7.25.3.1 +diff -up firefox-147.0/third_party/rust/glslopt/.cargo-checksum.json.backup firefox-147.0/third_party/rust/glslopt/.cargo-checksum.json +--- firefox-147.0/third_party/rust/glslopt/.cargo-checksum.json.backup 2026-01-07 12:48:27.390768071 +0100 ++++ firefox-147.0/third_party/rust/glslopt/.cargo-checksum.json 2026-01-07 12:48:29.538659136 +0100 +@@ -1 +1 @@ +-{"files":{"Cargo.lock":"f7970552595dc803ace9ef19b5f5d7b1fc784aac30cb27b2ebc3002d97122b9d","Cargo.toml":"7c53ee20d848f9913cacbfcb3ab2e89e30deee8d619d173c95130c7c5d065827","README.md":"4468e08c64c19977707d792bfab0080e35ff927b64990eab77873f8ba056ba1c","build.rs":"92e29699487c21389fc823c50b410cfbfc74cc774265d24958489909ee48a076","glsl-optimizer/CMakeLists.txt":"42ce94744e82ffa000da8b64d81fc140e293b9f5da7dd4cf6b49e7404a2448d9","glsl-optimizer/README.md":"b18eef11a92d267d88a937b1154f7670ee433c730b102fdf7e2da0b02722b146","glsl-optimizer/contrib/glslopt/Main.cpp":"14ba213210c62e234b8d9b0052105fed28eedd83d535ebe85acc10bda7322dd4","glsl-optimizer/contrib/glslopt/Readme":"65d2a6f1aa1dc61e903e090cdade027abad33e02e7c9c81e07dc80508acadec4","glsl-optimizer/generateParsers.sh":"878a97db5d3b69eb3b4c3a95780763b373cfcc0c02e0b28894f162dbbd1b8848","glsl-optimizer/include/GL/gl.h":"1989b51365b6d7d0c48ff6e8b181ef75e2cdf71bfb1626b1cc4362e2f54854a3","glsl-optimizer/include/GL/glext.h":"2ac3681045a35a2194a81a960cad395c04bef1c8a20ef46b799fb24af3ec5f70","glsl-optimizer/include/KHR/khrplatform.h":"1448141a0c054d7f46edfb63f4fe6c203acf9591974049481c32442fb03fd6ed","glsl-optimizer/include/c11/threads.h":"56e9e592b28df19f0db432125223cb3eb5c0c1f960c22db96a15692e14776337","glsl-optimizer/include/c11/threads_posix.h":"f8ad2b69fa472e332b50572c1b2dcc1c8a0fa783a1199aad245398d3df421b4b","glsl-optimizer/include/c11/threads_win32.h":"95bf19d7fc14d328a016889afd583e4c49c050a93bcfb114bd2e9130a4532488","glsl-optimizer/include/c11_compat.h":"103fedb48f658d36cb416c9c9e5ea4d70dff181aab551fcb1028107d098ffa3e","glsl-optimizer/include/c99_compat.h":"aafad02f1ea90a7857636913ea21617a0fcd6197256dcfc6dd97bb3410ba892e","glsl-optimizer/include/no_extern_c.h":"40069dbb6dd2843658d442f926e609c7799b9c296046a90b62b570774fd618f5","glsl-optimizer/license.txt":"e26a745226f4a46b3ca00ffbe8be18507362189a2863d04b4f563ba176a9a836","glsl-optimizer/src/compiler/builtin_type_macros.h":"5b4fc4d4da7b07f997b6eb569e37db79fa0735286575ef1fab08d419e76776ff","glsl-optimizer/src/compiler/glsl/README":"e7d408b621c1b605857c4cab63902f615edb06b530142b91ac040808df6e22f7","glsl-optimizer/src/compiler/glsl/TODO":"dd3b7a098e6f9c85ca8c99ce6dea49d65bb75d4cea243b917f29e4ad2c974603","glsl-optimizer/src/compiler/glsl/ast.h":"3e68ff374350c49211a9931f7f55a485d8d89fc4b21caaffbf6655009ad95bf8","glsl-optimizer/src/compiler/glsl/ast_array_index.cpp":"92b4d501f33e0544c00d14e4f8837753afd916c2b42e076ccc95c9e8fc37ba94","glsl-optimizer/src/compiler/glsl/ast_expr.cpp":"afd712a7b1beb2b633888f4a0911b0a8e4ae5eb5ab9c1e3f247d518cdaaa56d6","glsl-optimizer/src/compiler/glsl/ast_function.cpp":"74f4fbd490e366b37f4715168bb3465ecd9334d4130942f75dcc8e80e8e7f027","glsl-optimizer/src/compiler/glsl/ast_to_hir.cpp":"d0f798eb09271d41d068b9e7b18220d37f1ed0083300ab51eba30989698fe23d","glsl-optimizer/src/compiler/glsl/ast_type.cpp":"8eb790b24b26dfb72bdc333744b566c26d8464c5d47d20eae659461f5c4899f7","glsl-optimizer/src/compiler/glsl/builtin_functions.cpp":"454189d643c220fcb49116ee5c8a34f7b349aa67564040deb8607f6a41a15e70","glsl-optimizer/src/compiler/glsl/builtin_functions.h":"a37cad7ed09b522c5b8bec7b80115a36846e7ba6e0874a2a858e32f7f202c665","glsl-optimizer/src/compiler/glsl/builtin_int64.h":"619def6f3aebf180da3944ef08f159ab12a58b24767e41d8b985ac37ded54d62","glsl-optimizer/src/compiler/glsl/builtin_types.cpp":"afec060b62d6f3b00bfbf94e9fa5f96341ce096c128d1eef322791e6ed9cea4d","glsl-optimizer/src/compiler/glsl/builtin_variables.cpp":"6563bfb1345cbca4c77e00eef09ad152f3e1dc271d246a08c5ce9e1f4ce4250a","glsl-optimizer/src/compiler/glsl/float64.glsl":"1072fd888be48c2a7a5117cd2d92a65f034965a66375f598bb856bff5d7be766","glsl-optimizer/src/compiler/glsl/generate_ir.cpp":"e5f0175370a0d07f93c48d3f0f1b8233d12c64a7b02de02dcc753ef7b398ef0f","glsl-optimizer/src/compiler/glsl/glcpp/README":"a0332a1b221d047e9cce5181a64d4ac4056046fd878360ec8ae3a7b1e062bcff","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-lex.c":"2d179879b1ffe84f58875eee5b0c19b6bae9c973b0c48e6bcd99978f2f501c80","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-lex.l":"e4c5744c837200dafd7c15a912d13f650308ea552454d4fa67271bc0a5bde118","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-parse.c":"03494f9ce1cb82260506e2559e73a3eeb622c4bd51b65eaa0a2c3351862bd4c8","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-parse.h":"264d9a18421cde255ce34a0a62b3d8e73465359f0d167e64aa3973062aae5bdd","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-parse.y":"fafb66e3a8f149d19e085f18a4273ba6d4c11af9e9a01d665cc784dddf97b79f","glsl-optimizer/src/compiler/glsl/glcpp/glcpp.c":"37ed294403c2abfd17fd999d1ae8d11b170e5e9c878979fefac74a31195c96b0","glsl-optimizer/src/compiler/glsl/glcpp/glcpp.h":"85ac8b444bcbd0822b66448a1da407b6ae5467b649f5afaf5c58325bd7569468","glsl-optimizer/src/compiler/glsl/glcpp/pp.c":"a52d94f1bcb3fb2747a95709c4a77c25de7eea8354d2b83bb18efd96976a4473","glsl-optimizer/src/compiler/glsl/glcpp/pp_standalone_scaffolding.c":"d11aeb3acfe966d1b78f1ee49804093f2434214c41391d139ffcb67b69dc9862","glsl-optimizer/src/compiler/glsl/glcpp/pp_standalone_scaffolding.h":"abbf1f36ec5a92d035bfbb841b9452287d147616e56373cdbee1c0e55af46406","glsl-optimizer/src/compiler/glsl/glsl_lexer.cpp":"272b9fc1383d72b81bfc03fa11fdf82270ed91a294e523f9ce2b4554bd3effa9","glsl-optimizer/src/compiler/glsl/glsl_lexer.ll":"2b57d9f9eb830c3d7961d4533048a158ee6f458c8d05c65bea7b7cfbc36e4458","glsl-optimizer/src/compiler/glsl/glsl_optimizer.cpp":"f8095d20629d0af70be930b0612e169edb274551a1d25a3cd1bf9995a11ce2e8","glsl-optimizer/src/compiler/glsl/glsl_optimizer.h":"22e843b4ec53ba5f6cd85ca5f7bad33922dca8061b19fb512d46f1caca8d4757","glsl-optimizer/src/compiler/glsl/glsl_parser.cpp":"126baf368d525aba301854e3d91ba60b5aee32e1102376af71416f32cb95ec48","glsl-optimizer/src/compiler/glsl/glsl_parser.h":"2ea9a50716098a8f7bef782d2a030d757b68da73afb01b4d4940d3e8381d44e8","glsl-optimizer/src/compiler/glsl/glsl_parser.yy":"6b1fd1576b29fce005dff744a6dbd0219e4c695c361d61864e1f3a8d6fa6b764","glsl-optimizer/src/compiler/glsl/glsl_parser_extras.cpp":"aad64b5b66467da650091430681e8c6a820cf3cadc4db3c160bf2f15875390ae","glsl-optimizer/src/compiler/glsl/glsl_parser_extras.h":"71fd0e92bbdb193dfb067d7bfdb1200d77392be2fbd0cbfc9ca89d1bb4c7e741","glsl-optimizer/src/compiler/glsl/glsl_symbol_table.cpp":"6660fb83c0ddddbbd64581d46ccfdb9c84bfaa99d13348c289e6442ab00df046","glsl-optimizer/src/compiler/glsl/glsl_symbol_table.h":"24682b8304e0ea3f6318ddb8c859686bd1faee23cd0511d1760977ae975d41bf","glsl-optimizer/src/compiler/glsl/hir_field_selection.cpp":"72a039b0fcab4161788def9e4bedac7ac06a20d8e13146529c6d246bd5202afd","glsl-optimizer/src/compiler/glsl/int64.glsl":"303dbe95dde44b91aee3e38b115b92028400d6a92f9268975d607471984e13eb","glsl-optimizer/src/compiler/glsl/ir.cpp":"2b4741cce90b5d4abff5d719c7324e2693c67294d4d99736cb241554adb281bc","glsl-optimizer/src/compiler/glsl/ir.h":"990b1c74447c4eb4835353ccb0ed9aea644f97fc1129ef1739cd935075d85d2e","glsl-optimizer/src/compiler/glsl/ir_array_refcount.cpp":"8cdc1cffe01e42e0566fa2193a75f789628e8025ad1b82f0ee6f204451b7f9f7","glsl-optimizer/src/compiler/glsl/ir_array_refcount.h":"75f06ec81342b379096ca52e1dc0fd5f19a11ff8e9b58203c20628179d644c12","glsl-optimizer/src/compiler/glsl/ir_basic_block.cpp":"1e2920b1c0ecb08424c745c558f84d0d7e44b74585cf2cc2265dc4dfede3fa2f","glsl-optimizer/src/compiler/glsl/ir_basic_block.h":"81be7da0fc0ee547cd13ec60c1fcd7d3ce3d70d7e5e988f01a3b43a827acdf05","glsl-optimizer/src/compiler/glsl/ir_builder.cpp":"daba29c5a1efdd5a9754f420eb3e2ebdf73485273497f40d4863dadeddb23c0d","glsl-optimizer/src/compiler/glsl/ir_builder.h":"2822e74dd3f6e3df8b300af27d5b11ea2dd99d0e5e7ca809b7bbcce9833c483c","glsl-optimizer/src/compiler/glsl/ir_builder_print_visitor.cpp":"8c6df5abf2fe313363f285f171c19ca6c8ee4f3bc2ed79d33c0c88cc8be45c48","glsl-optimizer/src/compiler/glsl/ir_builder_print_visitor.h":"799852adc3a0e54d04080655e7cebfa0d3bf5b6ffed5d8414f141380665d4db7","glsl-optimizer/src/compiler/glsl/ir_clone.cpp":"d897a4e1f5bbec4a6a2f15044c1be9a4d13899c73be77335b041049a4589aa5d","glsl-optimizer/src/compiler/glsl/ir_constant_expression.cpp":"78bd87ddb09db67f6c499067728d72aef4f16aa02721a99a4b769d1e0cfa9010","glsl-optimizer/src/compiler/glsl/ir_equals.cpp":"bca28533a6310b0fc152b56d80872368f1510dc62ed6e8ac199b9ffa7fac02e7","glsl-optimizer/src/compiler/glsl/ir_expression_flattening.cpp":"7e918d4e1f237eca01396004015865ce345afe32a876c9dbc6728576a1a7eae4","glsl-optimizer/src/compiler/glsl/ir_expression_flattening.h":"f45b66aa9497520e7e08e612d24b308477c34477fbd963ee9320eac664957f16","glsl-optimizer/src/compiler/glsl/ir_expression_operation.h":"cc9f10727dbd26cac506804f51456302c702650f9eeb59054a7e1575d5cf6687","glsl-optimizer/src/compiler/glsl/ir_expression_operation.py":"7b86c96021b9fbe165957f4ecb0b612fefcde1c2cf3c6d75e3cdb22e369216ba","glsl-optimizer/src/compiler/glsl/ir_expression_operation_constant.h":"9ad3346416392e3efa11e12ecf2feca7453c5253d241eb96c91dfb85d4f2b971","glsl-optimizer/src/compiler/glsl/ir_expression_operation_strings.h":"a6826daf496a8b9e89885bc2a161ac3445d501b23c6e0ac33e2c01b506b273c8","glsl-optimizer/src/compiler/glsl/ir_function.cpp":"7537365fc0fbe4b37a26b9a2146cc64d3e9a774d60eab63b65002ad165ae8fc7","glsl-optimizer/src/compiler/glsl/ir_function_can_inline.cpp":"faddbf112187a048d502716a3fb82570a322299ba2a3abd79388382c82040bfc","glsl-optimizer/src/compiler/glsl/ir_function_detect_recursion.cpp":"9176973eaf5c0a984701f953bb7a80f37dca43d59b5bce50fc69b3f02f2902d7","glsl-optimizer/src/compiler/glsl/ir_function_inlining.h":"9739493f99c489987d650762fccdd3fb3d432f6481d67f6c799176685bd59632","glsl-optimizer/src/compiler/glsl/ir_hierarchical_visitor.cpp":"3725861fbe2b98e0617f52d3b14cf6d3b25fb5ec00f5ef5d308b03642f592767","glsl-optimizer/src/compiler/glsl/ir_hierarchical_visitor.h":"e0560210e966c0c31e4ca843e80ea154e64db5a444b8c2df845b6ba5b3a43fc1","glsl-optimizer/src/compiler/glsl/ir_hv_accept.cpp":"caf7ce2cd9494aadd3c58bcf77f29de58368dc9e347a362bbf37f8bda9509b80","glsl-optimizer/src/compiler/glsl/ir_optimization.h":"8b3dcfc7f9e96b21a8dd47a0040d90be483a9e67a2cdce3a697188fb758d4630","glsl-optimizer/src/compiler/glsl/ir_print_glsl_visitor.cpp":"f8e34a983452be0dcb5a695e9c8e895eead24f9e540992a8afe510ae85da4c4c","glsl-optimizer/src/compiler/glsl/ir_print_glsl_visitor.h":"1ad1bd3efd1ace39051c13f904c05fd80425d329444f9a8d47fd6d948faf46e0","glsl-optimizer/src/compiler/glsl/ir_print_visitor.cpp":"643f5a68aae3fb37267fd793f1216d1cfdeb2c09338c26b1f30e4c6deaef4de5","glsl-optimizer/src/compiler/glsl/ir_print_visitor.h":"4573eb93268a2654c14b505253dd651e2695d43dc745904d824da18305269b95","glsl-optimizer/src/compiler/glsl/ir_reader.cpp":"06bfba802c8354e5a8b2334b6d78d6297de18235bedd3f8fbb382c89870b02f2","glsl-optimizer/src/compiler/glsl/ir_reader.h":"63e3f7f1597936a7011d5b520e171b197bf82bee6c1560d822c3edf5aaa6f9e9","glsl-optimizer/src/compiler/glsl/ir_rvalue_visitor.cpp":"84b5c5d746555adca85759c2912fe48010232b7c1c0bd2cf03bd04067a85e66f","glsl-optimizer/src/compiler/glsl/ir_rvalue_visitor.h":"fd8c561b71085d3211fff85ed514fecb299d8ce19a04bc063419a55b6d840525","glsl-optimizer/src/compiler/glsl/ir_set_program_inouts.cpp":"ab9f115ce9e7f312d9c7978340ced0dc4ae6d13a80e08442ba9709d11d50cae5","glsl-optimizer/src/compiler/glsl/ir_uniform.h":"683ae6896b1a08470c090be5f822fc31cd434eab9216e954b9bba24a46975109","glsl-optimizer/src/compiler/glsl/ir_unused_structs.cpp":"9c1620c45f2fc071fe5ed828472040b14c5f42effe06aa0e3b8352c95ef78786","glsl-optimizer/src/compiler/glsl/ir_unused_structs.h":"13387b49c23093575276b25b9dfd31fedd8f131c5c4f3128ab04cf03e15b5295","glsl-optimizer/src/compiler/glsl/ir_validate.cpp":"6b232be5999a86ea278f4f15b2832d76843246509118d924243055a3b9b0299f","glsl-optimizer/src/compiler/glsl/ir_variable_refcount.cpp":"2764a3cad937d53f36db7447c3a5b98b04bf153acf81074d971857fc5bca460d","glsl-optimizer/src/compiler/glsl/ir_variable_refcount.h":"b0668e3eb1501ef65e38fe12830742ecb3d28e6039f30e366c8924efc29b4a39","glsl-optimizer/src/compiler/glsl/ir_visitor.h":"f21b3534c3d66d5fb707d1581fece7e1eb043523afbaedf89918cfb031c6df94","glsl-optimizer/src/compiler/glsl/link_atomics.cpp":"360f0209e11f367ba358223597b0a118bae095bff16337cf03f1fb89c5b80ca6","glsl-optimizer/src/compiler/glsl/link_functions.cpp":"de7895da8aa33a1e3c2c1eb2fdaf267ab5d1fbfdb79ae2e67f95211e946e294c","glsl-optimizer/src/compiler/glsl/link_interface_blocks.cpp":"1926cfa73810704eb19b916c1b2cdb9321155e2f98b2a0a57c7c3c6e960540cd","glsl-optimizer/src/compiler/glsl/link_uniform_block_active_visitor.cpp":"1e14e06ca3b2c1089cfba2e8eaf0c1f373d9d6374b6082f320962dd71ae09611","glsl-optimizer/src/compiler/glsl/link_uniform_block_active_visitor.h":"fd58c155af645295bb6aec08797889de586f4d919731de2bce57e8dce59bb048","glsl-optimizer/src/compiler/glsl/link_uniform_blocks.cpp":"09589f49776dce32e6c4044937de7e0c839a9754ad31960148f8f9e010658997","glsl-optimizer/src/compiler/glsl/link_uniform_initializers.cpp":"bf98e08c12db466acf9623cbeb8fa8e3b4002512722e7a6521287f558a099f37","glsl-optimizer/src/compiler/glsl/link_uniforms.cpp":"84bad5b1377362cecf259b05124239be5220b03ce1c0c61b59bd9a47e4379af2","glsl-optimizer/src/compiler/glsl/link_varyings.cpp":"a5f1a53e7c80d635515fe808ff223d89fef1767abb0f2b7aa28fa6773dca353f","glsl-optimizer/src/compiler/glsl/link_varyings.h":"b9dbe018f038df69763df2e928742ce81bbc6e3aaba26f50621e30a6d9aa6220","glsl-optimizer/src/compiler/glsl/linker.cpp":"40b1ecd5d4f6c7f13d5a87ce390561a51fdf6f3fcd9b2197b9c88b03a773ba94","glsl-optimizer/src/compiler/glsl/linker.h":"ecf94b4ad75ef461c27c557fda4bd25f34c91930822b8e1d729ec84520d4a049","glsl-optimizer/src/compiler/glsl/linker_util.cpp":"1663ad88e2a369305659aeeffaedb5bd752cf76340a2ba5797fc0bf600633cf9","glsl-optimizer/src/compiler/glsl/linker_util.h":"6db788daf9c8e87ae2764b61a8b37ebe419e69c1b82ddee01986e37c978c6993","glsl-optimizer/src/compiler/glsl/list.h":"b1f46ce0e552fe7c45b2a19408a9d97662e23e4b182ab335491c26f8cf25886f","glsl-optimizer/src/compiler/glsl/loop_analysis.cpp":"57ecd573477c68091c7cc99537faa7139a8f395935e3d4f10144cefdefb5a611","glsl-optimizer/src/compiler/glsl/loop_analysis.h":"a85f045a038ee5b5176063e85d7988865862c44ab0580f771b993a042d0b69cc","glsl-optimizer/src/compiler/glsl/loop_unroll.cpp":"bd4292ea2809f5a669bcb76ceaa1ac365772dcd638c579c3ed10275214901a54","glsl-optimizer/src/compiler/glsl/lower_blend_equation_advanced.cpp":"8cfbef140d9c4b4d2f57bfa05c9c374d31a121d0f87afce94333f049023b654a","glsl-optimizer/src/compiler/glsl/lower_buffer_access.cpp":"1ae221c3c7a95aeb867207e7a742be635f91b406c157747bfd6ddf10274d97fb","glsl-optimizer/src/compiler/glsl/lower_buffer_access.h":"807886953a576a323591798cbca5e2df24295ea893b28affd8ffb5926cebaa04","glsl-optimizer/src/compiler/glsl/lower_builtins.cpp":"4d81afc32cf58e1481fcb5e42888ab93dbe6820310a20ff7a9982b77b2152d9b","glsl-optimizer/src/compiler/glsl/lower_const_arrays_to_uniforms.cpp":"608403f0eeeedf21cfcd3014116e0f44e28cbdf6c4c32aac7e613e64e30205e1","glsl-optimizer/src/compiler/glsl/lower_cs_derived.cpp":"179905cd47a294122adeb5b0abfed6f2f67782dcde21b544d1ee2c1985154e66","glsl-optimizer/src/compiler/glsl/lower_discard.cpp":"3b361b2db0004d544d64611cb50d5a6e364cf6c5f2e60c449085d7d753dd7fb0","glsl-optimizer/src/compiler/glsl/lower_discard_flow.cpp":"f5c29b6a27690bb5c91f196d1a1cf9f6be4f1025292311fe2dac561ce6774dee","glsl-optimizer/src/compiler/glsl/lower_distance.cpp":"a118c85493d5d22b2c059a930c51a5854896d4b1dade76598eaa985e5a3dff8c","glsl-optimizer/src/compiler/glsl/lower_if_to_cond_assign.cpp":"469e617757fd1728709cce021aac5c8da05ee503bf5366977bdc4ef7a6d83950","glsl-optimizer/src/compiler/glsl/lower_instructions.cpp":"6ff5c396abe40d8a2145d571e99e2bbe9143393e15aafc28adc2803a01d821b6","glsl-optimizer/src/compiler/glsl/lower_int64.cpp":"d1ed41196880dd53c7b13e2782f9423f8442bf1d46186e8be92b1b66218a83ee","glsl-optimizer/src/compiler/glsl/lower_jumps.cpp":"34de7b493f281589fb0c2c0f6e885d0a0fabbe7a4e97a73de374dd714777a58c","glsl-optimizer/src/compiler/glsl/lower_mat_op_to_vec.cpp":"dff7a308edc4846c348ed4225c6699a9c75abac68d88f41f85954276552779f4","glsl-optimizer/src/compiler/glsl/lower_named_interface_blocks.cpp":"16063ac127bff75a68272070ab11c21c25101edbff62b4c68f4983b4cd941af0","glsl-optimizer/src/compiler/glsl/lower_offset_array.cpp":"3b00773399135aea85746a5a68b96ef000bc6841be1a2c8e6f25c516628b0949","glsl-optimizer/src/compiler/glsl/lower_output_reads.cpp":"a0fc9975d5aa1617e21fc6c353659a9802da9e83779a3eef4ec584f74b4dadc5","glsl-optimizer/src/compiler/glsl/lower_packed_varyings.cpp":"7550099d4ae123d71541c2fc88bc04fbfe9271ec75d7e210987d1c8cac3cf3ea","glsl-optimizer/src/compiler/glsl/lower_packing_builtins.cpp":"79a13d161fe505a410ab948d92769395708693ec888153630fa240e5b97e356f","glsl-optimizer/src/compiler/glsl/lower_precision.cpp":"f82a185b879872b977a1787d8061b9a80bc4cf8db1b970db6efba2ad9cc20fa2","glsl-optimizer/src/compiler/glsl/lower_shared_reference.cpp":"ea2dccf50a83bc19391bf6b7ab6aa53c0005f427af4066d25140340af9a4beef","glsl-optimizer/src/compiler/glsl/lower_subroutine.cpp":"f69fa53650eeb6f2944fce4d36a6e0a423e6705f3a3bd3389c7fadb83cfc8802","glsl-optimizer/src/compiler/glsl/lower_tess_level.cpp":"b196c9d424c0569f3e85d75c2d125af21566cb113d69036db87c0990703e0fa7","glsl-optimizer/src/compiler/glsl/lower_texture_projection.cpp":"4d247f244272adc8250fd888d8d932a140dd5de4d1efc7a58492c3c2b8291527","glsl-optimizer/src/compiler/glsl/lower_ubo_reference.cpp":"89bdbc6c1669230c644c0857db1ce2781ec61d349ecd08c7914146e1f4750a4a","glsl-optimizer/src/compiler/glsl/lower_variable_index_to_cond_assign.cpp":"fce930f29ac9405b297d1f749d68f59506b89c70b4ee1b1ab8cf49a34cc71ecf","glsl-optimizer/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp":"3c67d851a11a55fad1c49a550f3a0cfe50892d33a3f238ce266cd829eba510a8","glsl-optimizer/src/compiler/glsl/lower_vec_index_to_swizzle.cpp":"f5ec666b73e1415cbab32519a53605ed385f3b03e889560373dbce69dda5000e","glsl-optimizer/src/compiler/glsl/lower_vector.cpp":"f7c13f5572ebe09b6a71553133b2cf003cd4b77b9657600672ee3b21bf890725","glsl-optimizer/src/compiler/glsl/lower_vector_derefs.cpp":"b05793da6dd620a531b43df5af8b2ecbc37b9db0c88910f5724ea10bcd057e19","glsl-optimizer/src/compiler/glsl/lower_vector_insert.cpp":"fee772ec17eea5e86a529bf9c5fa2ee0d29a5982bb75ebc6d68ed36cd19aa299","glsl-optimizer/src/compiler/glsl/lower_vertex_id.cpp":"690e8715182e03fead5cc5a35251fb4f41b357e4c71a1dfbc4bd7be19862b56d","glsl-optimizer/src/compiler/glsl/lower_xfb_varying.cpp":"58c0e8b270e4bbde54250be03cdb2f36966bcafb785372ad2e2b786835df7f9f","glsl-optimizer/src/compiler/glsl/main.cpp":"ae5e88abbbc8a12f769e1296bad938b9d7398cc6da0d3d0caeceeeb876536850","glsl-optimizer/src/compiler/glsl/opt_add_neg_to_sub.h":"f5054944bfd068810629080d0ea11df78b3f57a8f86df75e13ca50157ad1964d","glsl-optimizer/src/compiler/glsl/opt_algebraic.cpp":"25f45b20e1972ee8c789177a1aeda6e4286c25db2eae3a43ff83029ae64969c0","glsl-optimizer/src/compiler/glsl/opt_array_splitting.cpp":"19d3ce0e815438f4df9ab2890e767b03a4f3f191b53bb30c0217cf2ae6a95430","glsl-optimizer/src/compiler/glsl/opt_conditional_discard.cpp":"0e44e0e126711a3725c1f3a2aa65ff03c381fed08680ffc30101aae60f716c4e","glsl-optimizer/src/compiler/glsl/opt_constant_folding.cpp":"a088d04d9b45f9e55e235835648f614c89b7803c03a6d4f6a6d1a6bc1f0228bd","glsl-optimizer/src/compiler/glsl/opt_constant_propagation.cpp":"8a9440d77ecd6dcf13e683cbb99943aab6311c8fd4b5f6a9189a8d4f270746f4","glsl-optimizer/src/compiler/glsl/opt_constant_variable.cpp":"63d3ccd4dd09f19c9cf1a2f51592111bed41284504f29f3c0de4cadebc439a37","glsl-optimizer/src/compiler/glsl/opt_copy_propagation_elements.cpp":"ffa0f50863995e0d2e31f55a52e82319edc71e520987bebd7f7e561ea331c64b","glsl-optimizer/src/compiler/glsl/opt_dead_builtin_variables.cpp":"84e8747b948232f01dd56b428b9315f96f9511f605f240119fc446fae28981a9","glsl-optimizer/src/compiler/glsl/opt_dead_builtin_varyings.cpp":"761523e88f5b3ba785170f4d7205e94fa99acb7e74d29efbe40e1c010e1dbdb3","glsl-optimizer/src/compiler/glsl/opt_dead_code.cpp":"fd1ba2da7337d4e5dad17f5c2d73d9cc8880305f423e85d64cf94553588fa401","glsl-optimizer/src/compiler/glsl/opt_dead_code_local.cpp":"969a598b4df322baf222258a66cd64a326ea20e5b3125be9d8d1771f522c69e0","glsl-optimizer/src/compiler/glsl/opt_dead_functions.cpp":"774cae6536d02edf26e996a2a895e1f62d5098f16dc96b44798b4fc731a9a95f","glsl-optimizer/src/compiler/glsl/opt_flatten_nested_if_blocks.cpp":"3696a5c55f02e20056e085bc2714f73ac992f221b6f3387d655068e86b512046","glsl-optimizer/src/compiler/glsl/opt_flip_matrices.cpp":"44f0fe05b49329667671f88c96dc86ab3fe1459ff7b87f2b2d88de2d49829f9f","glsl-optimizer/src/compiler/glsl/opt_function_inlining.cpp":"fb56a33c90419a01676b57cbd91d0674a54cca40e6defaacc88dd33facebc131","glsl-optimizer/src/compiler/glsl/opt_if_simplification.cpp":"ac406eb35e379c357641d6c5749f50c65961455924d3dc884e2b90046fa92c5c","glsl-optimizer/src/compiler/glsl/opt_minmax.cpp":"8abd59d3b14ef60ff14a9c69660e6945f5cf10b97edb4afebe56be3f81d96316","glsl-optimizer/src/compiler/glsl/opt_rebalance_tree.cpp":"8bb6329dc0f299042368fc81934c2df019b45ab9f7aa0415d4e57b8d1ff98c9f","glsl-optimizer/src/compiler/glsl/opt_redundant_jumps.cpp":"222c73e2ac7a938ebb6428cc6c780c908ff6156d8ff935b04fed93a48fc10496","glsl-optimizer/src/compiler/glsl/opt_structure_splitting.cpp":"2edc79cc13f3177934e0443ad62f5976a1991f01f86ea303a803434849b13a47","glsl-optimizer/src/compiler/glsl/opt_swizzle.cpp":"015d0abddfe507f67c4b96c82988d861d018ededf7bf055e2bcbe9ea92da694e","glsl-optimizer/src/compiler/glsl/opt_tree_grafting.cpp":"46d28ac983ea244a4315bdc0e8892979ec4d1f9b9a96ac8a8a08006d9bc5e878","glsl-optimizer/src/compiler/glsl/opt_vectorize.cpp":"d80ee43bb97d9f016fb9c5e1e06f5b2afa569811f368ba067be794ec11d085fb","glsl-optimizer/src/compiler/glsl/program.h":"2982447e2abd35371e273ad87951722782a8b21c08294f67c39d987da1e1c55f","glsl-optimizer/src/compiler/glsl/propagate_invariance.cpp":"080943e21baa32494723a2eefb185915d2daae1f46d6df420145c5ad6857e119","glsl-optimizer/src/compiler/glsl/s_expression.cpp":"1ced972bc6ecc8eab4116ea71fb0212ab9ae5bcc0be3b47aa5d9d903566b3af1","glsl-optimizer/src/compiler/glsl/s_expression.h":"65b847e30e22a809b57d0bc70243049c99d9c6318803c5b8d0826aba55dc217e","glsl-optimizer/src/compiler/glsl/serialize.cpp":"be0eb4251348a9d921acb839a5c48c6023a2e9d116d602bb0432787ab623655d","glsl-optimizer/src/compiler/glsl/serialize.h":"57425732eba1233d928e5f07f88b623ce65af46b3bb034bf147f0a4b7f94f9a1","glsl-optimizer/src/compiler/glsl/shader_cache.cpp":"e0c5c433f2df3fccdf1d61281bfcb0ee5633433339b97c697d64db99611cbaaf","glsl-optimizer/src/compiler/glsl/shader_cache.h":"9217164d8d7f54aca0fe5922c7187095a6ae0cb703b196b79805aeef07a7e697","glsl-optimizer/src/compiler/glsl/standalone.cpp":"8e6c416a14d631261917a5fe4cc91880c287b22b2dfd70eb22028289a8fa5364","glsl-optimizer/src/compiler/glsl/standalone.h":"a7c397d1dfdd1e7fb2cfe99db35cd9df93251e642059208533202b7f20497f83","glsl-optimizer/src/compiler/glsl/standalone_scaffolding.cpp":"970d14b7a9d58e5270321f97bf5d57795558b1c570a56678e04a65b26c60bf4f","glsl-optimizer/src/compiler/glsl/standalone_scaffolding.h":"d921a617ea82b9e49413314492a645c44356de503581b1be3f1b57de236e480d","glsl-optimizer/src/compiler/glsl/string_to_uint_map.cpp":"d824bf5b839bd39498dc9e457103cdbe3e5289ddf7564107c27b1505948dd31f","glsl-optimizer/src/compiler/glsl/string_to_uint_map.h":"e2f18e66359c9d620e085de7f4a334a47df9c66e65a5bfe8b734c627bec04104","glsl-optimizer/src/compiler/glsl/test_optpass.h":"b27b8f35f5387e7ce4982bb51c7b63ccf14f91757f3108a5d02ed006925bb8a0","glsl-optimizer/src/compiler/glsl/xxd.py":"376484142f27f45090ea8203ae2621abf73f06175cb0ee8d96f44a3b9327f4bd","glsl-optimizer/src/compiler/glsl_types.cpp":"044bb6754f45419a3151e7a25c39202a82009ae3c6bc54ff7f0bb4258a5deefe","glsl-optimizer/src/compiler/glsl_types.h":"fd899a42f34ddeb8601bc3cd6c5e3aed82fc8aef4042dde1b39b3c01e1dcc219","glsl-optimizer/src/compiler/shader_enums.c":"436bff5216b11b0980bdfada5885fc6ac9afa2037a3027fcd6eea2a8635597ac","glsl-optimizer/src/compiler/shader_enums.h":"13220442a5c02e83540cf2c0ad4f8417b2fbda5f2586dec4e92082544c937cdd","glsl-optimizer/src/compiler/shader_info.h":"4c5453e81197ca83593ee4f365074b23530f2ab21c78e1733b63dec6f344c12a","glsl-optimizer/src/gallium/auxiliary/util/u_half.h":"3c2b37bda3ccb64387e44b723d29cf9046decab1a893bf42d842e9603398bdee","glsl-optimizer/src/gallium/include/pipe/p_compiler.h":"c75620096ce8523dae90599e50aa2ef6468d3b0e368a77795edeb20dd1abfc0c","glsl-optimizer/src/gallium/include/pipe/p_config.h":"a27692fc35f9e55df3224b7529e66b3001e911e94e6bc5f8f569e493e1ee3fb7","glsl-optimizer/src/gallium/include/pipe/p_defines.h":"be26d68c0acc67c5e44788c6299716a9eee415fd81d7d747e3738a829e3b6b38","glsl-optimizer/src/gallium/include/pipe/p_format.h":"5674215fc41d27496f037cf837717daefbf23ebb38d40ace7c0c414bc08182b0","glsl-optimizer/src/gallium/include/pipe/p_state.h":"d600593aba5f5a17072a6c38f6baa81e01c7994b0174250f7e433bb41684b702","glsl-optimizer/src/mapi/glapi/glapi.h":"73632a625c0ddabc401205e8b5a81eb8af8506868efe4b170d7979ec3619e9c5","glsl-optimizer/src/mesa/main/config.h":"5800259373099e5405de2eb52619f9de242552a479902a3a642a333c8cb3c1e7","glsl-optimizer/src/mesa/main/context.c":"2f3208473d99c94f734b1137ba91889d4a1babb9e7534bf1dc85d851ee98274e","glsl-optimizer/src/mesa/main/context.h":"cc7e4194797db9d007f01884e23d786c453b3860821f7f2ddcdf0f1bf3f8ffb1","glsl-optimizer/src/mesa/main/dd.h":"6a964acd06b6c2d88700e69fb75fe3c6b3b3d45bbc41db24f3f897a29695fe0c","glsl-optimizer/src/mesa/main/debug_output.h":"7312422e90b8c0e34028ac27280e438139b5cba525c99deb3ac883cd3d87e452","glsl-optimizer/src/mesa/main/draw.h":"7eaef3a9e27a60ea6f7937109bf3a6190b831162fde0479abb12077ce27c353d","glsl-optimizer/src/mesa/main/enums.h":"87d562a6764f51c014a2274fa7c3aca17c04441537ddd56b2554f13c6fffea92","glsl-optimizer/src/mesa/main/errors.h":"c79444b5df289c90fbb22a33b2d0c23917d9fc4510960088f0b79e53bb56b1b2","glsl-optimizer/src/mesa/main/extensions.h":"a38b2f87cc93c513994281350d69e06c84ff8eded5313ec0a1be33f375e0ebbd","glsl-optimizer/src/mesa/main/extensions_table.c":"17642d1a8c9a0bf2bd61060052d33ff14a005d2b962e6cf91465797a50851e85","glsl-optimizer/src/mesa/main/extensions_table.h":"2c879571c238d2e14461031ac740372fd0f9ac3a34c0d5541bb9b7ed4c0376c8","glsl-optimizer/src/mesa/main/formats.h":"02e2f7ec3e39286cf9f27e2641043e6df8ecb1dfde9e643313210e214af2a929","glsl-optimizer/src/mesa/main/glheader.h":"58217b33eead6aa6b23cd4a291cefeaa6cb84e465f4960daffca97c44d6d1c35","glsl-optimizer/src/mesa/main/glthread.h":"51fb2711f77e7eafcfc52d29d5b844978832b24c930d88accd48d143a6eb9c6f","glsl-optimizer/src/mesa/main/hash.h":"7e7f782034c16a8e693de48e00c31d4a90b0129f4029fd074033d7d16ccbe718","glsl-optimizer/src/mesa/main/macros.h":"73d15ddfd64f2b57b9b2ffeeb993b9c2c0899a80563e9d6ff337b11ccbe6eee5","glsl-optimizer/src/mesa/main/menums.h":"5dfac0e2279d60b0cd0c7b9fc2a5021620d0f6282ed2e738c420214e3af152d3","glsl-optimizer/src/mesa/main/mesa_private.h":"edda678b93438944279a551f663b8858ad84814a9fc88ba9672ef195599c24ae","glsl-optimizer/src/mesa/main/mtypes.h":"6efddefa099e4d2e3fdd97f0055644f47aba21711385edfeabc2d9b0676f2eec","glsl-optimizer/src/mesa/main/shaderobj.h":"9f0dfe96d0c2154201adef942bd36053533ac7b2492fb3786acda5bea514c75e","glsl-optimizer/src/mesa/main/uniforms.h":"4e331e6ad6e9cbded978b4082dbe0a57c1f8f01327446bb6892bfc179976c38b","glsl-optimizer/src/mesa/main/version.h":"9d0a13a758099302dc55cf7d045791834a89b0f9d4cf17b2692259b369a8a9a1","glsl-optimizer/src/mesa/math/m_matrix.h":"a37b19f182e070db3df93b0ede43c22fb8be8c2906504133ee6dbd7db1185d8b","glsl-optimizer/src/mesa/program/dummy_errors.c":"1820e305515b4c5e041f5e1623266a48ec8f076a155310be7d60637101f593e4","glsl-optimizer/src/mesa/program/ir_to_mesa.h":"b47f58d22e3ca2ae42d52501ea769d15c4476834944fa97eeccd3a3439211d00","glsl-optimizer/src/mesa/program/prog_instruction.h":"ab3832152a7e144b59e5a2264b2c29db56d93be31e76bbd958527a56771b40eb","glsl-optimizer/src/mesa/program/prog_parameter.h":"ba18c743284eadbc837c2c364c73e5d372321a7637a76e589d8d39fe8b5de225","glsl-optimizer/src/mesa/program/prog_statevars.h":"fc413698f84bc52d45fdeae0471934ee9904bfb7eac1a2b5f70446e54bcbbdca","glsl-optimizer/src/mesa/program/program.h":"1f01026a4eff440a3f122fd9b519d03546fe7f7d8be60dca834e95a2f8fbbfd2","glsl-optimizer/src/mesa/program/symbol_table.c":"6611cb9f078035bf5ff8c9112093a6c7d99f8af99a3931d0c07f227cc72283ea","glsl-optimizer/src/mesa/program/symbol_table.h":"631dc35ac48d5e87962d45507461920f6575610960ffcc42a08cefeb43300cda","glsl-optimizer/src/mesa/vbo/vbo.h":"6eb1dcd9a08c92f276c5fe08da184ff9d455d1be421913b8ad732a7b65e858fb","glsl-optimizer/src/util/bitscan.h":"9e49e694e6b34fe035bc685f32588827eb8cbe7d82878963c7ab52843e1c16aa","glsl-optimizer/src/util/bitset.h":"c40f78515c6230fed18345c6751ce33833a49da7a27901c7e6d7340cbdcbc5e7","glsl-optimizer/src/util/blob.c":"8f729846f66efc9c15485cc5fc24c6ec861fc1fecb2f652573f2a237d481b791","glsl-optimizer/src/util/blob.h":"93e1eaac866b9a7cd6fc03b533c18fb2edf0e97f03395eff4f3a605c4fc14d0c","glsl-optimizer/src/util/compiler.h":"79e3bf40a5bab704e6c949f23a1352759607bb57d80e5d8df2ef159755f10b68","glsl-optimizer/src/util/crc32.c":"2f3467a046b3a76784ecb9aa55d527698c8607fd0b12c622f6691aaa77b58505","glsl-optimizer/src/util/crc32.h":"59bd81865e51042b73a86f8fb117c312418df095fed2d828c5c1d1c8b6fc6cd4","glsl-optimizer/src/util/debug.c":"c3d68e9752ccc19e66c669562cd113cf1d0ac83cbb30174789e7fb8d1df58f9c","glsl-optimizer/src/util/debug.h":"50068d745c4199ccbd33d68dd4c8a36d2b5179c7869a21e75906ddd0718ca456","glsl-optimizer/src/util/detect_os.h":"343a8790d17a3710c6dd015ee367f84e3902ff3f2e36faca2bf93f9d725d3574","glsl-optimizer/src/util/disk_cache.c":"f533937e5a4fffe76e2739ef4b6b1e1da097d96d63eb808e68ebbc7027641c23","glsl-optimizer/src/util/disk_cache.h":"e83314fb14134a8e079b15e470a6376ba5a8253701f048c890a62b7e55d64bc8","glsl-optimizer/src/util/fast_urem_by_const.h":"e108fce804616c47d071dfe4a04163eec1126e448ed1aa89abb6b3a6d772bd5b","glsl-optimizer/src/util/fnv1a.h":"ab2596f19c6adf431ae27618f62c5743e24ad23ef83bb359a4c4c218245ab459","glsl-optimizer/src/util/format/u_format.h":"4cdfc0c59cbc99a092e5ec5a396910f2d93b9643e5d8141050b011e66f11e45b","glsl-optimizer/src/util/futex.h":"26f7c9d86e9ffef4c0fa2761f1aaa1918337302e20bd6ca10e61dc3c47356deb","glsl-optimizer/src/util/half_float.c":"11bc2584493d5d9d46e8c8a619a0307cf150bf5ab5d0f96bb764b061dc37a00e","glsl-optimizer/src/util/half_float.h":"7f7c380f126da1400a91758cc0392f24bf967bce1672890b62be26fe9fbd922b","glsl-optimizer/src/util/hash_table.c":"0ca40352e35dedab0a84c64c903f1b16d47e950bb5f43b4d22bb57d499bfea6e","glsl-optimizer/src/util/hash_table.h":"217191bb360592e2232f187473c10287d2cda8ae6fa5c53d0ef74c8c206118b4","glsl-optimizer/src/util/list.h":"9fab03c6a78186bb5f173269f825f6ce976b409d931852e3d93bac632e07989a","glsl-optimizer/src/util/macros.h":"63faf65b51058c483b17f1f77da51d1c53c8beab52678cb6bd01f1228a63b6b0","glsl-optimizer/src/util/mesa-sha1.c":"00c692ec353ebc02c06c57c5a71de0ab7a119f86a4146f452e65ec87e4944417","glsl-optimizer/src/util/mesa-sha1.h":"bff4c29f4bf7cdbcefb30fa0c996a7604a380eba8976467c2a60e7cd328f7e26","glsl-optimizer/src/util/mesa-sha1_test.c":"25da89a59d51469f77b4c468ca23ffdce0a7a1166a70b6cc23026a6800b0143c","glsl-optimizer/src/util/os_memory.h":"64555faf1760ae6954f42c83727c38dfc4c278e9152115779ffaad58b42adacf","glsl-optimizer/src/util/os_memory_aligned.h":"12d86fa94be38c13f7eeebdf313795e1267dd5a7187d2f0072e0e896f41702f6","glsl-optimizer/src/util/os_memory_stdc.h":"07360363b88c927065e10df71bebf6c8a0cc3b9167c9dfce55f2d65f11e6f787","glsl-optimizer/src/util/os_misc.c":"a9936e613ec84803abd59ad47c192c8e3939993c950ac91973fdc4cec1801bb8","glsl-optimizer/src/util/os_misc.h":"cc68eb12e05b5e749c54298cb4a6f4cd20cc5af7db3403e70b3c27b56090c740","glsl-optimizer/src/util/os_time.h":"73e775f7335244ff5964c678c27eedf1aea6abea44c4169d327ea8c7ce4a3a88","glsl-optimizer/src/util/ralloc.c":"4b51189595ef67bcef52c40cbf654d969041dbd15e15d4a893ad494ac060aeca","glsl-optimizer/src/util/ralloc.h":"e573c45875ff1530f0dbee9a93ae55535fdac8d5cc88a79ebc327c688824bde5","glsl-optimizer/src/util/rounding.h":"0450722353caf83de07e67f335949dbe95fe53b534052d4ee9d28d2781387614","glsl-optimizer/src/util/set.c":"86f8c9a830bead5a5a79bc970b0ff97809312af07b3beb39ef9d90af04d40a1b","glsl-optimizer/src/util/set.h":"3e39ca161e7ed4ec7c436cc9c7919ed9a55ed1b71edbf2caf6f9bcfd9bc578ed","glsl-optimizer/src/util/sha1/README":"00af7419af05247081858acb2902efd99fcda2ce16e331079f701645bb3729c0","glsl-optimizer/src/util/sha1/sha1.c":"1403bbe0aad42ba3e6be7e09f7cad87a6a8c4ad5b63962f7b92b9f37d8133b04","glsl-optimizer/src/util/sha1/sha1.h":"68d9f240eab2918026ecdf22be36811abbd4f1389f6c36e31258041aeaedd247","glsl-optimizer/src/util/simple_mtx.h":"12c6c3c4b7db9168bc656d5b3c65912075084d2b388c415d5c3d3f5953a9d6c7","glsl-optimizer/src/util/softfloat.c":"a97e51a96fe5e6a052c02aa6bbec683fe73fb88a8c087d9c930503e2120d8a2e","glsl-optimizer/src/util/softfloat.h":"66664b0250e83bf5dd4cc743acd119d076efcea624a0eab3d6b60718e6ee8811","glsl-optimizer/src/util/string_buffer.c":"63a1d1b1e34926c88ea00159cafbcd56568b805c4f64d1e8c97169fe313921fc","glsl-optimizer/src/util/string_buffer.h":"7b88d1b1d9c6cfb8e93331813535c127289437c75f822029e9a3bca8ea6b52ee","glsl-optimizer/src/util/strndup.h":"0273c4fdb7482cd7746881a63d3998648c6d63415ba85af1d1860f0e0dc504c6","glsl-optimizer/src/util/strtod.c":"5cf610d8a37373cf37cfb7aae903525d943b2674b1f32594c70b0eb19a8c9697","glsl-optimizer/src/util/strtod.h":"237396def4e264d35ed4bedea00ef9a4ceab6d7a11a18c770d9747d22c69ed2d","glsl-optimizer/src/util/u_atomic.h":"c02e809526c6c09ba8fe51f50b2490d1b6c8e5c7f3c4031ae958250d098fc3bb","glsl-optimizer/src/util/u_debug.c":"8c060e379b816618f3dd22c9ea523c68b9425c76c36a7dfe5d6d375b337f5f4a","glsl-optimizer/src/util/u_debug.h":"e11e26edd9b9e4e6f8e6a435e69f4d9edda27e9a379f68f4c82ea2525aaaea68","glsl-optimizer/src/util/u_dynarray.h":"853d0fa6ff2261614488be624deb8a2b01e57c2c8eabc28578cbeed4ccc95694","glsl-optimizer/src/util/u_endian.h":"3ccea7e529740318d8a4b05c00db3adc9d1e292a52bdc56a05c9fae99209720f","glsl-optimizer/src/util/u_math.c":"c868a8c0886dc78f1b06b13404ba8b253090449045774dd56893ac9d75795184","glsl-optimizer/src/util/u_math.h":"a04e32e126db016413f9de0a2028a3e71737137463b1289eae576f884b06fcf1","glsl-optimizer/src/util/u_memory.h":"c5db17c724c70283ddbe04165722f6988d4e0eb9aa3602ae472feff016649af9","glsl-optimizer/src/util/u_queue.h":"92930ce236c0528a98b695f5cea8c5c6aa9683beaf71a2227bdc5d33d1b21506","glsl-optimizer/src/util/u_string.h":"c5a2f4ef576d1547bda12c4ea219179fefa54414977743ac094abcaf696ef6ca","glsl-optimizer/src/util/u_thread.h":"00b708459b27f9910d18db92c18cc65cfc618ac2b3cd144e45f8640057b10d58","glsl-optimizer/src/util/xxhash.h":"2f2aff2fc6c0c929f52cf6ae7314122124c5be026d41ad1c357608383c4a37ad","src/bindings.rs":"79993db2058bde39f99ef483d02560d33b1cb882f6a552319e8b86eb6f9021e1","src/lib.rs":"04be1554cd829eb40864b06d80b491dd48117a4e3a601c7d482117f7a0391e67","wrapper.hpp":"f3ea34cc496f7d90b9bfcada3250b37b314c3524dac693b2ece9517bc7d274ac"},"package":"8ba4741358604ca0848c27ecc069d68e62e11cde81e38aac1da3c54b79ab5adf"} +\ No newline at end of file ++{"files":{"Cargo.lock":"f7970552595dc803ace9ef19b5f5d7b1fc784aac30cb27b2ebc3002d97122b9d","Cargo.toml":"7c53ee20d848f9913cacbfcb3ab2e89e30deee8d619d173c95130c7c5d065827","README.md":"4468e08c64c19977707d792bfab0080e35ff927b64990eab77873f8ba056ba1c","build.rs":"92e29699487c21389fc823c50b410cfbfc74cc774265d24958489909ee48a076","glsl-optimizer/CMakeLists.txt":"42ce94744e82ffa000da8b64d81fc140e293b9f5da7dd4cf6b49e7404a2448d9","glsl-optimizer/README.md":"b18eef11a92d267d88a937b1154f7670ee433c730b102fdf7e2da0b02722b146","glsl-optimizer/contrib/glslopt/Main.cpp":"14ba213210c62e234b8d9b0052105fed28eedd83d535ebe85acc10bda7322dd4","glsl-optimizer/contrib/glslopt/Readme":"65d2a6f1aa1dc61e903e090cdade027abad33e02e7c9c81e07dc80508acadec4","glsl-optimizer/generateParsers.sh":"878a97db5d3b69eb3b4c3a95780763b373cfcc0c02e0b28894f162dbbd1b8848","glsl-optimizer/include/GL/gl.h":"1989b51365b6d7d0c48ff6e8b181ef75e2cdf71bfb1626b1cc4362e2f54854a3","glsl-optimizer/include/GL/glext.h":"2ac3681045a35a2194a81a960cad395c04bef1c8a20ef46b799fb24af3ec5f70","glsl-optimizer/include/KHR/khrplatform.h":"1448141a0c054d7f46edfb63f4fe6c203acf9591974049481c32442fb03fd6ed","glsl-optimizer/include/c11/threads.h":"56e9e592b28df19f0db432125223cb3eb5c0c1f960c22db96a15692e14776337","glsl-optimizer/include/c11/threads_posix.h":"f922e2c8613582a9340aa5ae37a4f7bd962dbc30e33a7a6ab14bed2d2995bc2b","glsl-optimizer/include/c11/threads_win32.h":"95bf19d7fc14d328a016889afd583e4c49c050a93bcfb114bd2e9130a4532488","glsl-optimizer/include/c11_compat.h":"103fedb48f658d36cb416c9c9e5ea4d70dff181aab551fcb1028107d098ffa3e","glsl-optimizer/include/c99_compat.h":"aafad02f1ea90a7857636913ea21617a0fcd6197256dcfc6dd97bb3410ba892e","glsl-optimizer/include/no_extern_c.h":"40069dbb6dd2843658d442f926e609c7799b9c296046a90b62b570774fd618f5","glsl-optimizer/license.txt":"e26a745226f4a46b3ca00ffbe8be18507362189a2863d04b4f563ba176a9a836","glsl-optimizer/src/compiler/builtin_type_macros.h":"5b4fc4d4da7b07f997b6eb569e37db79fa0735286575ef1fab08d419e76776ff","glsl-optimizer/src/compiler/glsl/README":"e7d408b621c1b605857c4cab63902f615edb06b530142b91ac040808df6e22f7","glsl-optimizer/src/compiler/glsl/TODO":"dd3b7a098e6f9c85ca8c99ce6dea49d65bb75d4cea243b917f29e4ad2c974603","glsl-optimizer/src/compiler/glsl/ast.h":"3e68ff374350c49211a9931f7f55a485d8d89fc4b21caaffbf6655009ad95bf8","glsl-optimizer/src/compiler/glsl/ast_array_index.cpp":"92b4d501f33e0544c00d14e4f8837753afd916c2b42e076ccc95c9e8fc37ba94","glsl-optimizer/src/compiler/glsl/ast_expr.cpp":"afd712a7b1beb2b633888f4a0911b0a8e4ae5eb5ab9c1e3f247d518cdaaa56d6","glsl-optimizer/src/compiler/glsl/ast_function.cpp":"74f4fbd490e366b37f4715168bb3465ecd9334d4130942f75dcc8e80e8e7f027","glsl-optimizer/src/compiler/glsl/ast_to_hir.cpp":"d0f798eb09271d41d068b9e7b18220d37f1ed0083300ab51eba30989698fe23d","glsl-optimizer/src/compiler/glsl/ast_type.cpp":"8eb790b24b26dfb72bdc333744b566c26d8464c5d47d20eae659461f5c4899f7","glsl-optimizer/src/compiler/glsl/builtin_functions.cpp":"454189d643c220fcb49116ee5c8a34f7b349aa67564040deb8607f6a41a15e70","glsl-optimizer/src/compiler/glsl/builtin_functions.h":"a37cad7ed09b522c5b8bec7b80115a36846e7ba6e0874a2a858e32f7f202c665","glsl-optimizer/src/compiler/glsl/builtin_int64.h":"619def6f3aebf180da3944ef08f159ab12a58b24767e41d8b985ac37ded54d62","glsl-optimizer/src/compiler/glsl/builtin_types.cpp":"afec060b62d6f3b00bfbf94e9fa5f96341ce096c128d1eef322791e6ed9cea4d","glsl-optimizer/src/compiler/glsl/builtin_variables.cpp":"6563bfb1345cbca4c77e00eef09ad152f3e1dc271d246a08c5ce9e1f4ce4250a","glsl-optimizer/src/compiler/glsl/float64.glsl":"1072fd888be48c2a7a5117cd2d92a65f034965a66375f598bb856bff5d7be766","glsl-optimizer/src/compiler/glsl/generate_ir.cpp":"e5f0175370a0d07f93c48d3f0f1b8233d12c64a7b02de02dcc753ef7b398ef0f","glsl-optimizer/src/compiler/glsl/glcpp/README":"a0332a1b221d047e9cce5181a64d4ac4056046fd878360ec8ae3a7b1e062bcff","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-lex.c":"2d179879b1ffe84f58875eee5b0c19b6bae9c973b0c48e6bcd99978f2f501c80","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-lex.l":"e4c5744c837200dafd7c15a912d13f650308ea552454d4fa67271bc0a5bde118","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-parse.c":"03494f9ce1cb82260506e2559e73a3eeb622c4bd51b65eaa0a2c3351862bd4c8","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-parse.h":"264d9a18421cde255ce34a0a62b3d8e73465359f0d167e64aa3973062aae5bdd","glsl-optimizer/src/compiler/glsl/glcpp/glcpp-parse.y":"fafb66e3a8f149d19e085f18a4273ba6d4c11af9e9a01d665cc784dddf97b79f","glsl-optimizer/src/compiler/glsl/glcpp/glcpp.c":"37ed294403c2abfd17fd999d1ae8d11b170e5e9c878979fefac74a31195c96b0","glsl-optimizer/src/compiler/glsl/glcpp/glcpp.h":"85ac8b444bcbd0822b66448a1da407b6ae5467b649f5afaf5c58325bd7569468","glsl-optimizer/src/compiler/glsl/glcpp/pp.c":"a52d94f1bcb3fb2747a95709c4a77c25de7eea8354d2b83bb18efd96976a4473","glsl-optimizer/src/compiler/glsl/glcpp/pp_standalone_scaffolding.c":"d11aeb3acfe966d1b78f1ee49804093f2434214c41391d139ffcb67b69dc9862","glsl-optimizer/src/compiler/glsl/glcpp/pp_standalone_scaffolding.h":"abbf1f36ec5a92d035bfbb841b9452287d147616e56373cdbee1c0e55af46406","glsl-optimizer/src/compiler/glsl/glsl_lexer.cpp":"272b9fc1383d72b81bfc03fa11fdf82270ed91a294e523f9ce2b4554bd3effa9","glsl-optimizer/src/compiler/glsl/glsl_lexer.ll":"2b57d9f9eb830c3d7961d4533048a158ee6f458c8d05c65bea7b7cfbc36e4458","glsl-optimizer/src/compiler/glsl/glsl_optimizer.cpp":"f8095d20629d0af70be930b0612e169edb274551a1d25a3cd1bf9995a11ce2e8","glsl-optimizer/src/compiler/glsl/glsl_optimizer.h":"22e843b4ec53ba5f6cd85ca5f7bad33922dca8061b19fb512d46f1caca8d4757","glsl-optimizer/src/compiler/glsl/glsl_parser.cpp":"126baf368d525aba301854e3d91ba60b5aee32e1102376af71416f32cb95ec48","glsl-optimizer/src/compiler/glsl/glsl_parser.h":"2ea9a50716098a8f7bef782d2a030d757b68da73afb01b4d4940d3e8381d44e8","glsl-optimizer/src/compiler/glsl/glsl_parser.yy":"6b1fd1576b29fce005dff744a6dbd0219e4c695c361d61864e1f3a8d6fa6b764","glsl-optimizer/src/compiler/glsl/glsl_parser_extras.cpp":"aad64b5b66467da650091430681e8c6a820cf3cadc4db3c160bf2f15875390ae","glsl-optimizer/src/compiler/glsl/glsl_parser_extras.h":"71fd0e92bbdb193dfb067d7bfdb1200d77392be2fbd0cbfc9ca89d1bb4c7e741","glsl-optimizer/src/compiler/glsl/glsl_symbol_table.cpp":"6660fb83c0ddddbbd64581d46ccfdb9c84bfaa99d13348c289e6442ab00df046","glsl-optimizer/src/compiler/glsl/glsl_symbol_table.h":"24682b8304e0ea3f6318ddb8c859686bd1faee23cd0511d1760977ae975d41bf","glsl-optimizer/src/compiler/glsl/hir_field_selection.cpp":"72a039b0fcab4161788def9e4bedac7ac06a20d8e13146529c6d246bd5202afd","glsl-optimizer/src/compiler/glsl/int64.glsl":"303dbe95dde44b91aee3e38b115b92028400d6a92f9268975d607471984e13eb","glsl-optimizer/src/compiler/glsl/ir.cpp":"2b4741cce90b5d4abff5d719c7324e2693c67294d4d99736cb241554adb281bc","glsl-optimizer/src/compiler/glsl/ir.h":"990b1c74447c4eb4835353ccb0ed9aea644f97fc1129ef1739cd935075d85d2e","glsl-optimizer/src/compiler/glsl/ir_array_refcount.cpp":"8cdc1cffe01e42e0566fa2193a75f789628e8025ad1b82f0ee6f204451b7f9f7","glsl-optimizer/src/compiler/glsl/ir_array_refcount.h":"75f06ec81342b379096ca52e1dc0fd5f19a11ff8e9b58203c20628179d644c12","glsl-optimizer/src/compiler/glsl/ir_basic_block.cpp":"1e2920b1c0ecb08424c745c558f84d0d7e44b74585cf2cc2265dc4dfede3fa2f","glsl-optimizer/src/compiler/glsl/ir_basic_block.h":"81be7da0fc0ee547cd13ec60c1fcd7d3ce3d70d7e5e988f01a3b43a827acdf05","glsl-optimizer/src/compiler/glsl/ir_builder.cpp":"daba29c5a1efdd5a9754f420eb3e2ebdf73485273497f40d4863dadeddb23c0d","glsl-optimizer/src/compiler/glsl/ir_builder.h":"2822e74dd3f6e3df8b300af27d5b11ea2dd99d0e5e7ca809b7bbcce9833c483c","glsl-optimizer/src/compiler/glsl/ir_builder_print_visitor.cpp":"8c6df5abf2fe313363f285f171c19ca6c8ee4f3bc2ed79d33c0c88cc8be45c48","glsl-optimizer/src/compiler/glsl/ir_builder_print_visitor.h":"799852adc3a0e54d04080655e7cebfa0d3bf5b6ffed5d8414f141380665d4db7","glsl-optimizer/src/compiler/glsl/ir_clone.cpp":"d897a4e1f5bbec4a6a2f15044c1be9a4d13899c73be77335b041049a4589aa5d","glsl-optimizer/src/compiler/glsl/ir_constant_expression.cpp":"78bd87ddb09db67f6c499067728d72aef4f16aa02721a99a4b769d1e0cfa9010","glsl-optimizer/src/compiler/glsl/ir_equals.cpp":"bca28533a6310b0fc152b56d80872368f1510dc62ed6e8ac199b9ffa7fac02e7","glsl-optimizer/src/compiler/glsl/ir_expression_flattening.cpp":"7e918d4e1f237eca01396004015865ce345afe32a876c9dbc6728576a1a7eae4","glsl-optimizer/src/compiler/glsl/ir_expression_flattening.h":"f45b66aa9497520e7e08e612d24b308477c34477fbd963ee9320eac664957f16","glsl-optimizer/src/compiler/glsl/ir_expression_operation.h":"cc9f10727dbd26cac506804f51456302c702650f9eeb59054a7e1575d5cf6687","glsl-optimizer/src/compiler/glsl/ir_expression_operation.py":"7b86c96021b9fbe165957f4ecb0b612fefcde1c2cf3c6d75e3cdb22e369216ba","glsl-optimizer/src/compiler/glsl/ir_expression_operation_constant.h":"9ad3346416392e3efa11e12ecf2feca7453c5253d241eb96c91dfb85d4f2b971","glsl-optimizer/src/compiler/glsl/ir_expression_operation_strings.h":"a6826daf496a8b9e89885bc2a161ac3445d501b23c6e0ac33e2c01b506b273c8","glsl-optimizer/src/compiler/glsl/ir_function.cpp":"7537365fc0fbe4b37a26b9a2146cc64d3e9a774d60eab63b65002ad165ae8fc7","glsl-optimizer/src/compiler/glsl/ir_function_can_inline.cpp":"faddbf112187a048d502716a3fb82570a322299ba2a3abd79388382c82040bfc","glsl-optimizer/src/compiler/glsl/ir_function_detect_recursion.cpp":"9176973eaf5c0a984701f953bb7a80f37dca43d59b5bce50fc69b3f02f2902d7","glsl-optimizer/src/compiler/glsl/ir_function_inlining.h":"9739493f99c489987d650762fccdd3fb3d432f6481d67f6c799176685bd59632","glsl-optimizer/src/compiler/glsl/ir_hierarchical_visitor.cpp":"3725861fbe2b98e0617f52d3b14cf6d3b25fb5ec00f5ef5d308b03642f592767","glsl-optimizer/src/compiler/glsl/ir_hierarchical_visitor.h":"e0560210e966c0c31e4ca843e80ea154e64db5a444b8c2df845b6ba5b3a43fc1","glsl-optimizer/src/compiler/glsl/ir_hv_accept.cpp":"caf7ce2cd9494aadd3c58bcf77f29de58368dc9e347a362bbf37f8bda9509b80","glsl-optimizer/src/compiler/glsl/ir_optimization.h":"8b3dcfc7f9e96b21a8dd47a0040d90be483a9e67a2cdce3a697188fb758d4630","glsl-optimizer/src/compiler/glsl/ir_print_glsl_visitor.cpp":"f8e34a983452be0dcb5a695e9c8e895eead24f9e540992a8afe510ae85da4c4c","glsl-optimizer/src/compiler/glsl/ir_print_glsl_visitor.h":"1ad1bd3efd1ace39051c13f904c05fd80425d329444f9a8d47fd6d948faf46e0","glsl-optimizer/src/compiler/glsl/ir_print_visitor.cpp":"643f5a68aae3fb37267fd793f1216d1cfdeb2c09338c26b1f30e4c6deaef4de5","glsl-optimizer/src/compiler/glsl/ir_print_visitor.h":"4573eb93268a2654c14b505253dd651e2695d43dc745904d824da18305269b95","glsl-optimizer/src/compiler/glsl/ir_reader.cpp":"06bfba802c8354e5a8b2334b6d78d6297de18235bedd3f8fbb382c89870b02f2","glsl-optimizer/src/compiler/glsl/ir_reader.h":"63e3f7f1597936a7011d5b520e171b197bf82bee6c1560d822c3edf5aaa6f9e9","glsl-optimizer/src/compiler/glsl/ir_rvalue_visitor.cpp":"84b5c5d746555adca85759c2912fe48010232b7c1c0bd2cf03bd04067a85e66f","glsl-optimizer/src/compiler/glsl/ir_rvalue_visitor.h":"fd8c561b71085d3211fff85ed514fecb299d8ce19a04bc063419a55b6d840525","glsl-optimizer/src/compiler/glsl/ir_set_program_inouts.cpp":"ab9f115ce9e7f312d9c7978340ced0dc4ae6d13a80e08442ba9709d11d50cae5","glsl-optimizer/src/compiler/glsl/ir_uniform.h":"683ae6896b1a08470c090be5f822fc31cd434eab9216e954b9bba24a46975109","glsl-optimizer/src/compiler/glsl/ir_unused_structs.cpp":"9c1620c45f2fc071fe5ed828472040b14c5f42effe06aa0e3b8352c95ef78786","glsl-optimizer/src/compiler/glsl/ir_unused_structs.h":"13387b49c23093575276b25b9dfd31fedd8f131c5c4f3128ab04cf03e15b5295","glsl-optimizer/src/compiler/glsl/ir_validate.cpp":"6b232be5999a86ea278f4f15b2832d76843246509118d924243055a3b9b0299f","glsl-optimizer/src/compiler/glsl/ir_variable_refcount.cpp":"2764a3cad937d53f36db7447c3a5b98b04bf153acf81074d971857fc5bca460d","glsl-optimizer/src/compiler/glsl/ir_variable_refcount.h":"b0668e3eb1501ef65e38fe12830742ecb3d28e6039f30e366c8924efc29b4a39","glsl-optimizer/src/compiler/glsl/ir_visitor.h":"f21b3534c3d66d5fb707d1581fece7e1eb043523afbaedf89918cfb031c6df94","glsl-optimizer/src/compiler/glsl/link_atomics.cpp":"360f0209e11f367ba358223597b0a118bae095bff16337cf03f1fb89c5b80ca6","glsl-optimizer/src/compiler/glsl/link_functions.cpp":"de7895da8aa33a1e3c2c1eb2fdaf267ab5d1fbfdb79ae2e67f95211e946e294c","glsl-optimizer/src/compiler/glsl/link_interface_blocks.cpp":"1926cfa73810704eb19b916c1b2cdb9321155e2f98b2a0a57c7c3c6e960540cd","glsl-optimizer/src/compiler/glsl/link_uniform_block_active_visitor.cpp":"1e14e06ca3b2c1089cfba2e8eaf0c1f373d9d6374b6082f320962dd71ae09611","glsl-optimizer/src/compiler/glsl/link_uniform_block_active_visitor.h":"fd58c155af645295bb6aec08797889de586f4d919731de2bce57e8dce59bb048","glsl-optimizer/src/compiler/glsl/link_uniform_blocks.cpp":"09589f49776dce32e6c4044937de7e0c839a9754ad31960148f8f9e010658997","glsl-optimizer/src/compiler/glsl/link_uniform_initializers.cpp":"bf98e08c12db466acf9623cbeb8fa8e3b4002512722e7a6521287f558a099f37","glsl-optimizer/src/compiler/glsl/link_uniforms.cpp":"84bad5b1377362cecf259b05124239be5220b03ce1c0c61b59bd9a47e4379af2","glsl-optimizer/src/compiler/glsl/link_varyings.cpp":"a5f1a53e7c80d635515fe808ff223d89fef1767abb0f2b7aa28fa6773dca353f","glsl-optimizer/src/compiler/glsl/link_varyings.h":"b9dbe018f038df69763df2e928742ce81bbc6e3aaba26f50621e30a6d9aa6220","glsl-optimizer/src/compiler/glsl/linker.cpp":"40b1ecd5d4f6c7f13d5a87ce390561a51fdf6f3fcd9b2197b9c88b03a773ba94","glsl-optimizer/src/compiler/glsl/linker.h":"ecf94b4ad75ef461c27c557fda4bd25f34c91930822b8e1d729ec84520d4a049","glsl-optimizer/src/compiler/glsl/linker_util.cpp":"1663ad88e2a369305659aeeffaedb5bd752cf76340a2ba5797fc0bf600633cf9","glsl-optimizer/src/compiler/glsl/linker_util.h":"6db788daf9c8e87ae2764b61a8b37ebe419e69c1b82ddee01986e37c978c6993","glsl-optimizer/src/compiler/glsl/list.h":"b1f46ce0e552fe7c45b2a19408a9d97662e23e4b182ab335491c26f8cf25886f","glsl-optimizer/src/compiler/glsl/loop_analysis.cpp":"57ecd573477c68091c7cc99537faa7139a8f395935e3d4f10144cefdefb5a611","glsl-optimizer/src/compiler/glsl/loop_analysis.h":"a85f045a038ee5b5176063e85d7988865862c44ab0580f771b993a042d0b69cc","glsl-optimizer/src/compiler/glsl/loop_unroll.cpp":"bd4292ea2809f5a669bcb76ceaa1ac365772dcd638c579c3ed10275214901a54","glsl-optimizer/src/compiler/glsl/lower_blend_equation_advanced.cpp":"8cfbef140d9c4b4d2f57bfa05c9c374d31a121d0f87afce94333f049023b654a","glsl-optimizer/src/compiler/glsl/lower_buffer_access.cpp":"1ae221c3c7a95aeb867207e7a742be635f91b406c157747bfd6ddf10274d97fb","glsl-optimizer/src/compiler/glsl/lower_buffer_access.h":"807886953a576a323591798cbca5e2df24295ea893b28affd8ffb5926cebaa04","glsl-optimizer/src/compiler/glsl/lower_builtins.cpp":"4d81afc32cf58e1481fcb5e42888ab93dbe6820310a20ff7a9982b77b2152d9b","glsl-optimizer/src/compiler/glsl/lower_const_arrays_to_uniforms.cpp":"608403f0eeeedf21cfcd3014116e0f44e28cbdf6c4c32aac7e613e64e30205e1","glsl-optimizer/src/compiler/glsl/lower_cs_derived.cpp":"179905cd47a294122adeb5b0abfed6f2f67782dcde21b544d1ee2c1985154e66","glsl-optimizer/src/compiler/glsl/lower_discard.cpp":"3b361b2db0004d544d64611cb50d5a6e364cf6c5f2e60c449085d7d753dd7fb0","glsl-optimizer/src/compiler/glsl/lower_discard_flow.cpp":"f5c29b6a27690bb5c91f196d1a1cf9f6be4f1025292311fe2dac561ce6774dee","glsl-optimizer/src/compiler/glsl/lower_distance.cpp":"a118c85493d5d22b2c059a930c51a5854896d4b1dade76598eaa985e5a3dff8c","glsl-optimizer/src/compiler/glsl/lower_if_to_cond_assign.cpp":"469e617757fd1728709cce021aac5c8da05ee503bf5366977bdc4ef7a6d83950","glsl-optimizer/src/compiler/glsl/lower_instructions.cpp":"6ff5c396abe40d8a2145d571e99e2bbe9143393e15aafc28adc2803a01d821b6","glsl-optimizer/src/compiler/glsl/lower_int64.cpp":"d1ed41196880dd53c7b13e2782f9423f8442bf1d46186e8be92b1b66218a83ee","glsl-optimizer/src/compiler/glsl/lower_jumps.cpp":"34de7b493f281589fb0c2c0f6e885d0a0fabbe7a4e97a73de374dd714777a58c","glsl-optimizer/src/compiler/glsl/lower_mat_op_to_vec.cpp":"dff7a308edc4846c348ed4225c6699a9c75abac68d88f41f85954276552779f4","glsl-optimizer/src/compiler/glsl/lower_named_interface_blocks.cpp":"16063ac127bff75a68272070ab11c21c25101edbff62b4c68f4983b4cd941af0","glsl-optimizer/src/compiler/glsl/lower_offset_array.cpp":"3b00773399135aea85746a5a68b96ef000bc6841be1a2c8e6f25c516628b0949","glsl-optimizer/src/compiler/glsl/lower_output_reads.cpp":"a0fc9975d5aa1617e21fc6c353659a9802da9e83779a3eef4ec584f74b4dadc5","glsl-optimizer/src/compiler/glsl/lower_packed_varyings.cpp":"7550099d4ae123d71541c2fc88bc04fbfe9271ec75d7e210987d1c8cac3cf3ea","glsl-optimizer/src/compiler/glsl/lower_packing_builtins.cpp":"79a13d161fe505a410ab948d92769395708693ec888153630fa240e5b97e356f","glsl-optimizer/src/compiler/glsl/lower_precision.cpp":"f82a185b879872b977a1787d8061b9a80bc4cf8db1b970db6efba2ad9cc20fa2","glsl-optimizer/src/compiler/glsl/lower_shared_reference.cpp":"ea2dccf50a83bc19391bf6b7ab6aa53c0005f427af4066d25140340af9a4beef","glsl-optimizer/src/compiler/glsl/lower_subroutine.cpp":"f69fa53650eeb6f2944fce4d36a6e0a423e6705f3a3bd3389c7fadb83cfc8802","glsl-optimizer/src/compiler/glsl/lower_tess_level.cpp":"b196c9d424c0569f3e85d75c2d125af21566cb113d69036db87c0990703e0fa7","glsl-optimizer/src/compiler/glsl/lower_texture_projection.cpp":"4d247f244272adc8250fd888d8d932a140dd5de4d1efc7a58492c3c2b8291527","glsl-optimizer/src/compiler/glsl/lower_ubo_reference.cpp":"89bdbc6c1669230c644c0857db1ce2781ec61d349ecd08c7914146e1f4750a4a","glsl-optimizer/src/compiler/glsl/lower_variable_index_to_cond_assign.cpp":"fce930f29ac9405b297d1f749d68f59506b89c70b4ee1b1ab8cf49a34cc71ecf","glsl-optimizer/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp":"3c67d851a11a55fad1c49a550f3a0cfe50892d33a3f238ce266cd829eba510a8","glsl-optimizer/src/compiler/glsl/lower_vec_index_to_swizzle.cpp":"f5ec666b73e1415cbab32519a53605ed385f3b03e889560373dbce69dda5000e","glsl-optimizer/src/compiler/glsl/lower_vector.cpp":"f7c13f5572ebe09b6a71553133b2cf003cd4b77b9657600672ee3b21bf890725","glsl-optimizer/src/compiler/glsl/lower_vector_derefs.cpp":"b05793da6dd620a531b43df5af8b2ecbc37b9db0c88910f5724ea10bcd057e19","glsl-optimizer/src/compiler/glsl/lower_vector_insert.cpp":"fee772ec17eea5e86a529bf9c5fa2ee0d29a5982bb75ebc6d68ed36cd19aa299","glsl-optimizer/src/compiler/glsl/lower_vertex_id.cpp":"690e8715182e03fead5cc5a35251fb4f41b357e4c71a1dfbc4bd7be19862b56d","glsl-optimizer/src/compiler/glsl/lower_xfb_varying.cpp":"58c0e8b270e4bbde54250be03cdb2f36966bcafb785372ad2e2b786835df7f9f","glsl-optimizer/src/compiler/glsl/main.cpp":"ae5e88abbbc8a12f769e1296bad938b9d7398cc6da0d3d0caeceeeb876536850","glsl-optimizer/src/compiler/glsl/opt_add_neg_to_sub.h":"f5054944bfd068810629080d0ea11df78b3f57a8f86df75e13ca50157ad1964d","glsl-optimizer/src/compiler/glsl/opt_algebraic.cpp":"25f45b20e1972ee8c789177a1aeda6e4286c25db2eae3a43ff83029ae64969c0","glsl-optimizer/src/compiler/glsl/opt_array_splitting.cpp":"19d3ce0e815438f4df9ab2890e767b03a4f3f191b53bb30c0217cf2ae6a95430","glsl-optimizer/src/compiler/glsl/opt_conditional_discard.cpp":"0e44e0e126711a3725c1f3a2aa65ff03c381fed08680ffc30101aae60f716c4e","glsl-optimizer/src/compiler/glsl/opt_constant_folding.cpp":"a088d04d9b45f9e55e235835648f614c89b7803c03a6d4f6a6d1a6bc1f0228bd","glsl-optimizer/src/compiler/glsl/opt_constant_propagation.cpp":"8a9440d77ecd6dcf13e683cbb99943aab6311c8fd4b5f6a9189a8d4f270746f4","glsl-optimizer/src/compiler/glsl/opt_constant_variable.cpp":"63d3ccd4dd09f19c9cf1a2f51592111bed41284504f29f3c0de4cadebc439a37","glsl-optimizer/src/compiler/glsl/opt_copy_propagation_elements.cpp":"ffa0f50863995e0d2e31f55a52e82319edc71e520987bebd7f7e561ea331c64b","glsl-optimizer/src/compiler/glsl/opt_dead_builtin_variables.cpp":"84e8747b948232f01dd56b428b9315f96f9511f605f240119fc446fae28981a9","glsl-optimizer/src/compiler/glsl/opt_dead_builtin_varyings.cpp":"761523e88f5b3ba785170f4d7205e94fa99acb7e74d29efbe40e1c010e1dbdb3","glsl-optimizer/src/compiler/glsl/opt_dead_code.cpp":"fd1ba2da7337d4e5dad17f5c2d73d9cc8880305f423e85d64cf94553588fa401","glsl-optimizer/src/compiler/glsl/opt_dead_code_local.cpp":"969a598b4df322baf222258a66cd64a326ea20e5b3125be9d8d1771f522c69e0","glsl-optimizer/src/compiler/glsl/opt_dead_functions.cpp":"774cae6536d02edf26e996a2a895e1f62d5098f16dc96b44798b4fc731a9a95f","glsl-optimizer/src/compiler/glsl/opt_flatten_nested_if_blocks.cpp":"3696a5c55f02e20056e085bc2714f73ac992f221b6f3387d655068e86b512046","glsl-optimizer/src/compiler/glsl/opt_flip_matrices.cpp":"44f0fe05b49329667671f88c96dc86ab3fe1459ff7b87f2b2d88de2d49829f9f","glsl-optimizer/src/compiler/glsl/opt_function_inlining.cpp":"fb56a33c90419a01676b57cbd91d0674a54cca40e6defaacc88dd33facebc131","glsl-optimizer/src/compiler/glsl/opt_if_simplification.cpp":"ac406eb35e379c357641d6c5749f50c65961455924d3dc884e2b90046fa92c5c","glsl-optimizer/src/compiler/glsl/opt_minmax.cpp":"8abd59d3b14ef60ff14a9c69660e6945f5cf10b97edb4afebe56be3f81d96316","glsl-optimizer/src/compiler/glsl/opt_rebalance_tree.cpp":"8bb6329dc0f299042368fc81934c2df019b45ab9f7aa0415d4e57b8d1ff98c9f","glsl-optimizer/src/compiler/glsl/opt_redundant_jumps.cpp":"222c73e2ac7a938ebb6428cc6c780c908ff6156d8ff935b04fed93a48fc10496","glsl-optimizer/src/compiler/glsl/opt_structure_splitting.cpp":"2edc79cc13f3177934e0443ad62f5976a1991f01f86ea303a803434849b13a47","glsl-optimizer/src/compiler/glsl/opt_swizzle.cpp":"015d0abddfe507f67c4b96c82988d861d018ededf7bf055e2bcbe9ea92da694e","glsl-optimizer/src/compiler/glsl/opt_tree_grafting.cpp":"46d28ac983ea244a4315bdc0e8892979ec4d1f9b9a96ac8a8a08006d9bc5e878","glsl-optimizer/src/compiler/glsl/opt_vectorize.cpp":"d80ee43bb97d9f016fb9c5e1e06f5b2afa569811f368ba067be794ec11d085fb","glsl-optimizer/src/compiler/glsl/program.h":"2982447e2abd35371e273ad87951722782a8b21c08294f67c39d987da1e1c55f","glsl-optimizer/src/compiler/glsl/propagate_invariance.cpp":"080943e21baa32494723a2eefb185915d2daae1f46d6df420145c5ad6857e119","glsl-optimizer/src/compiler/glsl/s_expression.cpp":"1ced972bc6ecc8eab4116ea71fb0212ab9ae5bcc0be3b47aa5d9d903566b3af1","glsl-optimizer/src/compiler/glsl/s_expression.h":"65b847e30e22a809b57d0bc70243049c99d9c6318803c5b8d0826aba55dc217e","glsl-optimizer/src/compiler/glsl/serialize.cpp":"be0eb4251348a9d921acb839a5c48c6023a2e9d116d602bb0432787ab623655d","glsl-optimizer/src/compiler/glsl/serialize.h":"57425732eba1233d928e5f07f88b623ce65af46b3bb034bf147f0a4b7f94f9a1","glsl-optimizer/src/compiler/glsl/shader_cache.cpp":"e0c5c433f2df3fccdf1d61281bfcb0ee5633433339b97c697d64db99611cbaaf","glsl-optimizer/src/compiler/glsl/shader_cache.h":"9217164d8d7f54aca0fe5922c7187095a6ae0cb703b196b79805aeef07a7e697","glsl-optimizer/src/compiler/glsl/standalone.cpp":"8e6c416a14d631261917a5fe4cc91880c287b22b2dfd70eb22028289a8fa5364","glsl-optimizer/src/compiler/glsl/standalone.h":"a7c397d1dfdd1e7fb2cfe99db35cd9df93251e642059208533202b7f20497f83","glsl-optimizer/src/compiler/glsl/standalone_scaffolding.cpp":"970d14b7a9d58e5270321f97bf5d57795558b1c570a56678e04a65b26c60bf4f","glsl-optimizer/src/compiler/glsl/standalone_scaffolding.h":"d921a617ea82b9e49413314492a645c44356de503581b1be3f1b57de236e480d","glsl-optimizer/src/compiler/glsl/string_to_uint_map.cpp":"d824bf5b839bd39498dc9e457103cdbe3e5289ddf7564107c27b1505948dd31f","glsl-optimizer/src/compiler/glsl/string_to_uint_map.h":"e2f18e66359c9d620e085de7f4a334a47df9c66e65a5bfe8b734c627bec04104","glsl-optimizer/src/compiler/glsl/test_optpass.h":"b27b8f35f5387e7ce4982bb51c7b63ccf14f91757f3108a5d02ed006925bb8a0","glsl-optimizer/src/compiler/glsl/xxd.py":"376484142f27f45090ea8203ae2621abf73f06175cb0ee8d96f44a3b9327f4bd","glsl-optimizer/src/compiler/glsl_types.cpp":"044bb6754f45419a3151e7a25c39202a82009ae3c6bc54ff7f0bb4258a5deefe","glsl-optimizer/src/compiler/glsl_types.h":"fd899a42f34ddeb8601bc3cd6c5e3aed82fc8aef4042dde1b39b3c01e1dcc219","glsl-optimizer/src/compiler/shader_enums.c":"436bff5216b11b0980bdfada5885fc6ac9afa2037a3027fcd6eea2a8635597ac","glsl-optimizer/src/compiler/shader_enums.h":"13220442a5c02e83540cf2c0ad4f8417b2fbda5f2586dec4e92082544c937cdd","glsl-optimizer/src/compiler/shader_info.h":"4c5453e81197ca83593ee4f365074b23530f2ab21c78e1733b63dec6f344c12a","glsl-optimizer/src/gallium/auxiliary/util/u_half.h":"3c2b37bda3ccb64387e44b723d29cf9046decab1a893bf42d842e9603398bdee","glsl-optimizer/src/gallium/include/pipe/p_compiler.h":"c75620096ce8523dae90599e50aa2ef6468d3b0e368a77795edeb20dd1abfc0c","glsl-optimizer/src/gallium/include/pipe/p_config.h":"a27692fc35f9e55df3224b7529e66b3001e911e94e6bc5f8f569e493e1ee3fb7","glsl-optimizer/src/gallium/include/pipe/p_defines.h":"be26d68c0acc67c5e44788c6299716a9eee415fd81d7d747e3738a829e3b6b38","glsl-optimizer/src/gallium/include/pipe/p_format.h":"5674215fc41d27496f037cf837717daefbf23ebb38d40ace7c0c414bc08182b0","glsl-optimizer/src/gallium/include/pipe/p_state.h":"d600593aba5f5a17072a6c38f6baa81e01c7994b0174250f7e433bb41684b702","glsl-optimizer/src/mapi/glapi/glapi.h":"73632a625c0ddabc401205e8b5a81eb8af8506868efe4b170d7979ec3619e9c5","glsl-optimizer/src/mesa/main/config.h":"5800259373099e5405de2eb52619f9de242552a479902a3a642a333c8cb3c1e7","glsl-optimizer/src/mesa/main/context.c":"2f3208473d99c94f734b1137ba91889d4a1babb9e7534bf1dc85d851ee98274e","glsl-optimizer/src/mesa/main/context.h":"cc7e4194797db9d007f01884e23d786c453b3860821f7f2ddcdf0f1bf3f8ffb1","glsl-optimizer/src/mesa/main/dd.h":"6a964acd06b6c2d88700e69fb75fe3c6b3b3d45bbc41db24f3f897a29695fe0c","glsl-optimizer/src/mesa/main/debug_output.h":"7312422e90b8c0e34028ac27280e438139b5cba525c99deb3ac883cd3d87e452","glsl-optimizer/src/mesa/main/draw.h":"7eaef3a9e27a60ea6f7937109bf3a6190b831162fde0479abb12077ce27c353d","glsl-optimizer/src/mesa/main/enums.h":"87d562a6764f51c014a2274fa7c3aca17c04441537ddd56b2554f13c6fffea92","glsl-optimizer/src/mesa/main/errors.h":"c79444b5df289c90fbb22a33b2d0c23917d9fc4510960088f0b79e53bb56b1b2","glsl-optimizer/src/mesa/main/extensions.h":"a38b2f87cc93c513994281350d69e06c84ff8eded5313ec0a1be33f375e0ebbd","glsl-optimizer/src/mesa/main/extensions_table.c":"17642d1a8c9a0bf2bd61060052d33ff14a005d2b962e6cf91465797a50851e85","glsl-optimizer/src/mesa/main/extensions_table.h":"2c879571c238d2e14461031ac740372fd0f9ac3a34c0d5541bb9b7ed4c0376c8","glsl-optimizer/src/mesa/main/formats.h":"02e2f7ec3e39286cf9f27e2641043e6df8ecb1dfde9e643313210e214af2a929","glsl-optimizer/src/mesa/main/glheader.h":"58217b33eead6aa6b23cd4a291cefeaa6cb84e465f4960daffca97c44d6d1c35","glsl-optimizer/src/mesa/main/glthread.h":"51fb2711f77e7eafcfc52d29d5b844978832b24c930d88accd48d143a6eb9c6f","glsl-optimizer/src/mesa/main/hash.h":"7e7f782034c16a8e693de48e00c31d4a90b0129f4029fd074033d7d16ccbe718","glsl-optimizer/src/mesa/main/macros.h":"73d15ddfd64f2b57b9b2ffeeb993b9c2c0899a80563e9d6ff337b11ccbe6eee5","glsl-optimizer/src/mesa/main/menums.h":"5dfac0e2279d60b0cd0c7b9fc2a5021620d0f6282ed2e738c420214e3af152d3","glsl-optimizer/src/mesa/main/mesa_private.h":"edda678b93438944279a551f663b8858ad84814a9fc88ba9672ef195599c24ae","glsl-optimizer/src/mesa/main/mtypes.h":"6efddefa099e4d2e3fdd97f0055644f47aba21711385edfeabc2d9b0676f2eec","glsl-optimizer/src/mesa/main/shaderobj.h":"9f0dfe96d0c2154201adef942bd36053533ac7b2492fb3786acda5bea514c75e","glsl-optimizer/src/mesa/main/uniforms.h":"4e331e6ad6e9cbded978b4082dbe0a57c1f8f01327446bb6892bfc179976c38b","glsl-optimizer/src/mesa/main/version.h":"9d0a13a758099302dc55cf7d045791834a89b0f9d4cf17b2692259b369a8a9a1","glsl-optimizer/src/mesa/math/m_matrix.h":"a37b19f182e070db3df93b0ede43c22fb8be8c2906504133ee6dbd7db1185d8b","glsl-optimizer/src/mesa/program/dummy_errors.c":"1820e305515b4c5e041f5e1623266a48ec8f076a155310be7d60637101f593e4","glsl-optimizer/src/mesa/program/ir_to_mesa.h":"b47f58d22e3ca2ae42d52501ea769d15c4476834944fa97eeccd3a3439211d00","glsl-optimizer/src/mesa/program/prog_instruction.h":"ab3832152a7e144b59e5a2264b2c29db56d93be31e76bbd958527a56771b40eb","glsl-optimizer/src/mesa/program/prog_parameter.h":"ba18c743284eadbc837c2c364c73e5d372321a7637a76e589d8d39fe8b5de225","glsl-optimizer/src/mesa/program/prog_statevars.h":"fc413698f84bc52d45fdeae0471934ee9904bfb7eac1a2b5f70446e54bcbbdca","glsl-optimizer/src/mesa/program/program.h":"1f01026a4eff440a3f122fd9b519d03546fe7f7d8be60dca834e95a2f8fbbfd2","glsl-optimizer/src/mesa/program/symbol_table.c":"6611cb9f078035bf5ff8c9112093a6c7d99f8af99a3931d0c07f227cc72283ea","glsl-optimizer/src/mesa/program/symbol_table.h":"631dc35ac48d5e87962d45507461920f6575610960ffcc42a08cefeb43300cda","glsl-optimizer/src/mesa/vbo/vbo.h":"6eb1dcd9a08c92f276c5fe08da184ff9d455d1be421913b8ad732a7b65e858fb","glsl-optimizer/src/util/bitscan.h":"9e49e694e6b34fe035bc685f32588827eb8cbe7d82878963c7ab52843e1c16aa","glsl-optimizer/src/util/bitset.h":"c40f78515c6230fed18345c6751ce33833a49da7a27901c7e6d7340cbdcbc5e7","glsl-optimizer/src/util/blob.c":"8f729846f66efc9c15485cc5fc24c6ec861fc1fecb2f652573f2a237d481b791","glsl-optimizer/src/util/blob.h":"93e1eaac866b9a7cd6fc03b533c18fb2edf0e97f03395eff4f3a605c4fc14d0c","glsl-optimizer/src/util/compiler.h":"79e3bf40a5bab704e6c949f23a1352759607bb57d80e5d8df2ef159755f10b68","glsl-optimizer/src/util/crc32.c":"2f3467a046b3a76784ecb9aa55d527698c8607fd0b12c622f6691aaa77b58505","glsl-optimizer/src/util/crc32.h":"59bd81865e51042b73a86f8fb117c312418df095fed2d828c5c1d1c8b6fc6cd4","glsl-optimizer/src/util/debug.c":"c3d68e9752ccc19e66c669562cd113cf1d0ac83cbb30174789e7fb8d1df58f9c","glsl-optimizer/src/util/debug.h":"50068d745c4199ccbd33d68dd4c8a36d2b5179c7869a21e75906ddd0718ca456","glsl-optimizer/src/util/detect_os.h":"343a8790d17a3710c6dd015ee367f84e3902ff3f2e36faca2bf93f9d725d3574","glsl-optimizer/src/util/disk_cache.c":"f533937e5a4fffe76e2739ef4b6b1e1da097d96d63eb808e68ebbc7027641c23","glsl-optimizer/src/util/disk_cache.h":"e83314fb14134a8e079b15e470a6376ba5a8253701f048c890a62b7e55d64bc8","glsl-optimizer/src/util/fast_urem_by_const.h":"e108fce804616c47d071dfe4a04163eec1126e448ed1aa89abb6b3a6d772bd5b","glsl-optimizer/src/util/fnv1a.h":"ab2596f19c6adf431ae27618f62c5743e24ad23ef83bb359a4c4c218245ab459","glsl-optimizer/src/util/format/u_format.h":"4cdfc0c59cbc99a092e5ec5a396910f2d93b9643e5d8141050b011e66f11e45b","glsl-optimizer/src/util/futex.h":"26f7c9d86e9ffef4c0fa2761f1aaa1918337302e20bd6ca10e61dc3c47356deb","glsl-optimizer/src/util/half_float.c":"11bc2584493d5d9d46e8c8a619a0307cf150bf5ab5d0f96bb764b061dc37a00e","glsl-optimizer/src/util/half_float.h":"7f7c380f126da1400a91758cc0392f24bf967bce1672890b62be26fe9fbd922b","glsl-optimizer/src/util/hash_table.c":"0ca40352e35dedab0a84c64c903f1b16d47e950bb5f43b4d22bb57d499bfea6e","glsl-optimizer/src/util/hash_table.h":"217191bb360592e2232f187473c10287d2cda8ae6fa5c53d0ef74c8c206118b4","glsl-optimizer/src/util/list.h":"9fab03c6a78186bb5f173269f825f6ce976b409d931852e3d93bac632e07989a","glsl-optimizer/src/util/macros.h":"63faf65b51058c483b17f1f77da51d1c53c8beab52678cb6bd01f1228a63b6b0","glsl-optimizer/src/util/mesa-sha1.c":"00c692ec353ebc02c06c57c5a71de0ab7a119f86a4146f452e65ec87e4944417","glsl-optimizer/src/util/mesa-sha1.h":"bff4c29f4bf7cdbcefb30fa0c996a7604a380eba8976467c2a60e7cd328f7e26","glsl-optimizer/src/util/mesa-sha1_test.c":"25da89a59d51469f77b4c468ca23ffdce0a7a1166a70b6cc23026a6800b0143c","glsl-optimizer/src/util/os_memory.h":"64555faf1760ae6954f42c83727c38dfc4c278e9152115779ffaad58b42adacf","glsl-optimizer/src/util/os_memory_aligned.h":"12d86fa94be38c13f7eeebdf313795e1267dd5a7187d2f0072e0e896f41702f6","glsl-optimizer/src/util/os_memory_stdc.h":"07360363b88c927065e10df71bebf6c8a0cc3b9167c9dfce55f2d65f11e6f787","glsl-optimizer/src/util/os_misc.c":"a9936e613ec84803abd59ad47c192c8e3939993c950ac91973fdc4cec1801bb8","glsl-optimizer/src/util/os_misc.h":"cc68eb12e05b5e749c54298cb4a6f4cd20cc5af7db3403e70b3c27b56090c740","glsl-optimizer/src/util/os_time.h":"73e775f7335244ff5964c678c27eedf1aea6abea44c4169d327ea8c7ce4a3a88","glsl-optimizer/src/util/ralloc.c":"4b51189595ef67bcef52c40cbf654d969041dbd15e15d4a893ad494ac060aeca","glsl-optimizer/src/util/ralloc.h":"e573c45875ff1530f0dbee9a93ae55535fdac8d5cc88a79ebc327c688824bde5","glsl-optimizer/src/util/rounding.h":"0450722353caf83de07e67f335949dbe95fe53b534052d4ee9d28d2781387614","glsl-optimizer/src/util/set.c":"86f8c9a830bead5a5a79bc970b0ff97809312af07b3beb39ef9d90af04d40a1b","glsl-optimizer/src/util/set.h":"3e39ca161e7ed4ec7c436cc9c7919ed9a55ed1b71edbf2caf6f9bcfd9bc578ed","glsl-optimizer/src/util/sha1/README":"00af7419af05247081858acb2902efd99fcda2ce16e331079f701645bb3729c0","glsl-optimizer/src/util/sha1/sha1.c":"1403bbe0aad42ba3e6be7e09f7cad87a6a8c4ad5b63962f7b92b9f37d8133b04","glsl-optimizer/src/util/sha1/sha1.h":"68d9f240eab2918026ecdf22be36811abbd4f1389f6c36e31258041aeaedd247","glsl-optimizer/src/util/simple_mtx.h":"12c6c3c4b7db9168bc656d5b3c65912075084d2b388c415d5c3d3f5953a9d6c7","glsl-optimizer/src/util/softfloat.c":"a97e51a96fe5e6a052c02aa6bbec683fe73fb88a8c087d9c930503e2120d8a2e","glsl-optimizer/src/util/softfloat.h":"66664b0250e83bf5dd4cc743acd119d076efcea624a0eab3d6b60718e6ee8811","glsl-optimizer/src/util/string_buffer.c":"63a1d1b1e34926c88ea00159cafbcd56568b805c4f64d1e8c97169fe313921fc","glsl-optimizer/src/util/string_buffer.h":"7b88d1b1d9c6cfb8e93331813535c127289437c75f822029e9a3bca8ea6b52ee","glsl-optimizer/src/util/strndup.h":"0273c4fdb7482cd7746881a63d3998648c6d63415ba85af1d1860f0e0dc504c6","glsl-optimizer/src/util/strtod.c":"5cf610d8a37373cf37cfb7aae903525d943b2674b1f32594c70b0eb19a8c9697","glsl-optimizer/src/util/strtod.h":"237396def4e264d35ed4bedea00ef9a4ceab6d7a11a18c770d9747d22c69ed2d","glsl-optimizer/src/util/u_atomic.h":"c02e809526c6c09ba8fe51f50b2490d1b6c8e5c7f3c4031ae958250d098fc3bb","glsl-optimizer/src/util/u_debug.c":"8c060e379b816618f3dd22c9ea523c68b9425c76c36a7dfe5d6d375b337f5f4a","glsl-optimizer/src/util/u_debug.h":"e11e26edd9b9e4e6f8e6a435e69f4d9edda27e9a379f68f4c82ea2525aaaea68","glsl-optimizer/src/util/u_dynarray.h":"853d0fa6ff2261614488be624deb8a2b01e57c2c8eabc28578cbeed4ccc95694","glsl-optimizer/src/util/u_endian.h":"3ccea7e529740318d8a4b05c00db3adc9d1e292a52bdc56a05c9fae99209720f","glsl-optimizer/src/util/u_math.c":"c868a8c0886dc78f1b06b13404ba8b253090449045774dd56893ac9d75795184","glsl-optimizer/src/util/u_math.h":"a04e32e126db016413f9de0a2028a3e71737137463b1289eae576f884b06fcf1","glsl-optimizer/src/util/u_memory.h":"c5db17c724c70283ddbe04165722f6988d4e0eb9aa3602ae472feff016649af9","glsl-optimizer/src/util/u_queue.h":"92930ce236c0528a98b695f5cea8c5c6aa9683beaf71a2227bdc5d33d1b21506","glsl-optimizer/src/util/u_string.h":"c5a2f4ef576d1547bda12c4ea219179fefa54414977743ac094abcaf696ef6ca","glsl-optimizer/src/util/u_thread.h":"00b708459b27f9910d18db92c18cc65cfc618ac2b3cd144e45f8640057b10d58","glsl-optimizer/src/util/xxhash.h":"2f2aff2fc6c0c929f52cf6ae7314122124c5be026d41ad1c357608383c4a37ad","src/bindings.rs":"79993db2058bde39f99ef483d02560d33b1cb882f6a552319e8b86eb6f9021e1","src/lib.rs":"04be1554cd829eb40864b06d80b491dd48117a4e3a601c7d482117f7a0391e67","wrapper.hpp":"f3ea34cc496f7d90b9bfcada3250b37b314c3524dac693b2ece9517bc7d274ac"},"package":"8ba4741358604ca0848c27ecc069d68e62e11cde81e38aac1da3c54b79ab5adf"} +\ No newline at end of file diff --git a/build-cacheFlush-missing.patch b/build-cacheFlush-missing.patch deleted file mode 100644 index 51c368c..0000000 --- a/build-cacheFlush-missing.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -up firefox-55.0.3/js/src/jit/ExecutableAllocator.h.wasm firefox-55.0.3/js/src/jit/ExecutableAllocator.h ---- firefox-55.0.3/js/src/jit/ExecutableAllocator.h.wasm 2017-09-05 11:32:12.235909468 +0200 -+++ firefox-55.0.3/js/src/jit/ExecutableAllocator.h 2017-09-05 11:32:46.157916575 +0200 -@@ -219,7 +219,7 @@ class ExecutableAllocator - - static void poisonCode(JSRuntime* rt, JitPoisonRangeVector& ranges); - --#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) || defined(JS_SIMULATOR_ARM64) -+#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) || defined(JS_SIMULATOR_ARM64) || defined(JS_CODEGEN_NONE) - static void cacheFlush(void*, size_t) - { - } -diff -up firefox-55.0.3/js/src/jit-test/tests/wasm/bench/wasm_box2d.wasm firefox-55.0.3/js/src/jit-test/tests/wasm/bench/wasm_box2d diff --git a/build-cubeb-pulse-arm.patch b/build-cubeb-pulse-arm.patch deleted file mode 100644 index 008208c..0000000 --- a/build-cubeb-pulse-arm.patch +++ /dev/null @@ -1,4946 +0,0 @@ -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/Cargo.toml.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/Cargo.toml ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/Cargo.toml.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/Cargo.toml 2017-08-04 13:37:46.383821740 +0200 -@@ -7,7 +7,11 @@ description = "Cubeb backed for PulseAud - [features] - pulse-dlopen = ["pulse-ffi/dlopen"] - -+[lib] -+crate-type = ["staticlib", "rlib"] -+ - [dependencies] - cubeb-ffi = { path = "cubeb-ffi" } - pulse-ffi = { path = "pulse-ffi" } -+pulse = { path = "pulse-rs" } - semver = "^0.6" -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/cubeb-ffi/src/ffi.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/cubeb-ffi/src/ffi.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/cubeb-ffi/src/ffi.rs.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/cubeb-ffi/src/ffi.rs 2017-08-04 13:37:46.384821737 +0200 -@@ -11,45 +11,45 @@ pub enum Context {} - pub enum Stream {} - - // These need to match cubeb_sample_format --pub const SAMPLE_S16LE: c_int = 0; --pub const SAMPLE_S16BE: c_int = 1; --pub const SAMPLE_FLOAT32LE: c_int = 2; --pub const SAMPLE_FLOAT32BE: c_int = 3; - pub type SampleFormat = c_int; -+pub const SAMPLE_S16LE: SampleFormat = 0; -+pub const SAMPLE_S16BE: SampleFormat = 1; -+pub const SAMPLE_FLOAT32LE: SampleFormat = 2; -+pub const SAMPLE_FLOAT32BE: SampleFormat = 3; - - #[cfg(target_endian = "little")] --pub const SAMPLE_S16NE: c_int = SAMPLE_S16LE; -+pub const SAMPLE_S16NE: SampleFormat = SAMPLE_S16LE; - #[cfg(target_endian = "little")] --pub const SAMPLE_FLOAT32NE: c_int = SAMPLE_FLOAT32LE; -+pub const SAMPLE_FLOAT32NE: SampleFormat = SAMPLE_FLOAT32LE; - #[cfg(target_endian = "big")] --pub const SAMPLE_S16NE: c_int = SAMPLE_S16BE; -+pub const SAMPLE_S16NE: SampleFormat = SAMPLE_S16BE; - #[cfg(target_endian = "big")] --pub const SAMPLE_FLOAT32NE: c_int = SAMPLE_FLOAT32BE; -+pub const SAMPLE_FLOAT32NE: SampleFormat = SAMPLE_FLOAT32BE; - - pub type DeviceId = *const c_void; - - // These need to match cubeb_channel_layout --pub const LAYOUT_UNDEFINED: c_int = 0; --pub const LAYOUT_DUAL_MONO: c_int = 1; --pub const LAYOUT_DUAL_MONO_LFE: c_int = 2; --pub const LAYOUT_MONO: c_int = 3; --pub const LAYOUT_MONO_LFE: c_int = 4; --pub const LAYOUT_STEREO: c_int = 5; --pub const LAYOUT_STEREO_LFE: c_int = 6; --pub const LAYOUT_3F: c_int = 7; --pub const LAYOUT_3F_LFE: c_int = 8; --pub const LAYOUT_2F1: c_int = 9; --pub const LAYOUT_2F1_LFE: c_int = 10; --pub const LAYOUT_3F1: c_int = 11; --pub const LAYOUT_3F1_LFE: c_int = 12; --pub const LAYOUT_2F2: c_int = 13; --pub const LAYOUT_2F2_LFE: c_int = 14; --pub const LAYOUT_3F2: c_int = 15; --pub const LAYOUT_3F2_LFE: c_int = 16; --pub const LAYOUT_3F3R_LFE: c_int = 17; --pub const LAYOUT_3F4_LFE: c_int = 18; --pub const LAYOUT_MAX: c_int = 19; - pub type ChannelLayout = c_int; -+pub const LAYOUT_UNDEFINED: ChannelLayout = 0; -+pub const LAYOUT_DUAL_MONO: ChannelLayout = 1; -+pub const LAYOUT_DUAL_MONO_LFE: ChannelLayout = 2; -+pub const LAYOUT_MONO: ChannelLayout = 3; -+pub const LAYOUT_MONO_LFE: ChannelLayout = 4; -+pub const LAYOUT_STEREO: ChannelLayout = 5; -+pub const LAYOUT_STEREO_LFE: ChannelLayout = 6; -+pub const LAYOUT_3F: ChannelLayout = 7; -+pub const LAYOUT_3F_LFE: ChannelLayout = 8; -+pub const LAYOUT_2F1: ChannelLayout = 9; -+pub const LAYOUT_2F1_LFE: ChannelLayout = 10; -+pub const LAYOUT_3F1: ChannelLayout = 11; -+pub const LAYOUT_3F1_LFE: ChannelLayout = 12; -+pub const LAYOUT_2F2: ChannelLayout = 13; -+pub const LAYOUT_2F2_LFE: ChannelLayout = 14; -+pub const LAYOUT_3F2: ChannelLayout = 15; -+pub const LAYOUT_3F2_LFE: ChannelLayout = 16; -+pub const LAYOUT_3F3R_LFE: ChannelLayout = 17; -+pub const LAYOUT_3F4_LFE: ChannelLayout = 18; -+pub const LAYOUT_MAX: ChannelLayout = 256; - - #[repr(C)] - #[derive(Clone, Copy, Debug)] -@@ -77,11 +77,11 @@ impl Default for Device { - } - - // These need to match cubeb_state --pub const STATE_STARTED: c_int = 0; --pub const STATE_STOPPED: c_int = 1; --pub const STATE_DRAINED: c_int = 2; --pub const STATE_ERROR: c_int = 3; - pub type State = c_int; -+pub const STATE_STARTED: State = 0; -+pub const STATE_STOPPED: State = 1; -+pub const STATE_DRAINED: State = 2; -+pub const STATE_ERROR: State = 3; - - pub const OK: i32 = 0; - pub const ERROR: i32 = -1; -@@ -249,32 +249,42 @@ pub struct LayoutMap { - } - - // cubeb_mixer.h -+pub type Channel = c_int; - - // These need to match cubeb_channel --pub const CHANNEL_INVALID: c_int = -1; --pub const CHANNEL_MONO: c_int = 0; --pub const CHANNEL_LEFT: c_int = 1; --pub const CHANNEL_RIGHT: c_int = 2; --pub const CHANNEL_CENTER: c_int = 3; --pub const CHANNEL_LS: c_int = 4; --pub const CHANNEL_RS: c_int = 5; --pub const CHANNEL_RLS: c_int = 6; --pub const CHANNEL_RCENTER: c_int = 7; --pub const CHANNEL_RRS: c_int = 8; --pub const CHANNEL_LFE: c_int = 9; --pub const CHANNEL_MAX: c_int = 256; --pub type Channel = c_int; -+pub const CHANNEL_INVALID: Channel = -1; -+pub const CHANNEL_MONO: Channel = 0; -+pub const CHANNEL_LEFT: Channel = 1; -+pub const CHANNEL_RIGHT: Channel = 2; -+pub const CHANNEL_CENTER: Channel = 3; -+pub const CHANNEL_LS: Channel = 4; -+pub const CHANNEL_RS: Channel = 5; -+pub const CHANNEL_RLS: Channel = 6; -+pub const CHANNEL_RCENTER: Channel = 7; -+pub const CHANNEL_RRS: Channel = 8; -+pub const CHANNEL_LFE: Channel = 9; -+pub const CHANNEL_MAX: Channel = 10; - - #[repr(C)] -+#[derive(Clone, Copy, Debug)] - pub struct ChannelMap { - pub channels: c_uint, -- pub map: [Channel; 256], -+ pub map: [Channel; CHANNEL_MAX as usize], - } - impl ::std::default::Default for ChannelMap { - fn default() -> Self { - ChannelMap { - channels: 0, -- map: unsafe { ::std::mem::zeroed() }, -+ map: [CHANNEL_INVALID, -+ CHANNEL_INVALID, -+ CHANNEL_INVALID, -+ CHANNEL_INVALID, -+ CHANNEL_INVALID, -+ CHANNEL_INVALID, -+ CHANNEL_INVALID, -+ CHANNEL_INVALID, -+ CHANNEL_INVALID, -+ CHANNEL_INVALID], - } - } - } -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_funcs.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_funcs.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_funcs.rs.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_funcs.rs 2017-08-04 13:37:46.384821737 +0200 -@@ -8,8 +8,8 @@ macro_rules! cstr { - - #[cfg(not(feature = "dlopen"))] - mod static_fns { -- use std::os::raw::{c_char, c_double, c_int, c_float, c_uint, c_void}; - use super::*; -+ use std::os::raw::{c_char, c_double, c_float, c_int, c_uint, c_void}; - - #[link(name = "pulse")] - extern "C" { -@@ -62,6 +62,7 @@ mod static_fns { - userdata: *mut c_void) - -> *mut pa_operation; - pub fn pa_context_set_state_callback(c: *mut pa_context, cb: pa_context_notify_cb_t, userdata: *mut c_void); -+ pub fn pa_context_errno(c: *mut pa_context) -> c_int; - pub fn pa_context_set_subscribe_callback(c: *mut pa_context, - cb: pa_context_subscribe_cb_t, - userdata: *mut c_void); -@@ -70,6 +71,7 @@ mod static_fns { - cb: pa_context_success_cb_t, - userdata: *mut c_void) - -> *mut pa_operation; -+ pub fn pa_context_ref(c: *mut pa_context) -> *mut pa_context; - pub fn pa_context_unref(c: *mut pa_context); - pub fn pa_cvolume_set(a: *mut pa_cvolume, channels: c_uint, v: pa_volume_t) -> *mut pa_cvolume; - pub fn pa_cvolume_set_balance(v: *mut pa_cvolume, -@@ -80,12 +82,20 @@ mod static_fns { - pub fn pa_mainloop_api_once(m: *mut pa_mainloop_api, - callback: pa_mainloop_api_once_cb_t, - userdata: *mut c_void); -- pub fn pa_operation_get_state(o: *const pa_operation) -> pa_operation_state_t; -+ pub fn pa_strerror(error: pa_error_code_t) -> *const c_char; -+ pub fn pa_operation_ref(o: *mut pa_operation) -> *mut pa_operation; - pub fn pa_operation_unref(o: *mut pa_operation); -+ pub fn pa_operation_cancel(o: *mut pa_operation); -+ pub fn pa_operation_get_state(o: *const pa_operation) -> pa_operation_state_t; -+ pub fn pa_operation_set_state_callback(o: *mut pa_operation, -+ cb: pa_operation_notify_cb_t, -+ userdata: *mut c_void); - pub fn pa_proplist_gets(p: *mut pa_proplist, key: *const c_char) -> *const c_char; - pub fn pa_rtclock_now() -> pa_usec_t; - pub fn pa_stream_begin_write(p: *mut pa_stream, data: *mut *mut c_void, nbytes: *mut usize) -> c_int; - pub fn pa_stream_cancel_write(p: *mut pa_stream) -> c_int; -+ pub fn pa_stream_is_suspended(s: *const pa_stream) -> c_int; -+ pub fn pa_stream_is_corked(s: *const pa_stream) -> c_int; - pub fn pa_stream_connect_playback(s: *mut pa_stream, - dev: *const c_char, - attr: *const pa_buffer_attr, -@@ -112,6 +122,7 @@ mod static_fns { - pub fn pa_stream_get_latency(s: *const pa_stream, r_usec: *mut pa_usec_t, negative: *mut c_int) -> c_int; - pub fn pa_stream_get_sample_spec(s: *const pa_stream) -> *const pa_sample_spec; - pub fn pa_stream_get_state(p: *const pa_stream) -> pa_stream_state_t; -+ pub fn pa_stream_get_context(s: *const pa_stream) -> *mut pa_context; - pub fn pa_stream_get_time(s: *const pa_stream, r_usec: *mut pa_usec_t) -> c_int; - pub fn pa_stream_new(c: *mut pa_context, - name: *const c_char, -@@ -123,6 +134,7 @@ mod static_fns { - pub fn pa_stream_set_state_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void); - pub fn pa_stream_set_write_callback(p: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void); - pub fn pa_stream_set_read_callback(p: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void); -+ pub fn pa_stream_ref(s: *mut pa_stream) -> *mut pa_stream; - pub fn pa_stream_unref(s: *mut pa_stream); - pub fn pa_stream_update_timing_info(p: *mut pa_stream, - cb: pa_stream_success_cb_t, -@@ -148,8 +160,6 @@ mod static_fns { - pub fn pa_threaded_mainloop_unlock(m: *mut pa_threaded_mainloop); - pub fn pa_threaded_mainloop_wait(m: *mut pa_threaded_mainloop); - pub fn pa_usec_to_bytes(t: pa_usec_t, spec: *const pa_sample_spec) -> usize; -- pub fn pa_xfree(ptr: *mut c_void); -- pub fn pa_xstrdup(str: *const c_char) -> *mut c_char; - pub fn pa_xrealloc(ptr: *mut c_void, size: usize) -> *mut c_void; - } - } -@@ -159,9 +169,9 @@ pub use self::static_fns::*; - - #[cfg(feature = "dlopen")] - mod dynamic_fns { -- use std::os::raw::{c_char, c_double, c_int, c_float, c_uint, c_void}; -- use libc::{dlclose, dlopen, dlsym, RTLD_LAZY}; - use super::*; -+ use libc::{RTLD_LAZY, dlclose, dlopen, dlsym}; -+ use std::os::raw::{c_char, c_double, c_float, c_int, c_uint, c_void}; - - #[derive(Debug)] - pub struct LibLoader { -@@ -287,6 +297,13 @@ mod dynamic_fns { - } - fp - }; -+ PA_CONTEXT_ERRNO = { -+ let fp = dlsym(h, cstr!("pa_context_errno")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; - PA_CONTEXT_SET_SUBSCRIBE_CALLBACK = { - let fp = dlsym(h, cstr!("pa_context_set_subscribe_callback")); - if fp.is_null() { -@@ -301,6 +318,13 @@ mod dynamic_fns { - } - fp - }; -+ PA_CONTEXT_REF = { -+ let fp = dlsym(h, cstr!("pa_context_ref")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; - PA_CONTEXT_UNREF = { - let fp = dlsym(h, cstr!("pa_context_unref")); - if fp.is_null() { -@@ -336,8 +360,15 @@ mod dynamic_fns { - } - fp - }; -- PA_OPERATION_GET_STATE = { -- let fp = dlsym(h, cstr!("pa_operation_get_state")); -+ PA_STRERROR = { -+ let fp = dlsym(h, cstr!("pa_strerror")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; -+ PA_OPERATION_REF = { -+ let fp = dlsym(h, cstr!("pa_operation_ref")); - if fp.is_null() { - return None; - } -@@ -350,6 +381,27 @@ mod dynamic_fns { - } - fp - }; -+ PA_OPERATION_CANCEL = { -+ let fp = dlsym(h, cstr!("pa_operation_cancel")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; -+ PA_OPERATION_GET_STATE = { -+ let fp = dlsym(h, cstr!("pa_operation_get_state")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; -+ PA_OPERATION_SET_STATE_CALLBACK = { -+ let fp = dlsym(h, cstr!("pa_operation_set_state_callback")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; - PA_PROPLIST_GETS = { - let fp = dlsym(h, cstr!("pa_proplist_gets")); - if fp.is_null() { -@@ -378,6 +430,20 @@ mod dynamic_fns { - } - fp - }; -+ PA_STREAM_IS_SUSPENDED = { -+ let fp = dlsym(h, cstr!("pa_stream_is_suspended")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; -+ PA_STREAM_IS_CORKED = { -+ let fp = dlsym(h, cstr!("pa_stream_is_corked")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; - PA_STREAM_CONNECT_PLAYBACK = { - let fp = dlsym(h, cstr!("pa_stream_connect_playback")); - if fp.is_null() { -@@ -462,6 +528,13 @@ mod dynamic_fns { - } - fp - }; -+ PA_STREAM_GET_CONTEXT = { -+ let fp = dlsym(h, cstr!("pa_stream_get_context")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; - PA_STREAM_GET_TIME = { - let fp = dlsym(h, cstr!("pa_stream_get_time")); - if fp.is_null() { -@@ -511,6 +584,13 @@ mod dynamic_fns { - } - fp - }; -+ PA_STREAM_REF = { -+ let fp = dlsym(h, cstr!("pa_stream_ref")); -+ if fp.is_null() { -+ return None; -+ } -+ fp -+ }; - PA_STREAM_UNREF = { - let fp = dlsym(h, cstr!("pa_stream_unref")); - if fp.is_null() { -@@ -623,20 +703,6 @@ mod dynamic_fns { - } - fp - }; -- PA_XFREE = { -- let fp = dlsym(h, cstr!("pa_xfree")); -- if fp.is_null() { -- return None; -- } -- fp -- }; -- PA_XSTRDUP = { -- let fp = dlsym(h, cstr!("pa_xstrdup")); -- if fp.is_null() { -- return None; -- } -- fp -- }; - PA_XREALLOC = { - let fp = dlsym(h, cstr!("pa_xrealloc")); - if fp.is_null() { -@@ -837,6 +903,12 @@ mod dynamic_fns { - *mut c_void)>(PA_CONTEXT_SET_STATE_CALLBACK))(c, cb, userdata) - } - -+ static mut PA_CONTEXT_ERRNO: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_context_errno(c: *mut pa_context) -> c_int { -+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_context) -> c_int>(PA_CONTEXT_ERRNO))(c) -+ } -+ - static mut PA_CONTEXT_SET_SUBSCRIBE_CALLBACK: *mut ::libc::c_void = 0 as *mut _; - #[inline] - pub unsafe fn pa_context_set_subscribe_callback(c: *mut pa_context, -@@ -863,6 +935,12 @@ mod dynamic_fns { - -> *mut pa_operation>(PA_CONTEXT_SUBSCRIBE))(c, m, cb, userdata) - } - -+ static mut PA_CONTEXT_REF: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_context_ref(c: *mut pa_context) -> *mut pa_context { -+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_context) -> *mut pa_context>(PA_CONTEXT_REF))(c) -+ } -+ - static mut PA_CONTEXT_UNREF: *mut ::libc::c_void = 0 as *mut _; - #[inline] - pub unsafe fn pa_context_unref(c: *mut pa_context) { -@@ -907,6 +985,30 @@ mod dynamic_fns { - *mut c_void)>(PA_MAINLOOP_API_ONCE))(m, callback, userdata) - } - -+ static mut PA_STRERROR: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_strerror(error: pa_error_code_t) -> *const c_char { -+ (::std::mem::transmute::<_, extern "C" fn(pa_error_code_t) -> *const c_char>(PA_STRERROR))(error) -+ } -+ -+ static mut PA_OPERATION_REF: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_operation_ref(o: *mut pa_operation) -> *mut pa_operation { -+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_operation) -> *mut pa_operation>(PA_OPERATION_REF))(o) -+ } -+ -+ static mut PA_OPERATION_UNREF: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_operation_unref(o: *mut pa_operation) { -+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_operation)>(PA_OPERATION_UNREF))(o) -+ } -+ -+ static mut PA_OPERATION_CANCEL: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_operation_cancel(o: *mut pa_operation) { -+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_operation)>(PA_OPERATION_CANCEL))(o) -+ } -+ - static mut PA_OPERATION_GET_STATE: *mut ::libc::c_void = 0 as *mut _; - #[inline] - pub unsafe fn pa_operation_get_state(o: *const pa_operation) -> pa_operation_state_t { -@@ -915,10 +1017,15 @@ mod dynamic_fns { - -> pa_operation_state_t>(PA_OPERATION_GET_STATE))(o) - } - -- static mut PA_OPERATION_UNREF: *mut ::libc::c_void = 0 as *mut _; -+ static mut PA_OPERATION_SET_STATE_CALLBACK: *mut ::libc::c_void = 0 as *mut _; - #[inline] -- pub unsafe fn pa_operation_unref(o: *mut pa_operation) { -- (::std::mem::transmute::<_, extern "C" fn(*mut pa_operation)>(PA_OPERATION_UNREF))(o) -+ pub unsafe fn pa_operation_set_state_callback(o: *mut pa_operation, -+ cb: pa_operation_notify_cb_t, -+ userdata: *mut c_void) { -+ (::std::mem::transmute::<_, -+ extern "C" fn(*mut pa_operation, -+ pa_operation_notify_cb_t, -+ *mut c_void)>(PA_OPERATION_SET_STATE_CALLBACK))(o, cb, userdata) - } - - static mut PA_PROPLIST_GETS: *mut ::libc::c_void = 0 as *mut _; -@@ -951,6 +1058,18 @@ mod dynamic_fns { - (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> c_int>(PA_STREAM_CANCEL_WRITE))(p) - } - -+ static mut PA_STREAM_IS_SUSPENDED: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_stream_is_suspended(s: *const pa_stream) -> c_int { -+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> c_int>(PA_STREAM_IS_SUSPENDED))(s) -+ } -+ -+ static mut PA_STREAM_IS_CORKED: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_stream_is_corked(s: *const pa_stream) -> c_int { -+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> c_int>(PA_STREAM_IS_CORKED))(s) -+ } -+ - static mut PA_STREAM_CONNECT_PLAYBACK: *mut ::libc::c_void = 0 as *mut _; - #[inline] - pub unsafe fn pa_stream_connect_playback(s: *mut pa_stream, -@@ -1066,6 +1185,12 @@ mod dynamic_fns { - (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> pa_stream_state_t>(PA_STREAM_GET_STATE))(p) - } - -+ static mut PA_STREAM_GET_CONTEXT: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_stream_get_context(s: *const pa_stream) -> *mut pa_context { -+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> *mut pa_context>(PA_STREAM_GET_CONTEXT))(s) -+ } -+ - static mut PA_STREAM_GET_TIME: *mut ::libc::c_void = 0 as *mut _; - #[inline] - pub unsafe fn pa_stream_get_time(s: *const pa_stream, r_usec: *mut pa_usec_t) -> c_int { -@@ -1132,6 +1257,12 @@ mod dynamic_fns { - *mut c_void)>(PA_STREAM_SET_READ_CALLBACK))(p, cb, userdata) - } - -+ static mut PA_STREAM_REF: *mut ::libc::c_void = 0 as *mut _; -+ #[inline] -+ pub unsafe fn pa_stream_ref(s: *mut pa_stream) -> *mut pa_stream { -+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> *mut pa_stream>(PA_STREAM_REF))(s) -+ } -+ - static mut PA_STREAM_UNREF: *mut ::libc::c_void = 0 as *mut _; - #[inline] - pub unsafe fn pa_stream_unref(s: *mut pa_stream) { -@@ -1253,18 +1384,6 @@ mod dynamic_fns { - spec) - } - -- static mut PA_XFREE: *mut ::libc::c_void = 0 as *mut _; -- #[inline] -- pub unsafe fn pa_xfree(ptr: *mut c_void) { -- (::std::mem::transmute::<_, extern "C" fn(*mut c_void)>(PA_XFREE))(ptr) -- } -- -- static mut PA_XSTRDUP: *mut ::libc::c_void = 0 as *mut _; -- #[inline] -- pub unsafe fn pa_xstrdup(str: *const c_char) -> *mut c_char { -- (::std::mem::transmute::<_, extern "C" fn(*const c_char) -> *mut c_char>(PA_XSTRDUP))(str) -- } -- - static mut PA_XREALLOC: *mut ::libc::c_void = 0 as *mut _; - #[inline] - pub unsafe fn pa_xrealloc(ptr: *mut c_void, size: usize) -> *mut c_void { -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_types.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_types.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_types.rs.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_types.rs 2017-08-04 13:37:46.384821737 +0200 -@@ -1,6 +1,6 @@ - #![allow(non_camel_case_types)] - --use std::os::raw::{c_char, c_int, c_long, c_ulong, c_void}; -+use std::os::raw::{c_char, c_int, c_long, c_uint, c_ulong, c_void}; - - /* automatically generated by rust-bindgen */ - pub const PA_RATE_MAX: u32 = 48000 * 8; -@@ -74,10 +74,10 @@ pub const PA_OPERATION_DONE: c_int = 1; - pub const PA_OPERATION_CANCELLED: c_int = 2; - pub type pa_operation_state_t = c_int; - --pub const PA_CONTEXT_NOFLAGS: c_int = 0; --pub const PA_CONTEXT_NOAUTOSPAWN: c_int = 1; --pub const PA_CONTEXT_NOFAIL: c_int = 2; --pub type pa_context_flags_t = c_int; -+pub const PA_CONTEXT_NOFLAGS: c_uint = 0; -+pub const PA_CONTEXT_NOAUTOSPAWN: c_uint = 1; -+pub const PA_CONTEXT_NOFAIL: c_uint = 2; -+pub type pa_context_flags_t = c_uint; - - pub const PA_DIRECTION_OUTPUT: c_int = 1; - pub const PA_DIRECTION_INPUT: c_int = 2; -@@ -93,28 +93,28 @@ pub const PA_STREAM_RECORD: c_int = 2; - pub const PA_STREAM_UPLOAD: c_int = 3; - pub type pa_stream_direction_t = c_int; - --pub const PA_STREAM_NOFLAGS: c_int = 0x0_0000; --pub const PA_STREAM_START_CORKED: c_int = 0x0_0001; --pub const PA_STREAM_INTERPOLATE_TIMING: c_int = 0x0_0002; --pub const PA_STREAM_NOT_MONOTONIC: c_int = 0x0_0004; --pub const PA_STREAM_AUTO_TIMING_UPDATE: c_int = 0x0_0008; --pub const PA_STREAM_NO_REMAP_CHANNELS: c_int = 0x0_0010; --pub const PA_STREAM_NO_REMIX_CHANNELS: c_int = 0x0_0020; --pub const PA_STREAM_FIX_FORMAT: c_int = 0x0_0040; --pub const PA_STREAM_FIX_RATE: c_int = 0x0_0080; --pub const PA_STREAM_FIX_CHANNELS: c_int = 0x0_0100; --pub const PA_STREAM_DONT_MOVE: c_int = 0x0_0200; --pub const PA_STREAM_VARIABLE_RATE: c_int = 0x0_0400; --pub const PA_STREAM_PEAK_DETECT: c_int = 0x0_0800; --pub const PA_STREAM_START_MUTED: c_int = 0x0_1000; --pub const PA_STREAM_ADJUST_LATENCY: c_int = 0x0_2000; --pub const PA_STREAM_EARLY_REQUESTS: c_int = 0x0_4000; --pub const PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND: c_int = 0x0_8000; --pub const PA_STREAM_START_UNMUTED: c_int = 0x1_0000; --pub const PA_STREAM_FAIL_ON_SUSPEND: c_int = 0x2_0000; --pub const PA_STREAM_RELATIVE_VOLUME: c_int = 0x4_0000; --pub const PA_STREAM_PASSTHROUGH: c_int = 0x8_0000; --pub type pa_stream_flags_t = c_int; -+pub const PA_STREAM_NOFLAGS: c_uint = 0x0_0000; -+pub const PA_STREAM_START_CORKED: c_uint = 0x0_0001; -+pub const PA_STREAM_INTERPOLATE_TIMING: c_uint = 0x0_0002; -+pub const PA_STREAM_NOT_MONOTONIC: c_uint = 0x0_0004; -+pub const PA_STREAM_AUTO_TIMING_UPDATE: c_uint = 0x0_0008; -+pub const PA_STREAM_NO_REMAP_CHANNELS: c_uint = 0x0_0010; -+pub const PA_STREAM_NO_REMIX_CHANNELS: c_uint = 0x0_0020; -+pub const PA_STREAM_FIX_FORMAT: c_uint = 0x0_0040; -+pub const PA_STREAM_FIX_RATE: c_uint = 0x0_0080; -+pub const PA_STREAM_FIX_CHANNELS: c_uint = 0x0_0100; -+pub const PA_STREAM_DONT_MOVE: c_uint = 0x0_0200; -+pub const PA_STREAM_VARIABLE_RATE: c_uint = 0x0_0400; -+pub const PA_STREAM_PEAK_DETECT: c_uint = 0x0_0800; -+pub const PA_STREAM_START_MUTED: c_uint = 0x0_1000; -+pub const PA_STREAM_ADJUST_LATENCY: c_uint = 0x0_2000; -+pub const PA_STREAM_EARLY_REQUESTS: c_uint = 0x0_4000; -+pub const PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND: c_uint = 0x0_8000; -+pub const PA_STREAM_START_UNMUTED: c_uint = 0x1_0000; -+pub const PA_STREAM_FAIL_ON_SUSPEND: c_uint = 0x2_0000; -+pub const PA_STREAM_RELATIVE_VOLUME: c_uint = 0x4_0000; -+pub const PA_STREAM_PASSTHROUGH: c_uint = 0x8_0000; -+pub type pa_stream_flags_t = c_uint; - - #[repr(C)] - #[derive(Clone, Copy, Debug)] -@@ -162,19 +162,19 @@ pub const PA_ERR_BUSY: c_int = 26; - pub const PA_ERR_MAX: c_int = 27; - pub type pa_error_code_t = c_int; - --pub const PA_SUBSCRIPTION_MASK_NULL: c_int = 0; --pub const PA_SUBSCRIPTION_MASK_SINK: c_int = 1; --pub const PA_SUBSCRIPTION_MASK_SOURCE: c_int = 2; --pub const PA_SUBSCRIPTION_MASK_SINK_INPUT: c_int = 4; --pub const PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT: c_int = 8; --pub const PA_SUBSCRIPTION_MASK_MODULE: c_int = 16; --pub const PA_SUBSCRIPTION_MASK_CLIENT: c_int = 32; --pub const PA_SUBSCRIPTION_MASK_SAMPLE_CACHE: c_int = 64; --pub const PA_SUBSCRIPTION_MASK_SERVER: c_int = 128; --pub const PA_SUBSCRIPTION_MASK_AUTOLOAD: c_int = 256; --pub const PA_SUBSCRIPTION_MASK_CARD: c_int = 512; --pub const PA_SUBSCRIPTION_MASK_ALL: c_int = 767; --pub type pa_subscription_mask_t = c_int; -+pub const PA_SUBSCRIPTION_MASK_NULL: c_uint = 0x0; -+pub const PA_SUBSCRIPTION_MASK_SINK: c_uint = 0x1; -+pub const PA_SUBSCRIPTION_MASK_SOURCE: c_uint = 0x2; -+pub const PA_SUBSCRIPTION_MASK_SINK_INPUT: c_uint = 0x4; -+pub const PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT: c_uint = 0x8; -+pub const PA_SUBSCRIPTION_MASK_MODULE: c_uint = 0x10; -+pub const PA_SUBSCRIPTION_MASK_CLIENT: c_uint = 0x20; -+pub const PA_SUBSCRIPTION_MASK_SAMPLE_CACHE: c_uint = 0x40; -+pub const PA_SUBSCRIPTION_MASK_SERVER: c_uint = 0x80; -+pub const PA_SUBSCRIPTION_MASK_AUTOLOAD: c_uint = 0x100; -+pub const PA_SUBSCRIPTION_MASK_CARD: c_uint = 0x200; -+pub const PA_SUBSCRIPTION_MASK_ALL: c_uint = 0x3FF; -+pub type pa_subscription_mask_t = c_uint; - - pub const PA_SUBSCRIPTION_EVENT_SINK: c_int = 0; - pub const PA_SUBSCRIPTION_EVENT_SOURCE: c_int = 1; -@@ -244,17 +244,17 @@ pub const PA_SEEK_RELATIVE_ON_READ: c_in - pub const PA_SEEK_RELATIVE_END: c_int = 3; - pub type pa_seek_mode_t = c_int; - --pub const PA_SINK_NOFLAGS: c_int = 0; --pub const PA_SINK_HW_VOLUME_CTRL: c_int = 1; --pub const PA_SINK_LATENCY: c_int = 2; --pub const PA_SINK_HARDWARE: c_int = 4; --pub const PA_SINK_NETWORK: c_int = 8; --pub const PA_SINK_HW_MUTE_CTRL: c_int = 16; --pub const PA_SINK_DECIBEL_VOLUME: c_int = 32; --pub const PA_SINK_FLAT_VOLUME: c_int = 64; --pub const PA_SINK_DYNAMIC_LATENCY: c_int = 128; --pub const PA_SINK_SET_FORMATS: c_int = 256; --pub type pa_sink_flags_t = c_int; -+pub const PA_SINK_NOFLAGS: c_uint = 0x000; -+pub const PA_SINK_HW_VOLUME_CTRL: c_uint = 0x001; -+pub const PA_SINK_LATENCY: c_uint = 0x002; -+pub const PA_SINK_HARDWARE: c_uint = 0x004; -+pub const PA_SINK_NETWORK: c_uint = 0x008; -+pub const PA_SINK_HW_MUTE_CTRL: c_uint = 0x010; -+pub const PA_SINK_DECIBEL_VOLUME: c_uint = 0x020; -+pub const PA_SINK_FLAT_VOLUME: c_uint = 0x040; -+pub const PA_SINK_DYNAMIC_LATENCY: c_uint = 0x080; -+pub const PA_SINK_SET_FORMATS: c_uint = 0x100; -+pub type pa_sink_flags_t = c_uint; - - pub const PA_SINK_INVALID_STATE: c_int = -1; - pub const PA_SINK_RUNNING: c_int = 0; -@@ -264,16 +264,16 @@ pub const PA_SINK_INIT: c_int = -2; - pub const PA_SINK_UNLINKED: c_int = -3; - pub type pa_sink_state_t = c_int; - --pub const PA_SOURCE_NOFLAGS: c_int = 0x00; --pub const PA_SOURCE_HW_VOLUME_CTRL: c_int = 0x01; --pub const PA_SOURCE_LATENCY: c_int = 0x02; --pub const PA_SOURCE_HARDWARE: c_int = 0x04; --pub const PA_SOURCE_NETWORK: c_int = 0x08; --pub const PA_SOURCE_HW_MUTE_CTRL: c_int = 0x10; --pub const PA_SOURCE_DECIBEL_VOLUME: c_int = 0x20; --pub const PA_SOURCE_DYNAMIC_LATENCY: c_int = 0x40; --pub const PA_SOURCE_FLAT_VOLUME: c_int = 0x80; --pub type pa_source_flags_t = c_int; -+pub const PA_SOURCE_NOFLAGS: c_uint = 0x00; -+pub const PA_SOURCE_HW_VOLUME_CTRL: c_uint = 0x01; -+pub const PA_SOURCE_LATENCY: c_uint = 0x02; -+pub const PA_SOURCE_HARDWARE: c_uint = 0x04; -+pub const PA_SOURCE_NETWORK: c_uint = 0x08; -+pub const PA_SOURCE_HW_MUTE_CTRL: c_uint = 0x10; -+pub const PA_SOURCE_DECIBEL_VOLUME: c_uint = 0x20; -+pub const PA_SOURCE_DYNAMIC_LATENCY: c_uint = 0x40; -+pub const PA_SOURCE_FLAT_VOLUME: c_uint = 0x80; -+pub type pa_source_flags_t = c_uint; - - pub const PA_SOURCE_INVALID_STATE: c_int = -1; - pub const PA_SOURCE_RUNNING: c_int = 0; -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/Cargo.toml.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/Cargo.toml ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/Cargo.toml.cubeb-pulse-arm 2017-08-04 13:37:46.384821737 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/Cargo.toml 2017-08-04 13:37:46.384821737 +0200 -@@ -0,0 +1,8 @@ -+[package] -+name = "pulse" -+version = "0.1.0" -+authors = ["Dan Glastonbury "] -+ -+[dependencies] -+bitflags = "^0.7.0" -+pulse-ffi = { path = "../pulse-ffi" } -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/context.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/context.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/context.rs.cubeb-pulse-arm 2017-08-04 13:37:46.385821734 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/context.rs 2017-08-04 13:37:46.385821734 +0200 -@@ -0,0 +1,394 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+use ::*; -+use ffi; -+use std::ffi::CStr; -+use std::os::raw::{c_int, c_void}; -+use std::ptr; -+use util::UnwrapCStr; -+ -+// A note about `wrapped` functions -+// -+// C FFI demands `unsafe extern fn(*mut pa_context, ...) -> i32`, etc, -+// but we want to allow such callbacks to be safe. This means no -+// `unsafe` or `extern`, and callbacks should be called with a safe -+// wrapper of `*mut pa_context`. Since the callback doesn't take -+// ownership, this is `&Context`. `fn wrapped(...)` defines a -+// function that converts from our safe signature to the unsafe -+// signature. -+// -+// Currently, we use a property of Rust, namely that each function -+// gets its own unique type. These unique types can't be written -+// directly, so we use generic and a type parameter, and let the Rust -+// compiler fill in the name for us: -+// -+// fn get_sink_input_info(&self, ..., _: CB, ...) -> ... -+// where CB: Fn(&Context, *const SinkInputInfo, i32, *mut c_void) -+// -+// Because we aren't storing or passing any state, we assert, at run-time :-(, -+// that our functions are zero-sized: -+// -+// assert!(mem::size_of::() == 0); -+// -+// We need to obtain a value of type F in order to call it. Since we -+// can't name the function, we have to unsafely construct that value -+// somehow - we do this using mem::uninitialized. Then, we call that -+// function with a reference to the Context, and save the result: -+// -+// | generate value || call it | -+// let result = ::std::mem::uninitialized::()(&mut object); -+// -+// Lastly, since our Object is an owned type, we need to avoid -+// dropping it, then return the result we just generated. -+// -+// mem::forget(object); -+// result -+ -+// Aid in returning Operation from callbacks -+macro_rules! op_or_err { -+ ($self_:ident, $e:expr) => {{ -+ let o = unsafe { $e }; -+ if o.is_null() { -+ Err(ErrorCode::from_error_code($self_.errno())) -+ } else { -+ Ok(unsafe { operation::from_raw_ptr(o) }) -+ } -+ }} -+} -+ -+#[repr(C)] -+#[derive(Debug)] -+pub struct Context(*mut ffi::pa_context); -+ -+impl Context { -+ pub fn new<'a, OPT>(api: &MainloopApi, name: OPT) -> Option -+ where OPT: Into> -+ { -+ let ptr = unsafe { ffi::pa_context_new(api.raw_mut(), name.unwrap_cstr()) }; -+ if ptr.is_null() { -+ None -+ } else { -+ Some(Context(ptr)) -+ } -+ } -+ -+ #[doc(hidden)] -+ pub fn raw_mut(&self) -> &mut ffi::pa_context { -+ unsafe { &mut *self.0 } -+ } -+ -+ pub fn unref(self) { -+ unsafe { -+ ffi::pa_context_unref(self.raw_mut()); -+ } -+ } -+ -+ pub fn clear_state_callback(&self) { -+ unsafe { -+ ffi::pa_context_set_state_callback(self.raw_mut(), None, ptr::null_mut()); -+ } -+ } -+ -+ pub fn set_state_callback(&self, _: CB, userdata: *mut c_void) -+ where CB: Fn(&Context, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, userdata: *mut c_void) -+ where F: Fn(&Context, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ unsafe { -+ ffi::pa_context_set_state_callback(self.raw_mut(), Some(wrapped::), userdata); -+ } -+ } -+ -+ pub fn errno(&self) -> ffi::pa_error_code_t { -+ unsafe { ffi::pa_context_errno(self.raw_mut()) } -+ } -+ -+ pub fn get_state(&self) -> ContextState { -+ ContextState::try_from(unsafe { -+ ffi::pa_context_get_state(self.raw_mut()) -+ }).expect("pa_context_get_state returned invalid ContextState") -+ } -+ -+ pub fn connect<'a, OPT>(&self, server: OPT, flags: ContextFlags, api: *const ffi::pa_spawn_api) -> Result<()> -+ where OPT: Into> -+ { -+ let r = unsafe { -+ ffi::pa_context_connect(self.raw_mut(), -+ server.into().unwrap_cstr(), -+ flags.into(), -+ api) -+ }; -+ error_result!((), r) -+ } -+ -+ pub fn disconnect(&self) { -+ unsafe { -+ ffi::pa_context_disconnect(self.raw_mut()); -+ } -+ } -+ -+ -+ pub fn drain(&self, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Context, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, userdata: *mut c_void) -+ where F: Fn(&Context, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ op_or_err!(self, -+ ffi::pa_context_drain(self.raw_mut(), Some(wrapped::), userdata)) -+ } -+ -+ pub fn rttime_new(&self, usec: USec, _: CB, userdata: *mut c_void) -> *mut ffi::pa_time_event -+ where CB: Fn(&MainloopApi, *mut ffi::pa_time_event, &TimeVal, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(a: *mut ffi::pa_mainloop_api, -+ e: *mut ffi::pa_time_event, -+ tv: *const TimeVal, -+ userdata: *mut c_void) -+ where F: Fn(&MainloopApi, *mut ffi::pa_time_event, &TimeVal, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let api = mainloop_api::from_raw_ptr(a); -+ let timeval = &*tv; -+ let result = uninitialized::()(&api, e, timeval, userdata); -+ forget(api); -+ -+ result -+ } -+ -+ unsafe { ffi::pa_context_rttime_new(self.raw_mut(), usec, Some(wrapped::), userdata) } -+ } -+ -+ pub fn get_server_info(&self, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Context, &ServerInfo, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, i: *const ffi::pa_server_info, userdata: *mut c_void) -+ where F: Fn(&Context, &ServerInfo, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ debug_assert_ne!(i, ptr::null_mut()); -+ let info = &*i; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, info, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ op_or_err!(self, -+ ffi::pa_context_get_server_info(self.raw_mut(), Some(wrapped::), userdata)) -+ } -+ -+ pub fn get_sink_info_by_name(&self, name: &CStr, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Context, *const SinkInfo, i32, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, -+ info: *const ffi::pa_sink_info, -+ eol: c_int, -+ userdata: *mut c_void) -+ where F: Fn(&Context, *const SinkInfo, i32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, info, eol, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ op_or_err!(self, -+ ffi::pa_context_get_sink_info_by_name(self.raw_mut(), name.as_ptr(), Some(wrapped::), userdata)) -+ } -+ -+ pub fn get_sink_info_list(&self, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Context, *const SinkInfo, i32, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, -+ info: *const ffi::pa_sink_info, -+ eol: c_int, -+ userdata: *mut c_void) -+ where F: Fn(&Context, *const SinkInfo, i32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, info, eol, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ op_or_err!(self, -+ ffi::pa_context_get_sink_info_list(self.raw_mut(), Some(wrapped::), userdata)) -+ } -+ -+ pub fn get_sink_input_info(&self, idx: u32, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Context, *const SinkInputInfo, i32, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, -+ info: *const ffi::pa_sink_input_info, -+ eol: c_int, -+ userdata: *mut c_void) -+ where F: Fn(&Context, *const SinkInputInfo, i32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, info, eol, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ op_or_err!(self, -+ ffi::pa_context_get_sink_input_info(self.raw_mut(), idx, Some(wrapped::), userdata)) -+ } -+ -+ pub fn get_source_info_list(&self, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Context, *const SourceInfo, i32, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, -+ info: *const ffi::pa_source_info, -+ eol: c_int, -+ userdata: *mut c_void) -+ where F: Fn(&Context, *const SourceInfo, i32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, info, eol, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ op_or_err!(self, -+ ffi::pa_context_get_source_info_list(self.raw_mut(), Some(wrapped::), userdata)) -+ } -+ -+ pub fn set_sink_input_volume(&self, -+ idx: u32, -+ volume: &CVolume, -+ _: CB, -+ userdata: *mut c_void) -+ -> Result -+ where CB: Fn(&Context, i32, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, success: c_int, userdata: *mut c_void) -+ where F: Fn(&Context, i32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, success, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ op_or_err!(self, -+ ffi::pa_context_set_sink_input_volume(self.raw_mut(), idx, volume, Some(wrapped::), userdata)) -+ } -+ -+ pub fn subscribe(&self, m: SubscriptionMask, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Context, i32, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, success: c_int, userdata: *mut c_void) -+ where F: Fn(&Context, i32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let result = uninitialized::()(&ctx, success, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ op_or_err!(self, -+ ffi::pa_context_subscribe(self.raw_mut(), m.into(), Some(wrapped::), userdata)) -+ } -+ -+ pub fn clear_subscribe_callback(&self) { -+ unsafe { -+ ffi::pa_context_set_subscribe_callback(self.raw_mut(), None, ptr::null_mut()); -+ } -+ } -+ -+ pub fn set_subscribe_callback(&self, _: CB, userdata: *mut c_void) -+ where CB: Fn(&Context, SubscriptionEvent, u32, *mut c_void) -+ { -+ debug_assert_eq!(::std::mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(c: *mut ffi::pa_context, -+ t: ffi::pa_subscription_event_type_t, -+ idx: u32, -+ userdata: *mut c_void) -+ where F: Fn(&Context, SubscriptionEvent, u32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let ctx = context::from_raw_ptr(c); -+ let event = SubscriptionEvent::try_from(t) -+ .expect("pa_context_subscribe_cb_t passed invalid pa_subscription_event_type_t"); -+ let result = uninitialized::()(&ctx, event, idx, userdata); -+ forget(ctx); -+ -+ result -+ } -+ -+ unsafe { -+ ffi::pa_context_set_subscribe_callback(self.raw_mut(), Some(wrapped::), userdata); -+ } -+ } -+} -+ -+#[doc(hidden)] -+pub unsafe fn from_raw_ptr(ptr: *mut ffi::pa_context) -> Context { -+ Context(ptr) -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/error.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/error.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/error.rs.cubeb-pulse-arm 2017-08-04 13:37:46.385821734 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/error.rs 2017-08-04 13:37:46.385821734 +0200 -@@ -0,0 +1,56 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+use ffi; -+use std::ffi::CStr; -+ -+#[macro_export] -+macro_rules! error_result { -+ ($t:expr, $err:expr) => { -+ if $err >= 0 { -+ Ok($t) -+ } else { -+ Err(ErrorCode::from_error_result($err)) -+ } -+ } -+} -+ -+#[derive(Debug, PartialEq)] -+pub struct ErrorCode { -+ err: ffi::pa_error_code_t, -+} -+ -+impl ErrorCode { -+ pub fn from_error_result(err: i32) -> Self { -+ debug_assert!(err < 0); -+ ErrorCode { -+ err: (-err) as ffi::pa_error_code_t, -+ } -+ } -+ -+ pub fn from_error_code(err: ffi::pa_error_code_t) -> Self { -+ debug_assert!(err > 0); -+ ErrorCode { -+ err: err, -+ } -+ } -+ -+ fn desc(&self) -> &'static str { -+ let cstr = unsafe { CStr::from_ptr(ffi::pa_strerror(self.err)) }; -+ cstr.to_str().unwrap() -+ } -+} -+ -+impl ::std::error::Error for ErrorCode { -+ fn description(&self) -> &str { -+ self.desc() -+ } -+} -+ -+impl ::std::fmt::Display for ErrorCode { -+ fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { -+ write!(f, "{:?}: {}", self, self.desc()) -+ } -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs.cubeb-pulse-arm 2017-08-04 13:37:46.385821734 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs 2017-08-04 13:37:46.385821734 +0200 -@@ -0,0 +1,653 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+#[macro_use] -+extern crate bitflags; -+extern crate pulse_ffi as ffi; -+ -+#[macro_use] -+mod error; -+mod context; -+mod mainloop_api; -+mod operation; -+mod proplist; -+mod stream; -+mod threaded_mainloop; -+mod util; -+ -+pub use context::Context; -+pub use error::ErrorCode; -+pub use ffi::pa_buffer_attr as BufferAttr; -+pub use ffi::pa_channel_map as ChannelMap; -+pub use ffi::pa_cvolume as CVolume; -+pub use ffi::pa_sample_spec as SampleSpec; -+pub use ffi::pa_server_info as ServerInfo; -+pub use ffi::pa_sink_info as SinkInfo; -+pub use ffi::pa_sink_input_info as SinkInputInfo; -+pub use ffi::pa_source_info as SourceInfo; -+pub use ffi::pa_usec_t as USec; -+pub use ffi::pa_volume_t as Volume; -+pub use ffi::timeval as TimeVal; -+pub use mainloop_api::MainloopApi; -+pub use operation::Operation; -+pub use proplist::Proplist; -+use std::os::raw::{c_char, c_uint}; -+pub use stream::Stream; -+pub use threaded_mainloop::ThreadedMainloop; -+ -+#[allow(non_camel_case_types)] -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum SampleFormat { -+ Invalid = ffi::PA_SAMPLE_INVALID, -+ U8 = ffi::PA_SAMPLE_U8, -+ Alaw = ffi::PA_SAMPLE_ALAW, -+ Ulaw = ffi::PA_SAMPLE_ULAW, -+ Signed16LE = ffi::PA_SAMPLE_S16LE, -+ Signed16BE = ffi::PA_SAMPLE_S16BE, -+ Float32LE = ffi::PA_SAMPLE_FLOAT32LE, -+ Float32BE = ffi::PA_SAMPLE_FLOAT32BE, -+ Signed32LE = ffi::PA_SAMPLE_S32LE, -+ Signed32BE = ffi::PA_SAMPLE_S32BE, -+ Signed24LE = ffi::PA_SAMPLE_S24LE, -+ Signed24BE = ffi::PA_SAMPLE_S24BE, -+ Signed24_32LE = ffi::PA_SAMPLE_S24_32LE, -+ Signed23_32BE = ffi::PA_SAMPLE_S24_32BE, -+} -+ -+impl Default for SampleFormat { -+ fn default() -> Self { -+ SampleFormat::Invalid -+ } -+} -+ -+impl Into for SampleFormat { -+ fn into(self) -> ffi::pa_sample_format_t { -+ self as ffi::pa_sample_format_t -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum ContextState { -+ Unconnected = ffi::PA_CONTEXT_UNCONNECTED, -+ Connecting = ffi::PA_CONTEXT_CONNECTING, -+ Authorizing = ffi::PA_CONTEXT_AUTHORIZING, -+ SettingName = ffi::PA_CONTEXT_SETTING_NAME, -+ Ready = ffi::PA_CONTEXT_READY, -+ Failed = ffi::PA_CONTEXT_FAILED, -+ Terminated = ffi::PA_CONTEXT_TERMINATED, -+} -+ -+impl ContextState { -+ // This function implements the PA_CONTENT_IS_GOOD macro from pulse/def.h -+ // It must match the version from PA headers. -+ pub fn is_good(self) -> bool { -+ match self { -+ ContextState::Connecting | -+ ContextState::Authorizing | -+ ContextState::SettingName | -+ ContextState::Ready => true, -+ _ => false, -+ } -+ } -+ -+ pub fn try_from(x: ffi::pa_context_state_t) -> Option { -+ if x >= ffi::PA_CONTEXT_UNCONNECTED && x <= ffi::PA_CONTEXT_TERMINATED { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Default for ContextState { -+ fn default() -> Self { -+ ContextState::Unconnected -+ } -+} -+ -+impl Into for ContextState { -+ fn into(self) -> ffi::pa_context_state_t { -+ self as ffi::pa_context_state_t -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum StreamState { -+ Unconnected = ffi::PA_STREAM_UNCONNECTED, -+ Creating = ffi::PA_STREAM_CREATING, -+ Ready = ffi::PA_STREAM_READY, -+ Failed = ffi::PA_STREAM_FAILED, -+ Terminated = ffi::PA_STREAM_TERMINATED, -+} -+ -+impl StreamState { -+ // This function implements the PA_STREAM_IS_GOOD macro from pulse/def.h -+ // It must match the version from PA headers. -+ pub fn is_good(self) -> bool { -+ match self { -+ StreamState::Creating | StreamState::Ready => true, -+ _ => false, -+ } -+ } -+ -+ pub fn try_from(x: ffi::pa_stream_state_t) -> Option { -+ if x >= ffi::PA_STREAM_UNCONNECTED && x <= ffi::PA_STREAM_TERMINATED { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Default for StreamState { -+ fn default() -> Self { -+ StreamState::Unconnected -+ } -+} -+ -+impl Into for StreamState { -+ fn into(self) -> ffi::pa_stream_state_t { -+ self as ffi::pa_stream_state_t -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum OperationState { -+ Running = ffi::PA_OPERATION_RUNNING, -+ Done = ffi::PA_OPERATION_DONE, -+ Cancelled = ffi::PA_OPERATION_CANCELLED, -+} -+ -+impl OperationState { -+ pub fn try_from(x: ffi::pa_operation_state_t) -> Option { -+ if x >= ffi::PA_OPERATION_RUNNING && x <= ffi::PA_OPERATION_CANCELLED { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Into for OperationState { -+ fn into(self) -> ffi::pa_operation_state_t { -+ self as ffi::pa_operation_state_t -+ } -+} -+ -+bitflags! { -+ pub flags ContextFlags: u32 { -+ const CONTEXT_FLAGS_NOAUTOSPAWN = ffi::PA_CONTEXT_NOAUTOSPAWN, -+ const CONTEXT_FLAGS_NOFAIL = ffi::PA_CONTEXT_NOFAIL, -+ } -+} -+ -+impl Into for ContextFlags { -+ fn into(self) -> ffi::pa_context_flags_t { -+ self.bits() as ffi::pa_context_flags_t -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum DeviceType { -+ Sink = ffi::PA_DEVICE_TYPE_SINK, -+ Source = ffi::PA_DEVICE_TYPE_SOURCE, -+} -+ -+impl DeviceType { -+ pub fn try_from(x: ffi::pa_device_type_t) -> Option { -+ if x >= ffi::PA_DEVICE_TYPE_SINK && x <= ffi::PA_DEVICE_TYPE_SOURCE { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Into for DeviceType { -+ fn into(self) -> ffi::pa_device_type_t { -+ self as ffi::pa_device_type_t -+ } -+} -+ -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum StreamDirection { -+ NoDirection = ffi::PA_STREAM_NODIRECTION, -+ Playback = ffi::PA_STREAM_PLAYBACK, -+ Record = ffi::PA_STREAM_RECORD, -+ StreamUpload = ffi::PA_STREAM_UPLOAD, -+} -+ -+impl StreamDirection { -+ pub fn try_from(x: ffi::pa_stream_direction_t) -> Option { -+ if x >= ffi::PA_STREAM_NODIRECTION && x <= ffi::PA_STREAM_UPLOAD { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Into for StreamDirection { -+ fn into(self) -> ffi::pa_stream_direction_t { -+ self as ffi::pa_stream_direction_t -+ } -+} -+ -+bitflags! { -+ pub flags StreamFlags : u32 { -+ const STREAM_START_CORKED = ffi::PA_STREAM_START_CORKED, -+ const STREAM_INTERPOLATE_TIMING = ffi::PA_STREAM_INTERPOLATE_TIMING, -+ const STREAM_NOT_MONOTONIC = ffi::PA_STREAM_NOT_MONOTONIC, -+ const STREAM_AUTO_TIMING_UPDATE = ffi::PA_STREAM_AUTO_TIMING_UPDATE, -+ const STREAM_NO_REMAP_CHANNELS = ffi::PA_STREAM_NO_REMAP_CHANNELS, -+ const STREAM_NO_REMIX_CHANNELS = ffi::PA_STREAM_NO_REMIX_CHANNELS, -+ const STREAM_FIX_FORMAT = ffi::PA_STREAM_FIX_FORMAT, -+ const STREAM_FIX_RATE = ffi::PA_STREAM_FIX_RATE, -+ const STREAM_FIX_CHANNELS = ffi::PA_STREAM_FIX_CHANNELS, -+ const STREAM_DONT_MOVE = ffi::PA_STREAM_DONT_MOVE, -+ const STREAM_VARIABLE_RATE = ffi::PA_STREAM_VARIABLE_RATE, -+ const STREAM_PEAK_DETECT = ffi::PA_STREAM_PEAK_DETECT, -+ const STREAM_START_MUTED = ffi::PA_STREAM_START_MUTED, -+ const STREAM_ADJUST_LATENCY = ffi::PA_STREAM_ADJUST_LATENCY, -+ const STREAM_EARLY_REQUESTS = ffi::PA_STREAM_EARLY_REQUESTS, -+ const STREAM_DONT_INHIBIT_AUTO_SUSPEND = ffi::PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND, -+ const STREAM_START_UNMUTED = ffi::PA_STREAM_START_UNMUTED, -+ const STREAM_FAIL_ON_SUSPEND = ffi::PA_STREAM_FAIL_ON_SUSPEND, -+ const STREAM_RELATIVE_VOLUME = ffi::PA_STREAM_RELATIVE_VOLUME, -+ const STREAM_PASSTHROUGH = ffi::PA_STREAM_PASSTHROUGH, -+ } -+} -+ -+impl StreamFlags { -+ pub fn try_from(x: ffi::pa_stream_flags_t) -> Option { -+ if (x & -+ !(ffi::PA_STREAM_NOFLAGS | ffi::PA_STREAM_START_CORKED | ffi::PA_STREAM_INTERPOLATE_TIMING | -+ ffi::PA_STREAM_NOT_MONOTONIC | ffi::PA_STREAM_AUTO_TIMING_UPDATE | -+ ffi::PA_STREAM_NO_REMAP_CHANNELS | -+ ffi::PA_STREAM_NO_REMIX_CHANNELS | ffi::PA_STREAM_FIX_FORMAT | ffi::PA_STREAM_FIX_RATE | -+ ffi::PA_STREAM_FIX_CHANNELS | -+ ffi::PA_STREAM_DONT_MOVE | ffi::PA_STREAM_VARIABLE_RATE | ffi::PA_STREAM_PEAK_DETECT | -+ ffi::PA_STREAM_START_MUTED | ffi::PA_STREAM_ADJUST_LATENCY | -+ ffi::PA_STREAM_EARLY_REQUESTS | -+ ffi::PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND | -+ ffi::PA_STREAM_START_UNMUTED | ffi::PA_STREAM_FAIL_ON_SUSPEND | -+ ffi::PA_STREAM_RELATIVE_VOLUME | ffi::PA_STREAM_PASSTHROUGH)) == 0 { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Into for StreamFlags { -+ fn into(self) -> ffi::pa_stream_flags_t { -+ self.bits() as ffi::pa_stream_flags_t -+ } -+} -+ -+bitflags!{ -+ pub flags SubscriptionMask : u32 { -+ const SUBSCRIPTION_MASK_SINK = ffi::PA_SUBSCRIPTION_MASK_SINK, -+ const SUBSCRIPTION_MASK_SOURCE = ffi::PA_SUBSCRIPTION_MASK_SOURCE, -+ const SUBSCRIPTION_MASK_SINK_INPUT = ffi::PA_SUBSCRIPTION_MASK_SINK_INPUT, -+ const SUBSCRIPTION_MASK_SOURCE_OUTPUT = ffi::PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT, -+ const SUBSCRIPTION_MASK_MODULE = ffi::PA_SUBSCRIPTION_MASK_MODULE, -+ const SUBSCRIPTION_MASK_CLIENT = ffi::PA_SUBSCRIPTION_MASK_CLIENT, -+ const SUBSCRIPTION_MASK_SAMPLE_CACHE = ffi::PA_SUBSCRIPTION_MASK_SAMPLE_CACHE, -+ const SUBSCRIPTION_MASK_SERVER = ffi::PA_SUBSCRIPTION_MASK_SERVER, -+ const SUBSCRIPTION_MASK_AUTOLOAD = ffi::PA_SUBSCRIPTION_MASK_AUTOLOAD, -+ const SUBSCRIPTION_MASK_CARD = ffi::PA_SUBSCRIPTION_MASK_CARD, -+ } -+} -+ -+impl SubscriptionMask { -+ pub fn try_from(x: ffi::pa_subscription_mask_t) -> Option { -+ if (x & !ffi::PA_SUBSCRIPTION_MASK_ALL) == 0 { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Into for SubscriptionMask { -+ fn into(self) -> ffi::pa_subscription_mask_t { -+ self.bits() as ffi::pa_subscription_mask_t -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum SubscriptionEventFacility { -+ Sink = ffi::PA_SUBSCRIPTION_EVENT_SINK, -+ Source = ffi::PA_SUBSCRIPTION_EVENT_SOURCE, -+ SinkInput = ffi::PA_SUBSCRIPTION_EVENT_SINK_INPUT, -+ SourceOutput = ffi::PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT, -+ Module = ffi::PA_SUBSCRIPTION_EVENT_MODULE, -+ Client = ffi::PA_SUBSCRIPTION_EVENT_CLIENT, -+ SampleCache = ffi::PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE, -+ Server = ffi::PA_SUBSCRIPTION_EVENT_SERVER, -+ Autoload = ffi::PA_SUBSCRIPTION_EVENT_AUTOLOAD, -+ Card = ffi::PA_SUBSCRIPTION_EVENT_CARD, -+} -+ -+#[repr(C)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum SubscriptionEventType { -+ New, -+ Change, -+ Remove, -+} -+ -+#[repr(C)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub struct SubscriptionEvent(ffi::pa_subscription_event_type_t); -+impl SubscriptionEvent { -+ pub fn try_from(x: ffi::pa_subscription_event_type_t) -> Option { -+ if (x & !(ffi::PA_SUBSCRIPTION_EVENT_TYPE_MASK | ffi::PA_SUBSCRIPTION_EVENT_FACILITY_MASK)) == 0 { -+ Some(SubscriptionEvent(x)) -+ } else { -+ None -+ } -+ } -+ -+ pub fn event_facility(self) -> SubscriptionEventFacility { -+ unsafe { ::std::mem::transmute(self.0 & ffi::PA_SUBSCRIPTION_EVENT_FACILITY_MASK) } -+ } -+ -+ pub fn event_type(self) -> SubscriptionEventType { -+ unsafe { ::std::mem::transmute(((self.0 & ffi::PA_SUBSCRIPTION_EVENT_TYPE_MASK) >> 4)) } -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum SeekMode { -+ Relative = ffi::PA_SEEK_RELATIVE, -+ Absolute = ffi::PA_SEEK_ABSOLUTE, -+ RelativeOnRead = ffi::PA_SEEK_RELATIVE_ON_READ, -+ RelativeEnd = ffi::PA_SEEK_RELATIVE_END, -+} -+ -+impl SeekMode { -+ pub fn try_from(x: ffi::pa_seek_mode_t) -> Option { -+ if x >= ffi::PA_SEEK_RELATIVE && x <= ffi::PA_SEEK_RELATIVE_END { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Into for SeekMode { -+ fn into(self) -> ffi::pa_seek_mode_t { -+ self as ffi::pa_seek_mode_t -+ } -+} -+ -+bitflags! { -+ pub flags SinkFlags: u32 { -+ const SINK_HW_VOLUME_CTRL = ffi::PA_SINK_HW_VOLUME_CTRL, -+ const SINK_LATENCY = ffi::PA_SINK_LATENCY, -+ const SINK_HARDWARE = ffi::PA_SINK_HARDWARE, -+ const SINK_NETWORK = ffi::PA_SINK_NETWORK, -+ const SINK_HW_MUTE_CTRL = ffi::PA_SINK_HW_MUTE_CTRL, -+ const SINK_DECIBEL_VOLUME = ffi::PA_SINK_DECIBEL_VOLUME, -+ const SINK_FLAT_VOLUME = ffi::PA_SINK_FLAT_VOLUME, -+ const SINK_DYNAMIC_LATENCY = ffi::PA_SINK_DYNAMIC_LATENCY, -+ const SINK_SET_FORMATS = ffi::PA_SINK_SET_FORMATS, -+ } -+} -+ -+impl SinkFlags { -+ pub fn try_from(x: ffi::pa_sink_flags_t) -> Option { -+ if (x & -+ !(ffi::PA_SOURCE_NOFLAGS | ffi::PA_SOURCE_HW_VOLUME_CTRL | ffi::PA_SOURCE_LATENCY | -+ ffi::PA_SOURCE_HARDWARE | ffi::PA_SOURCE_NETWORK | ffi::PA_SOURCE_HW_MUTE_CTRL | -+ ffi::PA_SOURCE_DECIBEL_VOLUME | -+ ffi::PA_SOURCE_DYNAMIC_LATENCY | ffi::PA_SOURCE_FLAT_VOLUME)) == 0 { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum SinkState { -+ InvalidState = ffi::PA_SINK_INVALID_STATE, -+ Running = ffi::PA_SINK_RUNNING, -+ Idle = ffi::PA_SINK_IDLE, -+ Suspended = ffi::PA_SINK_SUSPENDED, -+ Init = ffi::PA_SINK_INIT, -+ Unlinked = ffi::PA_SINK_UNLINKED, -+} -+ -+bitflags!{ -+ pub flags SourceFlags: u32 { -+ const SOURCE_FLAGS_HW_VOLUME_CTRL = ffi::PA_SOURCE_HW_VOLUME_CTRL, -+ const SOURCE_FLAGS_LATENCY = ffi::PA_SOURCE_LATENCY, -+ const SOURCE_FLAGS_HARDWARE = ffi::PA_SOURCE_HARDWARE, -+ const SOURCE_FLAGS_NETWORK = ffi::PA_SOURCE_NETWORK, -+ const SOURCE_FLAGS_HW_MUTE_CTRL = ffi::PA_SOURCE_HW_MUTE_CTRL, -+ const SOURCE_FLAGS_DECIBEL_VOLUME = ffi::PA_SOURCE_DECIBEL_VOLUME, -+ const SOURCE_FLAGS_DYNAMIC_LATENCY = ffi::PA_SOURCE_DYNAMIC_LATENCY, -+ const SOURCE_FLAGS_FLAT_VOLUME = ffi::PA_SOURCE_FLAT_VOLUME, -+ } -+} -+ -+impl Into for SourceFlags { -+ fn into(self) -> ffi::pa_source_flags_t { -+ self.bits() as ffi::pa_source_flags_t -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum SourceState { -+ InvalidState = ffi::PA_SOURCE_INVALID_STATE, -+ Running = ffi::PA_SOURCE_RUNNING, -+ Idle = ffi::PA_SOURCE_IDLE, -+ Suspended = ffi::PA_SOURCE_SUSPENDED, -+ Init = ffi::PA_SOURCE_INIT, -+ Unlinked = ffi::PA_SOURCE_UNLINKED, -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum PortAvailable { -+ Unknown = ffi::PA_PORT_AVAILABLE_UNKNOWN, -+ No = ffi::PA_PORT_AVAILABLE_NO, -+ Yes = ffi::PA_PORT_AVAILABLE_YES, -+} -+ -+impl PortAvailable { -+ pub fn try_from(x: ffi::pa_port_available_t) -> Option { -+ if x >= ffi::PA_PORT_AVAILABLE_UNKNOWN && x <= ffi::PA_PORT_AVAILABLE_YES { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Into for PortAvailable { -+ fn into(self) -> ffi::pa_port_available_t { -+ self as ffi::pa_port_available_t -+ } -+} -+ -+#[repr(i32)] -+#[derive(Clone, Copy, Debug, PartialEq, Eq)] -+pub enum ChannelPosition { -+ Invalid = ffi::PA_CHANNEL_POSITION_INVALID, -+ Mono = ffi::PA_CHANNEL_POSITION_MONO, -+ FrontLeft = ffi::PA_CHANNEL_POSITION_FRONT_LEFT, -+ FrontRight = ffi::PA_CHANNEL_POSITION_FRONT_RIGHT, -+ FrontCenter = ffi::PA_CHANNEL_POSITION_FRONT_CENTER, -+ RearCenter = ffi::PA_CHANNEL_POSITION_REAR_CENTER, -+ RearLeft = ffi::PA_CHANNEL_POSITION_REAR_LEFT, -+ RearRight = ffi::PA_CHANNEL_POSITION_REAR_RIGHT, -+ LowFreqEffects = ffi::PA_CHANNEL_POSITION_LFE, -+ FrontLeftOfCenter = ffi::PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, -+ FrontRightOfCenter = ffi::PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, -+ SideLeft = ffi::PA_CHANNEL_POSITION_SIDE_LEFT, -+ SideRight = ffi::PA_CHANNEL_POSITION_SIDE_RIGHT, -+ Aux0 = ffi::PA_CHANNEL_POSITION_AUX0, -+ Aux1 = ffi::PA_CHANNEL_POSITION_AUX1, -+ Aux2 = ffi::PA_CHANNEL_POSITION_AUX2, -+ Aux3 = ffi::PA_CHANNEL_POSITION_AUX3, -+ Aux4 = ffi::PA_CHANNEL_POSITION_AUX4, -+ Aux5 = ffi::PA_CHANNEL_POSITION_AUX5, -+ Aux6 = ffi::PA_CHANNEL_POSITION_AUX6, -+ Aux7 = ffi::PA_CHANNEL_POSITION_AUX7, -+ Aux8 = ffi::PA_CHANNEL_POSITION_AUX8, -+ Aux9 = ffi::PA_CHANNEL_POSITION_AUX9, -+ Aux10 = ffi::PA_CHANNEL_POSITION_AUX10, -+ Aux11 = ffi::PA_CHANNEL_POSITION_AUX11, -+ Aux12 = ffi::PA_CHANNEL_POSITION_AUX12, -+ Aux13 = ffi::PA_CHANNEL_POSITION_AUX13, -+ Aux14 = ffi::PA_CHANNEL_POSITION_AUX14, -+ Aux15 = ffi::PA_CHANNEL_POSITION_AUX15, -+ Aux16 = ffi::PA_CHANNEL_POSITION_AUX16, -+ Aux17 = ffi::PA_CHANNEL_POSITION_AUX17, -+ Aux18 = ffi::PA_CHANNEL_POSITION_AUX18, -+ Aux19 = ffi::PA_CHANNEL_POSITION_AUX19, -+ Aux20 = ffi::PA_CHANNEL_POSITION_AUX20, -+ Aux21 = ffi::PA_CHANNEL_POSITION_AUX21, -+ Aux22 = ffi::PA_CHANNEL_POSITION_AUX22, -+ Aux23 = ffi::PA_CHANNEL_POSITION_AUX23, -+ Aux24 = ffi::PA_CHANNEL_POSITION_AUX24, -+ Aux25 = ffi::PA_CHANNEL_POSITION_AUX25, -+ Aux26 = ffi::PA_CHANNEL_POSITION_AUX26, -+ Aux27 = ffi::PA_CHANNEL_POSITION_AUX27, -+ Aux28 = ffi::PA_CHANNEL_POSITION_AUX28, -+ Aux29 = ffi::PA_CHANNEL_POSITION_AUX29, -+ Aux30 = ffi::PA_CHANNEL_POSITION_AUX30, -+ Aux31 = ffi::PA_CHANNEL_POSITION_AUX31, -+ TopCenter = ffi::PA_CHANNEL_POSITION_TOP_CENTER, -+ TopFrontLeft = ffi::PA_CHANNEL_POSITION_TOP_FRONT_LEFT, -+ TopFrontRight = ffi::PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, -+ TopFrontCenter = ffi::PA_CHANNEL_POSITION_TOP_FRONT_CENTER, -+ TopRearLeft = ffi::PA_CHANNEL_POSITION_TOP_REAR_LEFT, -+ TopRearRight = ffi::PA_CHANNEL_POSITION_TOP_REAR_RIGHT, -+ TopRearCenter = ffi::PA_CHANNEL_POSITION_TOP_REAR_CENTER, -+} -+ -+impl ChannelPosition { -+ pub fn try_from(x: ffi::pa_channel_position_t) -> Option { -+ if x >= ffi::PA_CHANNEL_POSITION_INVALID && x < ffi::PA_CHANNEL_POSITION_MAX { -+ Some(unsafe { ::std::mem::transmute(x) }) -+ } else { -+ None -+ } -+ } -+} -+ -+impl Default for ChannelPosition { -+ fn default() -> Self { -+ ChannelPosition::Invalid -+ } -+} -+ -+impl Into for ChannelPosition { -+ fn into(self) -> ffi::pa_channel_position_t { -+ self as ffi::pa_channel_position_t -+ } -+} -+pub type Result = ::std::result::Result; -+ -+pub trait CVolumeExt { -+ fn set(&mut self, channels: c_uint, v: Volume); -+ fn set_balance(&mut self, map: &ChannelMap, new_balance: f32); -+} -+ -+impl CVolumeExt for CVolume { -+ fn set(&mut self, channels: c_uint, v: Volume) { -+ unsafe { -+ ffi::pa_cvolume_set(self, channels, v); -+ } -+ } -+ -+ fn set_balance(&mut self, map: &ChannelMap, new_balance: f32) { -+ unsafe { -+ ffi::pa_cvolume_set_balance(self, map, new_balance); -+ } -+ } -+} -+ -+pub trait ChannelMapExt { -+ fn init() -> ChannelMap; -+ fn can_balance(&self) -> bool; -+} -+ -+impl ChannelMapExt for ChannelMap { -+ fn init() -> ChannelMap { -+ let mut cm = ChannelMap::default(); -+ unsafe { -+ ffi::pa_channel_map_init(&mut cm); -+ } -+ cm -+ } -+ fn can_balance(&self) -> bool { -+ unsafe { ffi::pa_channel_map_can_balance(self) > 0 } -+ } -+} -+ -+pub trait ProplistExt { -+ fn proplist(&self) -> Proplist; -+} -+ -+impl ProplistExt for SinkInfo { -+ fn proplist(&self) -> Proplist { -+ unsafe { proplist::from_raw_ptr(self.proplist) } -+ } -+} -+ -+impl ProplistExt for SourceInfo { -+ fn proplist(&self) -> Proplist { -+ unsafe { proplist::from_raw_ptr(self.proplist) } -+ } -+} -+ -+pub trait SampleSpecExt { -+ fn frame_size(&self) -> usize; -+} -+ -+impl SampleSpecExt for SampleSpec { -+ fn frame_size(&self) -> usize { -+ unsafe { ffi::pa_frame_size(self) } -+ } -+} -+ -+pub trait USecExt { -+ fn to_bytes(self, spec: &SampleSpec) -> usize; -+} -+ -+impl USecExt for USec { -+ fn to_bytes(self, spec: &SampleSpec) -> usize { -+ unsafe { ffi::pa_usec_to_bytes(self, spec) } -+ } -+} -+ -+pub fn library_version() -> *const c_char { -+ unsafe { ffi::pa_get_library_version() } -+} -+ -+pub fn sw_volume_from_linear(vol: f64) -> Volume { -+ unsafe { ffi::pa_sw_volume_from_linear(vol) } -+} -+ -+pub fn rtclock_now() -> USec { -+ unsafe { ffi::pa_rtclock_now() } -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/mainloop_api.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/mainloop_api.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/mainloop_api.rs.cubeb-pulse-arm 2017-08-04 13:37:46.385821734 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/mainloop_api.rs 2017-08-04 13:37:46.385821734 +0200 -@@ -0,0 +1,58 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+use ffi; -+use std::mem; -+use std::os::raw::c_void; -+ -+ -+#[allow(non_camel_case_types)] -+type pa_once_cb_t = Option; -+fn wrap_once_cb(_: F) -> pa_once_cb_t -+ where F: Fn(&MainloopApi, *mut c_void) -+{ -+ assert!(mem::size_of::() == 0); -+ -+ unsafe extern "C" fn wrapped(m: *mut ffi::pa_mainloop_api, userdata: *mut c_void) -+ where F: Fn(&MainloopApi, *mut c_void) -+ { -+ let api = from_raw_ptr(m); -+ let result = mem::transmute::<_, &F>(&())(&api, userdata); -+ mem::forget(api); -+ result -+ } -+ -+ Some(wrapped::) -+} -+ -+pub struct MainloopApi(*mut ffi::pa_mainloop_api); -+ -+impl MainloopApi { -+ pub fn raw_mut(&self) -> &mut ffi::pa_mainloop_api { -+ unsafe { &mut *self.0 } -+ } -+ -+ pub fn once(&self, cb: CB, userdata: *mut c_void) -+ where CB: Fn(&MainloopApi, *mut c_void) -+ { -+ let wrapped = wrap_once_cb(cb); -+ unsafe { -+ ffi::pa_mainloop_api_once(self.raw_mut(), wrapped, userdata); -+ } -+ } -+ -+ pub fn time_free(&self, e: *mut ffi::pa_time_event) { -+ unsafe { -+ if let Some(f) = self.raw_mut().time_free { -+ f(e); -+ } -+ } -+ } -+} -+ -+pub unsafe fn from_raw_ptr(raw: *mut ffi::pa_mainloop_api) -> MainloopApi { -+ MainloopApi(raw) -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/operation.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/operation.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/operation.rs.cubeb-pulse-arm 2017-08-04 13:37:46.385821734 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/operation.rs 2017-08-04 13:37:46.385821734 +0200 -@@ -0,0 +1,43 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+use ffi; -+ -+#[derive(Debug)] -+pub struct Operation(*mut ffi::pa_operation); -+ -+impl Operation { -+ pub unsafe fn from_raw_ptr(raw: *mut ffi::pa_operation) -> Operation { -+ Operation(raw) -+ } -+ -+ pub fn cancel(&mut self) { -+ unsafe { -+ ffi::pa_operation_cancel(self.0); -+ } -+ } -+ -+ pub fn get_state(&self) -> ffi::pa_operation_state_t { -+ unsafe { ffi::pa_operation_get_state(self.0) } -+ } -+} -+ -+impl Clone for Operation { -+ fn clone(&self) -> Self { -+ Operation(unsafe { ffi::pa_operation_ref(self.0) }) -+ } -+} -+ -+impl Drop for Operation { -+ fn drop(&mut self) { -+ unsafe { -+ ffi::pa_operation_unref(self.0); -+ } -+ } -+} -+ -+pub unsafe fn from_raw_ptr(raw: *mut ffi::pa_operation) -> Operation { -+ Operation::from_raw_ptr(raw) -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/proplist.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/proplist.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/proplist.rs.cubeb-pulse-arm 2017-08-04 13:37:46.385821734 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/proplist.rs 2017-08-04 13:37:46.385821734 +0200 -@@ -0,0 +1,31 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+use ffi; -+use std::ffi::{CStr, CString}; -+ -+#[derive(Debug)] -+pub struct Proplist(*mut ffi::pa_proplist); -+ -+impl Proplist { -+ pub fn gets(&self, key: T) -> Option<&CStr> -+ where T: Into> -+ { -+ let key = match CString::new(key) { -+ Ok(k) => k, -+ _ => return None, -+ }; -+ let r = unsafe { ffi::pa_proplist_gets(self.0, key.as_ptr()) }; -+ if r.is_null() { -+ None -+ } else { -+ Some(unsafe { CStr::from_ptr(r) }) -+ } -+ } -+} -+ -+pub unsafe fn from_raw_ptr(raw: *mut ffi::pa_proplist) -> Proplist { -+ return Proplist(raw); -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/stream.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/stream.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/stream.rs.cubeb-pulse-arm 2017-08-04 13:37:46.386821731 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/stream.rs 2017-08-04 13:37:46.386821731 +0200 -@@ -0,0 +1,367 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+use ::*; -+use context; -+use ffi; -+use operation; -+use std::ffi::CStr; -+use std::mem; -+use std::os::raw::{c_int, c_void}; -+use std::ptr; -+use util::*; -+ -+#[derive(Debug)] -+pub struct Stream(*mut ffi::pa_stream); -+ -+impl Stream { -+ pub fn new<'a, CM>(c: &Context, name: &::std::ffi::CStr, ss: &SampleSpec, map: CM) -> Option -+ where CM: Into> -+ { -+ let ptr = unsafe { -+ ffi::pa_stream_new(c.raw_mut(), -+ name.as_ptr(), -+ ss as *const _, -+ to_ptr(map.into())) -+ }; -+ if ptr.is_null() { -+ None -+ } else { -+ Some(Stream(ptr)) -+ } -+ } -+ -+ #[doc(hidden)] -+ pub fn raw_mut(&self) -> &mut ffi::pa_stream { -+ unsafe { &mut *self.0 } -+ } -+ -+ pub fn unref(self) { -+ unsafe { -+ ffi::pa_stream_unref(self.raw_mut()); -+ } -+ } -+ -+ pub fn get_state(&self) -> StreamState { -+ StreamState::try_from(unsafe { -+ ffi::pa_stream_get_state(self.raw_mut()) -+ }).expect("pa_stream_get_state returned invalid StreamState") -+ } -+ -+ pub fn get_context(&self) -> Option { -+ let ptr = unsafe { ffi::pa_stream_get_context(self.raw_mut()) }; -+ if ptr.is_null() { -+ return None; -+ } -+ -+ let ctx = unsafe { context::from_raw_ptr(ptr) }; -+ Some(ctx) -+ } -+ -+ pub fn get_index(&self) -> u32 { -+ unsafe { ffi::pa_stream_get_index(self.raw_mut()) } -+ } -+ -+ pub fn get_device_name<'a>(&'a self) -> Result<&'a CStr> { -+ let r = unsafe { ffi::pa_stream_get_device_name(self.raw_mut()) }; -+ if r.is_null() { -+ let err = if let Some(c) = self.get_context() { -+ c.errno() -+ } else { -+ ffi::PA_ERR_UNKNOWN -+ }; -+ return Err(ErrorCode::from_error_code(err)); -+ } -+ Ok(unsafe { CStr::from_ptr(r) }) -+ } -+ -+ pub fn is_suspended(&self) -> Result { -+ let r = unsafe { ffi::pa_stream_is_suspended(self.raw_mut()) }; -+ error_result!(r != 0, r) -+ } -+ -+ pub fn is_corked(&self) -> Result { -+ let r = unsafe { ffi::pa_stream_is_corked(self.raw_mut()) }; -+ error_result!(r != 0, r) -+ } -+ -+ pub fn connect_playback<'a, D, A, V, S>(&self, -+ dev: D, -+ attr: A, -+ flags: StreamFlags, -+ volume: V, -+ sync_stream: S) -+ -> Result<()> -+ where D: Into>, -+ A: Into>, -+ V: Into>, -+ S: Into> -+ { -+ let r = unsafe { -+ ffi::pa_stream_connect_playback(self.raw_mut(), -+ str_to_ptr(dev.into()), -+ to_ptr(attr.into()), -+ flags.into(), -+ to_ptr(volume.into()), -+ map_to_mut_ptr(sync_stream.into(), |p| p.0)) -+ }; -+ error_result!((), r) -+ } -+ -+ pub fn connect_record<'a, D, A>(&self, dev: D, attr: A, flags: StreamFlags) -> Result<()> -+ where D: Into>, -+ A: Into> -+ { -+ let r = unsafe { -+ ffi::pa_stream_connect_record(self.raw_mut(), -+ str_to_ptr(dev.into()), -+ to_ptr(attr.into()), -+ flags.into()) -+ }; -+ error_result!((), r) -+ } -+ -+ pub fn disconnect(&self) -> Result<()> { -+ let r = unsafe { ffi::pa_stream_disconnect(self.raw_mut()) }; -+ error_result!((), r) -+ } -+ -+ pub fn begin_write(&self, req_bytes: usize) -> Result<(*mut c_void, usize)> { -+ let mut data: *mut c_void = ptr::null_mut(); -+ let mut nbytes = req_bytes; -+ let r = unsafe { ffi::pa_stream_begin_write(self.raw_mut(), &mut data, &mut nbytes) }; -+ error_result!((data, nbytes), r) -+ } -+ -+ pub fn cancel_write(&self) -> Result<()> { -+ let r = unsafe { ffi::pa_stream_cancel_write(self.raw_mut()) }; -+ error_result!((), r) -+ } -+ -+ pub fn write(&self, data: *const c_void, nbytes: usize, offset: i64, seek: SeekMode) -> Result<()> { -+ let r = unsafe { ffi::pa_stream_write(self.raw_mut(), data, nbytes, None, offset, seek.into()) }; -+ error_result!((), r) -+ } -+ -+ pub unsafe fn peek(&self, data: *mut *const c_void, length: *mut usize) -> Result<()> { -+ let r = ffi::pa_stream_peek(self.raw_mut(), data, length); -+ error_result!((), r) -+ } -+ -+ pub fn drop(&self) -> Result<()> { -+ let r = unsafe { ffi::pa_stream_drop(self.raw_mut()) }; -+ error_result!((), r) -+ } -+ -+ pub fn writable_size(&self) -> Result { -+ let r = unsafe { ffi::pa_stream_writable_size(self.raw_mut()) }; -+ if r == ::std::usize::MAX { -+ let err = if let Some(c) = self.get_context() { -+ c.errno() -+ } else { -+ ffi::PA_ERR_UNKNOWN -+ }; -+ return Err(ErrorCode::from_error_code(err)); -+ } -+ Ok(r) -+ } -+ -+ pub fn readable_size(&self) -> Result { -+ let r = unsafe { ffi::pa_stream_readable_size(self.raw_mut()) }; -+ if r == ::std::usize::MAX { -+ let err = if let Some(c) = self.get_context() { -+ c.errno() -+ } else { -+ ffi::PA_ERR_UNKNOWN -+ }; -+ return Err(ErrorCode::from_error_code(err)); -+ } -+ Ok(r) -+ } -+ -+ pub fn update_timing_info(&self, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Stream, i32, *mut c_void) -+ { -+ debug_assert_eq!(mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(s: *mut ffi::pa_stream, success: c_int, userdata: *mut c_void) -+ where F: Fn(&Stream, i32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let mut stm = stream::from_raw_ptr(s); -+ let result = uninitialized::()(&mut stm, success, userdata); -+ forget(stm); -+ -+ result -+ } -+ -+ let r = unsafe { ffi::pa_stream_update_timing_info(self.raw_mut(), Some(wrapped::), userdata) }; -+ if r.is_null() { -+ let err = if let Some(c) = self.get_context() { -+ c.errno() -+ } else { -+ ffi::PA_ERR_UNKNOWN -+ }; -+ return Err(ErrorCode::from_error_code(err)); -+ } -+ Ok(unsafe { operation::from_raw_ptr(r) }) -+ } -+ -+ pub fn clear_state_callback(&self) { -+ unsafe { -+ ffi::pa_stream_set_state_callback(self.raw_mut(), None, ptr::null_mut()); -+ } -+ } -+ -+ pub fn set_state_callback(&self, _: CB, userdata: *mut c_void) -+ where CB: Fn(&Stream, *mut c_void) -+ { -+ debug_assert_eq!(mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(s: *mut ffi::pa_stream, userdata: *mut c_void) -+ where F: Fn(&Stream, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let mut stm = stream::from_raw_ptr(s); -+ let result = uninitialized::()(&mut stm, userdata); -+ forget(stm); -+ -+ result -+ } -+ -+ unsafe { -+ ffi::pa_stream_set_state_callback(self.raw_mut(), Some(wrapped::), userdata); -+ } -+ } -+ -+ pub fn clear_write_callback(&self) { -+ unsafe { -+ ffi::pa_stream_set_write_callback(self.raw_mut(), None, ptr::null_mut()); -+ } -+ } -+ -+ pub fn set_write_callback(&self, _: CB, userdata: *mut c_void) -+ where CB: Fn(&Stream, usize, *mut c_void) -+ { -+ debug_assert_eq!(mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(s: *mut ffi::pa_stream, nbytes: usize, userdata: *mut c_void) -+ where F: Fn(&Stream, usize, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let mut stm = stream::from_raw_ptr(s); -+ let result = uninitialized::()(&mut stm, nbytes, userdata); -+ forget(stm); -+ -+ result -+ } -+ -+ unsafe { -+ ffi::pa_stream_set_write_callback(self.raw_mut(), Some(wrapped::), userdata); -+ } -+ } -+ -+ pub fn clear_read_callback(&self) { -+ unsafe { -+ ffi::pa_stream_set_read_callback(self.raw_mut(), None, ptr::null_mut()); -+ } -+ } -+ -+ pub fn set_read_callback(&self, _: CB, userdata: *mut c_void) -+ where CB: Fn(&Stream, usize, *mut c_void) -+ { -+ debug_assert_eq!(mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(s: *mut ffi::pa_stream, nbytes: usize, userdata: *mut c_void) -+ where F: Fn(&Stream, usize, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let mut stm = stream::from_raw_ptr(s); -+ let result = uninitialized::()(&mut stm, nbytes, userdata); -+ forget(stm); -+ -+ result -+ } -+ -+ unsafe { -+ ffi::pa_stream_set_read_callback(self.raw_mut(), Some(wrapped::), userdata); -+ } -+ } -+ -+ pub fn cork(&self, b: i32, _: CB, userdata: *mut c_void) -> Result -+ where CB: Fn(&Stream, i32, *mut c_void) -+ { -+ debug_assert_eq!(mem::size_of::(), 0); -+ -+ // See: A note about `wrapped` functions -+ unsafe extern "C" fn wrapped(s: *mut ffi::pa_stream, success: c_int, userdata: *mut c_void) -+ where F: Fn(&Stream, i32, *mut c_void) -+ { -+ use std::mem::{forget, uninitialized}; -+ let mut stm = stream::from_raw_ptr(s); -+ let result = uninitialized::()(&mut stm, success, userdata); -+ forget(stm); -+ -+ result -+ } -+ -+ let r = unsafe { ffi::pa_stream_cork(self.raw_mut(), b, Some(wrapped::), userdata) }; -+ if r.is_null() { -+ let err = if let Some(c) = self.get_context() { -+ c.errno() -+ } else { -+ ffi::PA_ERR_UNKNOWN -+ }; -+ return Err(ErrorCode::from_error_code(err)); -+ } -+ Ok(unsafe { operation::from_raw_ptr(r) }) -+ } -+ -+ pub fn get_time(&self) -> Result<(u64)> { -+ let mut usec: u64 = 0; -+ let r = unsafe { ffi::pa_stream_get_time(self.raw_mut(), &mut usec) }; -+ error_result!(usec, r) -+ } -+ -+ pub fn get_latency(&self) -> Result<(u64, bool)> { -+ let mut usec: u64 = 0; -+ let mut negative: i32 = 0; -+ let r = unsafe { ffi::pa_stream_get_latency(self.raw_mut(), &mut usec, &mut negative) }; -+ error_result!((usec, negative != 0), r) -+ } -+ -+ pub fn get_sample_spec(&self) -> &SampleSpec { -+ unsafe { -+ let ptr = ffi::pa_stream_get_sample_spec(self.raw_mut()); -+ debug_assert!(!ptr.is_null()); -+ &*ptr -+ } -+ } -+ -+ pub fn get_channel_map(&self) -> &ChannelMap { -+ unsafe { -+ let ptr = ffi::pa_stream_get_channel_map(self.raw_mut()); -+ debug_assert!(!ptr.is_null()); -+ &*ptr -+ } -+ } -+ -+ pub fn get_buffer_attr(&self) -> &BufferAttr { -+ unsafe { -+ let ptr = ffi::pa_stream_get_buffer_attr(self.raw_mut()); -+ debug_assert!(!ptr.is_null()); -+ &*ptr -+ } -+ } -+} -+ -+#[doc(hidden)] -+pub unsafe fn from_raw_ptr(ptr: *mut ffi::pa_stream) -> Stream { -+ Stream(ptr) -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/threaded_mainloop.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/threaded_mainloop.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/threaded_mainloop.rs.cubeb-pulse-arm 2017-08-04 13:37:46.386821731 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/threaded_mainloop.rs 2017-08-04 13:37:46.386821731 +0200 -@@ -0,0 +1,92 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+use ErrorCode; -+use Result; -+use ffi; -+use mainloop_api; -+use mainloop_api::MainloopApi; -+ -+#[derive(Debug)] -+pub struct ThreadedMainloop(*mut ffi::pa_threaded_mainloop); -+ -+impl ThreadedMainloop { -+ pub unsafe fn from_raw_ptr(raw: *mut ffi::pa_threaded_mainloop) -> Self { -+ ThreadedMainloop(raw) -+ } -+ -+ pub fn new() -> Self { -+ unsafe { ThreadedMainloop::from_raw_ptr(ffi::pa_threaded_mainloop_new()) } -+ } -+ -+ pub fn raw_mut(&self) -> &mut ffi::pa_threaded_mainloop { -+ unsafe { &mut *self.0 } -+ } -+ -+ pub fn is_null(&self) -> bool { -+ self.0.is_null() -+ } -+ -+ pub fn start(&self) -> Result<()> { -+ match unsafe { ffi::pa_threaded_mainloop_start(self.raw_mut()) } { -+ 0 => Ok(()), -+ _ => Err(ErrorCode::from_error_code(ffi::PA_ERR_UNKNOWN)), -+ } -+ } -+ -+ pub fn stop(&self) { -+ unsafe { -+ ffi::pa_threaded_mainloop_stop(self.raw_mut()); -+ } -+ } -+ -+ pub fn lock(&self) { -+ unsafe { -+ ffi::pa_threaded_mainloop_lock(self.raw_mut()); -+ } -+ } -+ -+ pub fn unlock(&self) { -+ unsafe { -+ ffi::pa_threaded_mainloop_unlock(self.raw_mut()); -+ } -+ } -+ -+ pub fn wait(&self) { -+ unsafe { -+ ffi::pa_threaded_mainloop_wait(self.raw_mut()); -+ } -+ } -+ -+ pub fn signal(&self) { -+ unsafe { -+ ffi::pa_threaded_mainloop_signal(self.raw_mut(), 0); -+ } -+ } -+ -+ pub fn get_api(&self) -> MainloopApi { -+ unsafe { mainloop_api::from_raw_ptr(ffi::pa_threaded_mainloop_get_api(self.raw_mut())) } -+ } -+ -+ pub fn in_thread(&self) -> bool { -+ unsafe { ffi::pa_threaded_mainloop_in_thread(self.raw_mut()) != 0 } -+ } -+} -+ -+impl ::std::default::Default for ThreadedMainloop { -+ fn default() -> Self { -+ ThreadedMainloop(::std::ptr::null_mut()) -+ } -+} -+ -+impl ::std::ops::Drop for ThreadedMainloop { -+ fn drop(&mut self) { -+ if !self.is_null() { -+ unsafe { -+ ffi::pa_threaded_mainloop_free(self.raw_mut()); -+ } -+ } -+ } -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/util.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/util.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/util.rs.cubeb-pulse-arm 2017-08-04 13:37:46.386821731 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/util.rs 2017-08-04 13:37:46.386821731 +0200 -@@ -0,0 +1,41 @@ -+// Copyright © 2017 Mozilla Foundation -+// -+// This program is made available under an ISC-style license. See the -+// accompanying file LICENSE for details. -+ -+use std::ffi::CStr; -+use std::os::raw::c_char; -+use std::ptr; -+ -+pub trait UnwrapCStr { -+ fn unwrap_cstr(self) -> *const c_char; -+} -+ -+impl<'a, U> UnwrapCStr for U -+ where U: Into> -+{ -+ fn unwrap_cstr(self) -> *const c_char { -+ self.into().map(|o| o.as_ptr()).unwrap_or(0 as *const _) -+ } -+} -+ -+pub fn map_to_mut_ptr *mut U>(t: Option<&mut T>, f: F) -> *mut U { -+ match t { -+ Some(x) => f(x), -+ None => ptr::null_mut(), -+ } -+} -+ -+pub fn str_to_ptr(s: Option<&CStr>) -> *const c_char { -+ match s { -+ Some(x) => x.as_ptr(), -+ None => ptr::null(), -+ } -+} -+ -+pub fn to_ptr(t: Option<&T>) -> *const T { -+ match t { -+ Some(x) => x as *const T, -+ None => ptr::null(), -+ } -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/README.md.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/README.md ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/README.md.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/README.md 2017-08-04 13:37:46.383821740 +0200 -@@ -3,3 +3,4 @@ - Implementation of PulseAudio backend for Cubeb written in Rust. - - [![Travis Build Status](https://travis-ci.org/djg/cubeb-pulse-rs.svg?branch=master)](https://travis-ci.org/djg/cubeb-pulse-rs) -+[![Travis Build Status](https://travis-ci.org/djg/cubeb-pulse-rs.svg?branch=dev)](https://travis-ci.org/djg/cubeb-pulse-rs) -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/README_MOZILLA.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/README_MOZILLA ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/README_MOZILLA.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/README_MOZILLA 2017-08-04 13:37:46.383821740 +0200 -@@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla - - The cubeb-pulse-rs git repository is: https://github.com/djg/cubeb-pulse-rs.git - --The git commit ID used was dbcd7f96aea8d249a4b78f9a7597768c9dff22eb (2017-04-25 11:42:10 +1000) -+The git commit ID used was 64515819cdf54a16626df5dce5f5c7cb1220d53b (2017-06-19 17:41:30 +1000) -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs 2017-08-04 13:50:38.145480458 +0200 -@@ -4,67 +4,60 @@ - // accompanying file LICENSE for details. - - use backend::*; --use backend::cork_state::CorkState; - use capi::PULSE_OPS; - use cubeb; -+use pulse::{self, ProplistExt}; - use pulse_ffi::*; - use semver; - use std::default::Default; --use std::ffi::CStr; -+use std::ffi::{CStr, CString}; - use std::mem; --use std::os::raw::{c_char, c_int, c_void}; -+use std::os::raw::{c_char, c_void}; - use std::ptr; - --macro_rules! dup_str { -- ($Dst: expr, $Src: expr) => { -- if !$Dst.is_null() { -- pa_xfree($Dst as *mut _); -- } -- -- $Dst = pa_xstrdup($Src); -- } --} -- --fn pa_channel_to_cubeb_channel(channel: pa_channel_position_t) -> cubeb::Channel { -- assert_ne!(channel, PA_CHANNEL_POSITION_INVALID); -+fn pa_channel_to_cubeb_channel(channel: pulse::ChannelPosition) -> cubeb::Channel { -+ use pulse::ChannelPosition; -+ assert_ne!(channel, ChannelPosition::Invalid); - match channel { -- PA_CHANNEL_POSITION_MONO => cubeb::CHANNEL_MONO, -- PA_CHANNEL_POSITION_FRONT_LEFT => cubeb::CHANNEL_LEFT, -- PA_CHANNEL_POSITION_FRONT_RIGHT => cubeb::CHANNEL_RIGHT, -- PA_CHANNEL_POSITION_FRONT_CENTER => cubeb::CHANNEL_CENTER, -- PA_CHANNEL_POSITION_SIDE_LEFT => cubeb::CHANNEL_LS, -- PA_CHANNEL_POSITION_SIDE_RIGHT => cubeb::CHANNEL_RS, -- PA_CHANNEL_POSITION_REAR_LEFT => cubeb::CHANNEL_RLS, -- PA_CHANNEL_POSITION_REAR_CENTER => cubeb::CHANNEL_RCENTER, -- PA_CHANNEL_POSITION_REAR_RIGHT => cubeb::CHANNEL_RRS, -- PA_CHANNEL_POSITION_LFE => cubeb::CHANNEL_LFE, -+ ChannelPosition::Mono => cubeb::CHANNEL_MONO, -+ ChannelPosition::FrontLeft => cubeb::CHANNEL_LEFT, -+ ChannelPosition::FrontRight => cubeb::CHANNEL_RIGHT, -+ ChannelPosition::FrontCenter => cubeb::CHANNEL_CENTER, -+ ChannelPosition::SideLeft => cubeb::CHANNEL_LS, -+ ChannelPosition::SideRight => cubeb::CHANNEL_RS, -+ ChannelPosition::RearLeft => cubeb::CHANNEL_RLS, -+ ChannelPosition::RearCenter => cubeb::CHANNEL_RCENTER, -+ ChannelPosition::RearRight => cubeb::CHANNEL_RRS, -+ ChannelPosition::LowFreqEffects => cubeb::CHANNEL_LFE, - _ => cubeb::CHANNEL_INVALID, - } - } - --fn channel_map_to_layout(cm: &pa_channel_map) -> cubeb::ChannelLayout { -+fn channel_map_to_layout(cm: &pulse::ChannelMap) -> cubeb::ChannelLayout { -+ use pulse::ChannelPosition; - let mut cubeb_map: cubeb::ChannelMap = Default::default(); - cubeb_map.channels = cm.channels as u32; - for i in 0usize..cm.channels as usize { -- cubeb_map.map[i] = pa_channel_to_cubeb_channel(cm.map[i]); -+ cubeb_map.map[i] = pa_channel_to_cubeb_channel(ChannelPosition::try_from(cm.map[i]) -+ .unwrap_or(ChannelPosition::Invalid)); - } - unsafe { cubeb::cubeb_channel_map_to_layout(&cubeb_map) } - } - - #[derive(Debug)] - pub struct DefaultInfo { -- pub sample_spec: pa_sample_spec, -- pub channel_map: pa_channel_map, -- pub flags: pa_sink_flags_t, -+ pub sample_spec: pulse::SampleSpec, -+ pub channel_map: pulse::ChannelMap, -+ pub flags: pulse::SinkFlags, - } - - #[derive(Debug)] - pub struct Context { - pub ops: *const cubeb::Ops, -- pub mainloop: *mut pa_threaded_mainloop, -- pub context: *mut pa_context, -+ pub mainloop: pulse::ThreadedMainloop, -+ pub context: Option, - pub default_sink_info: Option, -- pub context_name: *const c_char, -+ pub context_name: Option, - pub collection_changed_callback: cubeb::DeviceCollectionChangedCallback, - pub collection_changed_user_ptr: *mut c_void, - pub error: bool, -@@ -82,7 +75,7 @@ impl Drop for Context { - - impl Context { - #[cfg(feature = "pulse-dlopen")] -- fn _new(name: *const i8) -> Result> { -+ fn _new(name: Option) -> Result> { - let libpulse = unsafe { open() }; - if libpulse.is_none() { - return Err(cubeb::ERROR); -@@ -91,12 +84,12 @@ impl Context { - let ctx = Box::new(Context { - ops: &PULSE_OPS, - libpulse: libpulse.unwrap(), -- mainloop: unsafe { pa_threaded_mainloop_new() }, -- context: 0 as *mut _, -+ mainloop: pulse::ThreadedMainloop::new(), -+ context: None, - default_sink_info: None, - context_name: name, - collection_changed_callback: None, -- collection_changed_user_ptr: 0 as *mut _, -+ collection_changed_user_ptr: ptr::null_mut(), - error: true, - version_0_9_8: false, - version_2_0_0: false, -@@ -106,15 +99,15 @@ impl Context { - } - - #[cfg(not(feature = "pulse-dlopen"))] -- fn _new(name: *const i8) -> Result> { -+ fn _new(name: Option) -> Result> { - Ok(Box::new(Context { - ops: &PULSE_OPS, -- mainloop: unsafe { pa_threaded_mainloop_new() }, -- context: 0 as *mut _, -+ mainloop: pulse::ThreadedMainloop::new(), -+ context: None, - default_sink_info: None, - context_name: name, - collection_changed_callback: None, -- collection_changed_user_ptr: 0 as *mut _, -+ collection_changed_user_ptr: ptr::null_mut(), - error: true, - version_0_9_8: false, - version_2_0_0: false, -@@ -122,53 +115,66 @@ impl Context { - } - - pub fn new(name: *const c_char) -> Result> { -+ fn server_info_cb(context: &pulse::Context, info: &pulse::ServerInfo, u: *mut c_void) { -+ fn sink_info_cb(_: &pulse::Context, i: *const pulse::SinkInfo, eol: i32, u: *mut c_void) { -+ let mut ctx = unsafe { &mut *(u as *mut Context) }; -+ if eol == 0 { -+ let info = unsafe { &*i }; -+ let flags = pulse::SinkFlags::try_from(info.flags).expect("SinkInfo contains invalid flags"); -+ ctx.default_sink_info = Some(DefaultInfo { -+ sample_spec: info.sample_spec, -+ channel_map: info.channel_map, -+ flags: flags, -+ }); -+ } -+ ctx.mainloop.signal(); -+ } -+ -+ let _ = context.get_sink_info_by_name(unsafe { CStr::from_ptr(info.default_sink_name) }, -+ sink_info_cb, -+ u); -+ } -+ -+ let name = super::try_cstr_from(name).map(|s| s.to_owned()); - let mut ctx = try!(Context::_new(name)); - -- unsafe { pa_threaded_mainloop_start(ctx.mainloop) }; -+ if ctx.mainloop.start().is_err() { -+ ctx.destroy(); -+ return Err(cubeb::ERROR); -+ } - -- if ctx.pulse_context_init() != cubeb::OK { -+ if ctx.context_init() != cubeb::OK { - ctx.destroy(); - return Err(cubeb::ERROR); - } - -- unsafe { -- /* server_info_callback performs a second async query, -- * which is responsible for initializing default_sink_info -- * and signalling the mainloop to end the wait. */ -- pa_threaded_mainloop_lock(ctx.mainloop); -- let o = pa_context_get_server_info(ctx.context, -- Some(server_info_callback), -- ctx.as_mut() as *mut Context as *mut _); -- if !o.is_null() { -- ctx.operation_wait(ptr::null_mut(), o); -- pa_operation_unref(o); -+ ctx.mainloop.lock(); -+ /* server_info_callback performs a second async query, -+ * which is responsible for initializing default_sink_info -+ * and signalling the mainloop to end the wait. */ -+ let user_data: *mut c_void = ctx.as_mut() as *mut _ as *mut _; -+ if let Some(ref context) = ctx.context { -+ if let Ok(o) = context.get_server_info(server_info_cb, user_data) { -+ ctx.operation_wait(None, &o); - } -- pa_threaded_mainloop_unlock(ctx.mainloop); -- assert!(ctx.default_sink_info.is_some()); - } -+ assert!(ctx.default_sink_info.is_some()); -+ ctx.mainloop.unlock(); - - // Return the result. - Ok(ctx) - } - - pub fn destroy(&mut self) { -- if !self.context.is_null() { -- unsafe { self.pulse_context_destroy() }; -- } -- assert!(self.context.is_null()); -+ self.context_destroy(); - - if !self.mainloop.is_null() { -- unsafe { -- pa_threaded_mainloop_stop(self.mainloop); -- pa_threaded_mainloop_free(self.mainloop); -- self.mainloop = ptr::null_mut(); -- } -+ self.mainloop.stop(); - } -- assert!(self.mainloop.is_null()); - } - - pub fn new_stream(&mut self, -- stream_name: *const c_char, -+ stream_name: &CStr, - input_device: cubeb::DeviceId, - input_stream_params: Option, - output_device: cubeb::DeviceId, -@@ -178,7 +184,7 @@ impl Context { - state_callback: cubeb::StateCallback, - user_ptr: *mut c_void) - -> Result> { -- if self.error && self.pulse_context_init() != 0 { -+ if self.error && self.context_init() != 0 { - return Err(cubeb::ERROR); - } - -@@ -221,41 +227,151 @@ impl Context { - } - - pub fn enumerate_devices(&self, devtype: cubeb::DeviceType) -> Result { -- let mut user_data: PulseDevListData = Default::default(); -- user_data.context = self as *const _ as *mut _; -+ fn add_output_device(_: &pulse::Context, i: *const pulse::SinkInfo, eol: i32, user_data: *mut c_void) { -+ if eol != 0 { -+ return; -+ } - -- unsafe { -- pa_threaded_mainloop_lock(self.mainloop); -+ debug_assert!(!i.is_null()); -+ debug_assert!(!user_data.is_null()); -+ -+ let mut list_data = unsafe { &mut *(user_data as *mut PulseDevListData) }; -+ let info = unsafe { &*i }; -+ -+ let group_id = match info.proplist().gets("sysfs.path") { -+ Some(p) => p.to_owned().into_raw(), -+ _ => ptr::null_mut(), -+ }; -+ -+ let vendor_name = match info.proplist().gets("device.vendor.name") { -+ Some(p) => p.to_owned().into_raw(), -+ _ => ptr::null_mut(), -+ }; -+ -+ let info_name = unsafe { CStr::from_ptr(info.name) }.to_owned(); -+ let info_description = unsafe { CStr::from_ptr(info.description) }.to_owned(); -+ -+ let preferred = if info_name == list_data.default_sink_name { -+ cubeb::DEVICE_PREF_ALL -+ } else { -+ cubeb::DevicePref::empty() -+ }; -+ -+ let ctx = &(*list_data.context); -+ -+ let device_id = info_name.into_raw(); -+ let friendly_name = info_description.into_raw(); -+ let devinfo = cubeb::DeviceInfo { -+ device_id: device_id, -+ devid: device_id as cubeb::DeviceId, -+ friendly_name: friendly_name, -+ group_id: group_id, -+ vendor_name: vendor_name, -+ devtype: cubeb::DEVICE_TYPE_OUTPUT, -+ state: ctx.state_from_port(info.active_port), -+ preferred: preferred, -+ format: cubeb::DeviceFmt::all(), -+ default_format: pulse_format_to_cubeb_format(info.sample_spec.format), -+ max_channels: info.channel_map.channels as u32, -+ min_rate: 1, -+ max_rate: PA_RATE_MAX, -+ default_rate: info.sample_spec.rate, -+ latency_lo: 0, -+ latency_hi: 0, -+ }; -+ list_data.devinfo.push(devinfo); -+ -+ ctx.mainloop.signal(); -+ } -+ -+ fn add_input_device(_: &pulse::Context, i: *const pulse::SourceInfo, eol: i32, user_data: *mut c_void) { -+ if eol != 0 { -+ return; -+ } -+ -+ debug_assert!(!user_data.is_null()); -+ debug_assert!(!i.is_null()); -+ -+ let mut list_data = unsafe { &mut *(user_data as *mut PulseDevListData) }; -+ let info = unsafe { &*i }; -+ -+ let group_id = match info.proplist().gets("sysfs.path") { -+ Some(p) => p.to_owned().into_raw(), -+ _ => ptr::null_mut(), -+ }; -+ -+ let vendor_name = match info.proplist().gets("device.vendor.name") { -+ Some(p) => p.to_owned().into_raw(), -+ _ => ptr::null_mut(), -+ }; - -- let o = pa_context_get_server_info(self.context, -- Some(pulse_server_info_cb), -- &mut user_data as *mut _ as *mut _); -- if !o.is_null() { -- self.operation_wait(ptr::null_mut(), o); -- pa_operation_unref(o); -+ let info_name = unsafe { CStr::from_ptr(info.name) }.to_owned(); -+ let info_description = unsafe { CStr::from_ptr(info.description) }.to_owned(); -+ -+ let preferred = if info_name == list_data.default_source_name { -+ cubeb::DEVICE_PREF_ALL -+ } else { -+ cubeb::DevicePref::empty() -+ }; -+ -+ let ctx = &(*list_data.context); -+ let device_id = info_name.into_raw(); -+ let friendly_name = info_description.into_raw(); -+ let devinfo = cubeb::DeviceInfo { -+ device_id: device_id, -+ devid: device_id as cubeb::DeviceId, -+ friendly_name: friendly_name, -+ group_id: group_id, -+ vendor_name: vendor_name, -+ devtype: cubeb::DEVICE_TYPE_INPUT, -+ state: ctx.state_from_port(info.active_port), -+ preferred: preferred, -+ format: cubeb::DeviceFmt::all(), -+ default_format: pulse_format_to_cubeb_format(info.sample_spec.format), -+ max_channels: info.channel_map.channels as u32, -+ min_rate: 1, -+ max_rate: PA_RATE_MAX, -+ default_rate: info.sample_spec.rate, -+ latency_lo: 0, -+ latency_hi: 0, -+ }; -+ -+ list_data.devinfo.push(devinfo); -+ -+ ctx.mainloop.signal(); -+ } -+ -+ fn default_device_names(_: &pulse::Context, info: &pulse::ServerInfo, user_data: *mut c_void) { -+ let list_data = unsafe { &mut *(user_data as *mut PulseDevListData) }; -+ -+ list_data.default_sink_name = unsafe { CStr::from_ptr(info.default_sink_name) }.to_owned(); -+ list_data.default_source_name = unsafe { CStr::from_ptr(info.default_source_name) }.to_owned(); -+ -+ (*list_data.context).mainloop.signal(); -+ } -+ -+ let mut user_data = PulseDevListData::new(self); -+ -+ if let Some(ref context) = self.context { -+ self.mainloop.lock(); -+ -+ if let Ok(o) = context.get_server_info(default_device_names, &mut user_data as *mut _ as *mut _) { -+ self.operation_wait(None, &o); - } - - if devtype == cubeb::DEVICE_TYPE_OUTPUT { -- let o = pa_context_get_sink_info_list(self.context, -- Some(pulse_sink_info_cb), -- &mut user_data as *mut _ as *mut _); -- if !o.is_null() { -- self.operation_wait(ptr::null_mut(), o); -- pa_operation_unref(o); -+ if let Ok(o) = context.get_sink_info_list(add_output_device, &mut user_data as *mut _ as *mut _) { -+ self.operation_wait(None, &o); - } - } - - if devtype == cubeb::DEVICE_TYPE_INPUT { -- let o = pa_context_get_source_info_list(self.context, -- Some(pulse_source_info_cb), -- &mut user_data as *mut _ as *mut _); -- if !o.is_null() { -- self.operation_wait(ptr::null_mut(), o); -- pa_operation_unref(o); -+ if let Ok(o) = context.get_source_info_list(add_input_device, &mut user_data as *mut _ as *mut _) { -+ self.operation_wait(None, &o); - } - } - -- pa_threaded_mainloop_unlock(self.mainloop); -+ self.mainloop.unlock(); - } - - // Extract the array of cubeb_device_info from -@@ -282,16 +398,16 @@ impl Context { - coll.count); - for dev in devices.iter_mut() { - if !dev.device_id.is_null() { -- pa_xfree(dev.device_id as *mut _); -+ let _ = CString::from_raw(dev.device_id as *mut _); - } - if !dev.group_id.is_null() { -- pa_xfree(dev.group_id as *mut _); -+ let _ = CString::from_raw(dev.group_id as *mut _); - } - if !dev.vendor_name.is_null() { -- pa_xfree(dev.vendor_name as *mut _); -+ let _ = CString::from_raw(dev.vendor_name as *mut _); - } - if !dev.friendly_name.is_null() { -- pa_xfree(dev.friendly_name as *mut _); -+ let _ = CString::from_raw(dev.friendly_name as *mut _); - } - } - } -@@ -302,115 +418,125 @@ impl Context { - cb: cubeb::DeviceCollectionChangedCallback, - user_ptr: *mut c_void) - -> i32 { -- unsafe extern "C" fn subscribe_success(_: *mut pa_context, success: i32, user_data: *mut c_void) { -- let ctx = &*(user_data as *mut Context); -+ fn update_collection(_: &pulse::Context, event: pulse::SubscriptionEvent, index: u32, user_data: *mut c_void) { -+ let mut ctx = unsafe { &mut *(user_data as *mut Context) }; -+ -+ let (f, t) = (event.event_facility(), event.event_type()); -+ match f { -+ pulse::SubscriptionEventFacility::Source | -+ pulse::SubscriptionEventFacility::Sink => { -+ match t { -+ pulse::SubscriptionEventType::Remove | -+ pulse::SubscriptionEventType::New => { -+ if cubeb::log_enabled() { -+ let op = if t == pulse::SubscriptionEventType::New { -+ "Adding" -+ } else { -+ "Removing" -+ }; -+ let dev = if f == pulse::SubscriptionEventFacility::Sink { -+ "sink" -+ } else { -+ "source " -+ }; -+ log!("{} {} index {}", op, dev, index); -+ -+ unsafe { -+ ctx.collection_changed_callback.unwrap()(ctx as *mut _ as *mut _, -+ ctx.collection_changed_user_ptr); -+ } -+ } -+ }, -+ _ => {}, -+ } -+ }, -+ _ => {}, -+ } -+ } -+ -+ fn success(_: &pulse::Context, success: i32, user_data: *mut c_void) { -+ let ctx = unsafe { &*(user_data as *mut Context) }; - debug_assert_ne!(success, 0); -- pa_threaded_mainloop_signal(ctx.mainloop, 0); -+ ctx.mainloop.signal(); - } - - self.collection_changed_callback = cb; - self.collection_changed_user_ptr = user_ptr; - -- unsafe { -- pa_threaded_mainloop_lock(self.mainloop); -+ let user_data: *mut c_void = self as *mut _ as *mut _; -+ if let Some(ref context) = self.context { -+ self.mainloop.lock(); - -- let mut mask: pa_subscription_mask_t = PA_SUBSCRIPTION_MASK_NULL; -+ let mut mask = pulse::SubscriptionMask::empty(); - if self.collection_changed_callback.is_none() { - // Unregister subscription -- pa_context_set_subscribe_callback(self.context, None, ptr::null_mut()); -+ context.clear_subscribe_callback(); - } else { -- pa_context_set_subscribe_callback(self.context, -- Some(pulse_subscribe_callback), -- self as *mut _ as *mut _); -- if devtype == cubeb::DEVICE_TYPE_INPUT { -- mask |= PA_SUBSCRIPTION_MASK_SOURCE -+ context.set_subscribe_callback(update_collection, user_data); -+ if devtype.contains(cubeb::DEVICE_TYPE_INPUT) { -+ mask |= pulse::SUBSCRIPTION_MASK_SOURCE - }; -- if devtype == cubeb::DEVICE_TYPE_OUTPUT { -- mask |= PA_SUBSCRIPTION_MASK_SOURCE -+ if devtype.contains(cubeb::DEVICE_TYPE_OUTPUT) { -+ mask = pulse::SUBSCRIPTION_MASK_SINK - }; - } - -- let o = pa_context_subscribe(self.context, -- mask, -- Some(subscribe_success), -- self as *const _ as *mut _); -- if o.is_null() { -+ if let Ok(o) = context.subscribe(mask, success, self as *const _ as *mut _) { -+ self.operation_wait(None, &o); -+ } else { - log!("Context subscribe failed"); - return cubeb::ERROR; - } -- self.operation_wait(ptr::null_mut(), o); -- pa_operation_unref(o); - -- pa_threaded_mainloop_unlock(self.mainloop); -+ self.mainloop.unlock(); - } - - cubeb::OK - } - -- // -- -- pub fn pulse_stream_cork(&self, stream: *mut pa_stream, state: CorkState) { -- unsafe extern "C" fn cork_success(_: *mut pa_stream, _: i32, u: *mut c_void) { -- let mainloop = u as *mut pa_threaded_mainloop; -- pa_threaded_mainloop_signal(mainloop, 0); -+ pub fn context_init(&mut self) -> i32 { -+ fn error_state(c: &pulse::Context, u: *mut c_void) { -+ let mut ctx = unsafe { &mut *(u as *mut Context) }; -+ if !c.get_state().is_good() { -+ ctx.error = true; -+ } -+ ctx.mainloop.signal(); - } - -- if stream.is_null() { -- return; -+ if self.context.is_some() { -+ debug_assert!(self.error); -+ self.context_destroy(); - } - -- let o = unsafe { -- pa_stream_cork(stream, -- state.is_cork() as i32, -- Some(cork_success), -- self.mainloop as *mut _) -+ self.context = { -+ let name = match self.context_name.as_ref() { -+ Some(s) => Some(s.as_ref()), -+ None => None, -+ }; -+ pulse::Context::new(&self.mainloop.get_api(), name) - }; - -- if !o.is_null() { -- self.operation_wait(stream, o); -- unsafe { pa_operation_unref(o) }; -+ let context_ptr: *mut c_void = self as *mut _ as *mut _; -+ if self.context.is_none() { -+ return cubeb::ERROR; - } -- } - -- pub fn pulse_context_init(&mut self) -> i32 { -- unsafe extern "C" fn error_state(c: *mut pa_context, u: *mut c_void) { -- let mut ctx = &mut *(u as *mut Context); -- if !PA_CONTEXT_IS_GOOD(pa_context_get_state(c)) { -- ctx.error = true; -- } -- pa_threaded_mainloop_signal(ctx.mainloop, 0); -+ self.mainloop.lock(); -+ if let Some(ref context) = self.context { -+ context.set_state_callback(error_state, context_ptr); -+ let _ = context.connect(None, pulse::ContextFlags::empty(), ptr::null()); - } - -- if !self.context.is_null() { -- debug_assert!(self.error); -- unsafe { self.pulse_context_destroy() }; -+ if !self.wait_until_context_ready() { -+ self.mainloop.unlock(); -+ self.context_destroy(); -+ return cubeb::ERROR; - } - -- unsafe { -- self.context = pa_context_new(pa_threaded_mainloop_get_api(self.mainloop), -- self.context_name); -- -- if self.context.is_null() { -- return cubeb::ERROR; -- } -- -- pa_context_set_state_callback(self.context, Some(error_state), self as *mut _ as *mut _); -- -- pa_threaded_mainloop_lock(self.mainloop); -- pa_context_connect(self.context, ptr::null(), 0, ptr::null()); -- -- if !self.wait_until_context_ready() { -- pa_threaded_mainloop_unlock(self.mainloop); -- self.pulse_context_destroy(); -- assert!(self.context.is_null()); -- return cubeb::ERROR; -- } -+ self.mainloop.unlock(); - -- pa_threaded_mainloop_unlock(self.mainloop); -- } -- -- let version_str = unsafe { CStr::from_ptr(pa_get_library_version()) }; -- if let Ok(version) = semver::Version::parse(version_str.to_string_lossy().as_ref()) { -+ let version_str = unsafe { CStr::from_ptr(pulse::library_version()) }; -+ if let Ok(version) = semver::Version::parse(&version_str.to_string_lossy()) { - self.version_0_9_8 = version >= semver::Version::parse("0.9.8").expect("Failed to parse version"); - self.version_2_0_0 = version >= semver::Version::parse("2.0.0").expect("Failed to parse version"); - } -@@ -420,34 +546,42 @@ impl Context { - cubeb::OK - } - -- unsafe fn pulse_context_destroy(&mut self) { -- unsafe extern "C" fn drain_complete(_c: *mut pa_context, u: *mut c_void) { -- let mainloop = u as *mut pa_threaded_mainloop; -- pa_threaded_mainloop_signal(mainloop, 0); -- } -- -- pa_threaded_mainloop_lock(self.mainloop); -- let o = pa_context_drain(self.context, Some(drain_complete), self.mainloop as *mut _); -- if !o.is_null() { -- self.operation_wait(ptr::null_mut(), o); -- pa_operation_unref(o); -- } -- pa_context_set_state_callback(self.context, None, ptr::null_mut()); -- pa_context_disconnect(self.context); -- pa_context_unref(self.context); -- self.context = ptr::null_mut(); -- pa_threaded_mainloop_unlock(self.mainloop); -+ fn context_destroy(&mut self) { -+ fn drain_complete(_: &pulse::Context, u: *mut c_void) { -+ let ctx = unsafe { &*(u as *mut Context) }; -+ ctx.mainloop.signal(); -+ } -+ -+ let context_ptr: *mut c_void = self as *mut _ as *mut _; -+ match self.context.take() { -+ Some(ctx) => { -+ self.mainloop.lock(); -+ if let Ok(o) = ctx.drain(drain_complete, context_ptr) { -+ self.operation_wait(None, &o); -+ } -+ ctx.clear_state_callback(); -+ ctx.disconnect(); -+ ctx.unref(); -+ self.mainloop.unlock(); -+ }, -+ _ => {}, -+ } - } - -- pub fn operation_wait(&self, stream: *mut pa_stream, o: *mut pa_operation) -> bool { -- unsafe { -- while pa_operation_get_state(o) == PA_OPERATION_RUNNING { -- pa_threaded_mainloop_wait(self.mainloop); -- if !PA_CONTEXT_IS_GOOD(pa_context_get_state(self.context)) { -+ pub fn operation_wait<'a, S>(&self, s: S, o: &pulse::Operation) -> bool -+ where S: Into> -+ { -+ let stream = s.into(); -+ while o.get_state() == PA_OPERATION_RUNNING { -+ self.mainloop.wait(); -+ if let Some(ref context) = self.context { -+ if !context.get_state().is_good() { - return false; - } -+ } - -- if !stream.is_null() && !PA_STREAM_IS_GOOD(pa_stream_get_state(stream)) { -+ if let Some(stm) = stream { -+ if !stm.get_state().is_good() { - return false; - } - } -@@ -457,36 +591,23 @@ impl Context { - } - - pub fn wait_until_context_ready(&self) -> bool { -- loop { -- let state = unsafe { pa_context_get_state(self.context) }; -- if !PA_CONTEXT_IS_GOOD(state) { -- return false; -- } -- if state == PA_CONTEXT_READY { -- break; -- } -- unsafe { -- pa_threaded_mainloop_wait(self.mainloop); -+ if let Some(ref context) = self.context { -+ loop { -+ let state = context.get_state(); -+ if !state.is_good() { -+ return false; -+ } -+ if state == pulse::ContextState::Ready { -+ break; -+ } -+ self.mainloop.wait(); - } - } - - true - } - -- fn state_from_sink_port(&self, i: *const pa_port_info) -> cubeb::DeviceState { -- if !i.is_null() { -- let info = unsafe { *i }; -- if self.version_2_0_0 && info.available == PA_PORT_AVAILABLE_NO { -- cubeb::DeviceState::Unplugged -- } else { -- cubeb::DeviceState::Enabled -- } -- } else { -- cubeb::DeviceState::Enabled -- } -- } -- -- fn state_from_source_port(&self, i: *mut pa_port_info) -> cubeb::DeviceState { -+ fn state_from_port(&self, i: *const pa_port_info) -> cubeb::DeviceState { - if !i.is_null() { - let info = unsafe { *i }; - if self.version_2_0_0 && info.available == PA_PORT_AVAILABLE_NO { -@@ -500,62 +621,30 @@ impl Context { - } - } - --// Callbacks --unsafe extern "C" fn server_info_callback(context: *mut pa_context, info: *const pa_server_info, u: *mut c_void) { -- unsafe extern "C" fn sink_info_callback(_context: *mut pa_context, -- info: *const pa_sink_info, -- eol: i32, -- u: *mut c_void) { -- let mut ctx = &mut *(u as *mut Context); -- if eol == 0 { -- let info = *info; -- ctx.default_sink_info = Some(DefaultInfo { -- sample_spec: info.sample_spec, -- channel_map: info.channel_map, -- flags: info.flags, -- }); -- } -- pa_threaded_mainloop_signal(ctx.mainloop, 0); -- } -- -- let o = pa_context_get_sink_info_by_name(context, -- (*info).default_sink_name, -- Some(sink_info_callback), -- u); -- if !o.is_null() { -- pa_operation_unref(o); -- } --} -- --struct PulseDevListData { -- default_sink_name: *mut c_char, -- default_source_name: *mut c_char, -+struct PulseDevListData<'a> { -+ default_sink_name: CString, -+ default_source_name: CString, - devinfo: Vec, -- context: *mut Context, -+ context: &'a Context, - } - --impl Drop for PulseDevListData { -- fn drop(&mut self) { -- if !self.default_sink_name.is_null() { -- unsafe { -- pa_xfree(self.default_sink_name as *mut _); -- } -- } -- if !self.default_source_name.is_null() { -- unsafe { -- pa_xfree(self.default_source_name as *mut _); -- } -+impl<'a> PulseDevListData<'a> { -+ pub fn new<'b>(context: &'b Context) -> Self -+ where 'b: 'a -+ { -+ PulseDevListData { -+ default_sink_name: CString::default(), -+ default_source_name: CString::default(), -+ devinfo: Vec::new(), -+ context: context, - } - } - } - --impl Default for PulseDevListData { -- fn default() -> Self { -- PulseDevListData { -- default_sink_name: ptr::null_mut(), -- default_source_name: ptr::null_mut(), -- devinfo: Vec::new(), -- context: ptr::null_mut(), -+impl<'a> Drop for PulseDevListData<'a> { -+ fn drop(&mut self) { -+ for elem in &mut self.devinfo { -+ let _ = unsafe { Box::from_raw(elem) }; - } - } - } -@@ -566,192 +655,7 @@ fn pulse_format_to_cubeb_format(format: - PA_SAMPLE_S16BE => cubeb::DEVICE_FMT_S16BE, - PA_SAMPLE_FLOAT32LE => cubeb::DEVICE_FMT_F32LE, - PA_SAMPLE_FLOAT32BE => cubeb::DEVICE_FMT_F32BE, -- _ => { -- panic!("Invalid format"); -- }, -+ // Unsupported format, return F32NE -+ _ => cubeb::CUBEB_FMT_F32NE, - } - } -- --unsafe extern "C" fn pulse_sink_info_cb(_context: *mut pa_context, -- i: *const pa_sink_info, -- eol: i32, -- user_data: *mut c_void) { -- if eol != 0 || i.is_null() { -- return; -- } -- -- debug_assert!(!user_data.is_null()); -- -- let info = *i; -- let mut list_data = &mut *(user_data as *mut PulseDevListData); -- -- let device_id = pa_xstrdup(info.name); -- -- let group_id = { -- let prop = pa_proplist_gets(info.proplist, b"sysfs.path\0".as_ptr() as *const c_char); -- if !prop.is_null() { -- pa_xstrdup(prop) -- } else { -- ptr::null_mut() -- } -- }; -- -- let vendor_name = { -- let prop = pa_proplist_gets(info.proplist, -- b"device.vendor.name\0".as_ptr() as *const c_char); -- if !prop.is_null() { -- pa_xstrdup(prop) -- } else { -- ptr::null_mut() -- } -- }; -- -- let preferred = if strcmp(info.name, list_data.default_sink_name) == 0 { -- cubeb::DEVICE_PREF_ALL -- } else { -- cubeb::DevicePref::empty() -- }; -- -- let ctx = &(*list_data.context); -- -- let devinfo = cubeb::DeviceInfo { -- device_id: device_id, -- devid: device_id as cubeb::DeviceId, -- friendly_name: pa_xstrdup(info.description), -- group_id: group_id, -- vendor_name: vendor_name, -- devtype: cubeb::DEVICE_TYPE_OUTPUT, -- state: ctx.state_from_sink_port(info.active_port), -- preferred: preferred, -- format: cubeb::DeviceFmt::all(), -- default_format: pulse_format_to_cubeb_format(info.sample_spec.format), -- max_channels: info.channel_map.channels as u32, -- min_rate: 1, -- max_rate: PA_RATE_MAX, -- default_rate: info.sample_spec.rate, -- latency_lo: 0, -- latency_hi: 0, -- }; -- list_data.devinfo.push(devinfo); -- -- pa_threaded_mainloop_signal(ctx.mainloop, 0); --} -- --unsafe extern "C" fn pulse_source_info_cb(_context: *mut pa_context, -- i: *const pa_source_info, -- eol: i32, -- user_data: *mut c_void) { -- if eol != 0 || i.is_null() { -- return; -- } -- -- debug_assert!(!user_data.is_null()); -- -- let info = *i; -- let mut list_data = &mut *(user_data as *mut PulseDevListData); -- -- let device_id = pa_xstrdup(info.name); -- -- let group_id = { -- let prop = pa_proplist_gets(info.proplist, b"sysfs.path\0".as_ptr() as *mut c_char); -- if !prop.is_null() { -- pa_xstrdup(prop) -- } else { -- ptr::null_mut() -- } -- }; -- -- let vendor_name = { -- let prop = pa_proplist_gets(info.proplist, -- b"device.vendor.name\0".as_ptr() as *mut c_char); -- if !prop.is_null() { -- pa_xstrdup(prop) -- } else { -- ptr::null_mut() -- } -- }; -- -- let preferred = if strcmp(info.name, list_data.default_source_name) == 0 { -- cubeb::DEVICE_PREF_ALL -- } else { -- cubeb::DevicePref::empty() -- }; -- -- let ctx = &(*list_data.context); -- -- let devinfo = cubeb::DeviceInfo { -- device_id: device_id, -- devid: device_id as cubeb::DeviceId, -- friendly_name: pa_xstrdup(info.description), -- group_id: group_id, -- vendor_name: vendor_name, -- devtype: cubeb::DEVICE_TYPE_INPUT, -- state: ctx.state_from_source_port(info.active_port), -- preferred: preferred, -- format: cubeb::DeviceFmt::all(), -- default_format: pulse_format_to_cubeb_format(info.sample_spec.format), -- max_channels: info.channel_map.channels as u32, -- min_rate: 1, -- max_rate: PA_RATE_MAX, -- default_rate: info.sample_spec.rate, -- latency_lo: 0, -- latency_hi: 0, -- }; -- -- list_data.devinfo.push(devinfo); -- -- pa_threaded_mainloop_signal(ctx.mainloop, 0); --} -- --unsafe extern "C" fn pulse_server_info_cb(_context: *mut pa_context, -- i: *const pa_server_info, -- user_data: *mut c_void) { -- assert!(!i.is_null()); -- let info = *i; -- let list_data = &mut *(user_data as *mut PulseDevListData); -- -- dup_str!(list_data.default_sink_name, info.default_sink_name); -- dup_str!(list_data.default_source_name, info.default_source_name); -- -- pa_threaded_mainloop_signal((*list_data.context).mainloop, 0); --} -- --unsafe extern "C" fn pulse_subscribe_callback(_ctx: *mut pa_context, -- t: pa_subscription_event_type_t, -- index: u32, -- user_data: *mut c_void) { -- let mut ctx = &mut *(user_data as *mut Context); -- -- match t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK { -- PA_SUBSCRIPTION_EVENT_SOURCE | -- PA_SUBSCRIPTION_EVENT_SINK => { -- -- if cubeb::log_enabled() { -- if (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE && -- (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE { -- log!("Removing sink index %d", index); -- } else if (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SOURCE && -- (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW { -- log!("Adding sink index %d", index); -- } -- if (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK && -- (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE { -- log!("Removing source index %d", index); -- } else if (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == PA_SUBSCRIPTION_EVENT_SINK && -- (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW { -- log!("Adding source index %d", index); -- } -- } -- -- if (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE || -- (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW { -- ctx.collection_changed_callback.unwrap()(ctx as *mut _ as *mut _, ctx.collection_changed_user_ptr); -- } -- }, -- _ => {}, -- } --} -- --extern "C" { -- pub fn strcmp(cs: *const c_char, ct: *const c_char) -> c_int; --} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/mod.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/mod.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/mod.rs.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/mod.rs 2017-08-04 13:37:46.386821731 +0200 -@@ -7,8 +7,16 @@ mod context; - mod cork_state; - mod stream; - -+use std::os::raw::c_char; -+use std::ffi::CStr; -+ - pub type Result = ::std::result::Result; - - pub use self::context::Context; - pub use self::stream::Device; - pub use self::stream::Stream; -+ -+// helper to convert *const c_char to Option -+fn try_cstr_from<'str>(s: *const c_char) -> Option<&'str CStr> { -+ if s.is_null() { None } else { Some(unsafe { CStr::from_ptr(s) }) } -+} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs 2017-08-04 13:37:46.387821728 +0200 -@@ -6,8 +6,10 @@ - use backend::*; - use backend::cork_state::CorkState; - use cubeb; -+use pulse::{self, CVolumeExt, ChannelMapExt, SampleSpecExt, USecExt}; - use pulse_ffi::*; --use std::os::raw::{c_char, c_long, c_void}; -+use std::ffi::{CStr, CString}; -+use std::os::raw::{c_long, c_void}; - use std::ptr; - - const PULSE_NO_GAIN: f32 = -1.0; -@@ -36,15 +38,12 @@ fn cubeb_channel_to_pa_channel(channel: - MAP[idx as usize] - } - --fn layout_to_channel_map(layout: cubeb::ChannelLayout) -> pa_channel_map { -+fn layout_to_channel_map(layout: cubeb::ChannelLayout) -> pulse::ChannelMap { - assert_ne!(layout, cubeb::LAYOUT_UNDEFINED); - - let order = cubeb::mixer::channel_index_to_order(layout); - -- let mut cm: pa_channel_map = Default::default(); -- unsafe { -- pa_channel_map_init(&mut cm); -- } -+ let mut cm = pulse::ChannelMap::init(); - cm.channels = order.len() as u8; - for (s, d) in order.iter().zip(cm.map.iter_mut()) { - *d = cubeb_channel_to_pa_channel(*s); -@@ -57,24 +56,27 @@ pub struct Device(cubeb::Device); - impl Drop for Device { - fn drop(&mut self) { - unsafe { -- pa_xfree(self.0.input_name as *mut _); -- pa_xfree(self.0.output_name as *mut _); -+ if !self.0.input_name.is_null() { -+ let _ = CString::from_raw(self.0.input_name); -+ } -+ if !self.0.output_name.is_null() { -+ let _ = CString::from_raw(self.0.output_name); -+ } - } - } - } - -- - #[derive(Debug)] - pub struct Stream<'ctx> { - context: &'ctx Context, -- output_stream: *mut pa_stream, -- input_stream: *mut pa_stream, -+ output_stream: Option, -+ input_stream: Option, - data_callback: cubeb::DataCallback, - state_callback: cubeb::StateCallback, - user_ptr: *mut c_void, - drain_timer: *mut pa_time_event, -- output_sample_spec: pa_sample_spec, -- input_sample_spec: pa_sample_spec, -+ output_sample_spec: pulse::SampleSpec, -+ input_sample_spec: pulse::SampleSpec, - shutdown: bool, - volume: f32, - state: cubeb::State, -@@ -88,7 +90,7 @@ impl<'ctx> Drop for Stream<'ctx> { - - impl<'ctx> Stream<'ctx> { - pub fn new(context: &'ctx Context, -- stream_name: *const c_char, -+ stream_name: &CStr, - input_device: cubeb::DeviceId, - input_stream_params: Option, - output_device: cubeb::DeviceId, -@@ -99,83 +101,167 @@ impl<'ctx> Stream<'ctx> { - user_ptr: *mut c_void) - -> Result>> { - -+ fn check_error(s: &pulse::Stream, u: *mut c_void) { -+ let stm = unsafe { &mut *(u as *mut Stream) }; -+ if !s.get_state().is_good() { -+ stm.state_change_callback(cubeb::STATE_ERROR); -+ } -+ stm.context.mainloop.signal(); -+ } -+ -+ fn read_data(s: &pulse::Stream, nbytes: usize, u: *mut c_void) { -+ fn read_from_input(s: &pulse::Stream, buffer: *mut *const c_void, size: *mut usize) -> i32 { -+ let readable_size: i32 = s.readable_size() -+ .and_then(|s| Ok(s as i32)) -+ .unwrap_or(-1); -+ if readable_size > 0 { -+ if unsafe { s.peek(buffer, size).is_err() } { -+ return -1; -+ } -+ } -+ readable_size -+ } -+ -+ logv!("Input callback buffer size {}", nbytes); -+ let mut stm = unsafe { &mut *(u as *mut Stream) }; -+ if stm.shutdown { -+ return; -+ } -+ -+ let mut read_data: *const c_void = ptr::null(); -+ let mut read_size: usize = 0; -+ while read_from_input(s, &mut read_data, &mut read_size) > 0 { -+ /* read_data can be NULL in case of a hole. */ -+ if !read_data.is_null() { -+ let in_frame_size = stm.input_sample_spec.frame_size(); -+ let read_frames = read_size / in_frame_size; -+ -+ if stm.output_stream.is_some() { -+ // input/capture + output/playback operation -+ let out_frame_size = stm.output_sample_spec.frame_size(); -+ let write_size = read_frames * out_frame_size; -+ // Offer full duplex data for writing -+ stm.trigger_user_callback(read_data, write_size); -+ } else { -+ // input/capture only operation. Call callback directly -+ let got = unsafe { -+ stm.data_callback.unwrap()(stm as *mut _ as *mut _, -+ stm.user_ptr, -+ read_data, -+ ptr::null_mut(), -+ read_frames as c_long) -+ }; -+ -+ if got < 0 || got as usize != read_frames { -+ let _ = s.cancel_write(); -+ stm.shutdown = true; -+ break; -+ } -+ } -+ } -+ -+ if read_size > 0 { -+ let _ = s.drop(); -+ } -+ -+ if stm.shutdown { -+ return; -+ } -+ } -+ } -+ -+ fn write_data(_: &pulse::Stream, nbytes: usize, u: *mut c_void) { -+ logv!("Output callback to be written buffer size {}", nbytes); -+ let mut stm = unsafe { &mut *(u as *mut Stream) }; -+ if stm.shutdown || stm.state != cubeb::STATE_STARTED { -+ return; -+ } -+ -+ if stm.input_stream.is_none() { -+ // Output/playback only operation. -+ // Write directly to output -+ debug_assert!(stm.output_stream.is_some()); -+ stm.trigger_user_callback(ptr::null(), nbytes); -+ } -+ } -+ - let mut stm = Box::new(Stream { - context: context, -- output_stream: ptr::null_mut(), -- input_stream: ptr::null_mut(), -+ output_stream: None, -+ input_stream: None, - data_callback: data_callback, - state_callback: state_callback, - user_ptr: user_ptr, - drain_timer: ptr::null_mut(), -- output_sample_spec: pa_sample_spec::default(), -- input_sample_spec: pa_sample_spec::default(), -+ output_sample_spec: pulse::SampleSpec::default(), -+ input_sample_spec: pulse::SampleSpec::default(), - shutdown: false, - volume: PULSE_NO_GAIN, - state: cubeb::STATE_ERROR, - }); - -- unsafe { -- pa_threaded_mainloop_lock(stm.context.mainloop); -+ if let Some(ref context) = stm.context.context { -+ stm.context.mainloop.lock(); -+ -+ // Setup output stream - if let Some(ref stream_params) = output_stream_params { -- match stm.pulse_stream_init(stream_params, stream_name) { -- Ok(s) => stm.output_stream = s, -+ match Stream::stream_init(context, stream_params, stream_name) { -+ Ok(s) => { -+ stm.output_sample_spec = *s.get_sample_spec(); -+ -+ s.set_state_callback(check_error, stm.as_mut() as *mut _ as *mut _); -+ s.set_write_callback(write_data, stm.as_mut() as *mut _ as *mut _); -+ -+ let battr = set_buffering_attribute(latency_frames, &stm.output_sample_spec); -+ let device_name = super::try_cstr_from(output_device as *const _); -+ let _ = s.connect_playback(device_name, -+ &battr, -+ pulse::STREAM_AUTO_TIMING_UPDATE | pulse::STREAM_INTERPOLATE_TIMING | -+ pulse::STREAM_START_CORKED | -+ pulse::STREAM_ADJUST_LATENCY, -+ None, -+ None); -+ -+ stm.output_stream = Some(s); -+ }, - Err(e) => { -- pa_threaded_mainloop_unlock(stm.context.mainloop); -+ stm.context.mainloop.unlock(); - stm.destroy(); - return Err(e); - }, - } - -- stm.output_sample_spec = *pa_stream_get_sample_spec(stm.output_stream); -- -- pa_stream_set_state_callback(stm.output_stream, -- Some(stream_state_callback), -- stm.as_mut() as *mut _ as *mut _); -- pa_stream_set_write_callback(stm.output_stream, -- Some(stream_write_callback), -- stm.as_mut() as *mut _ as *mut _); -- -- let battr = set_buffering_attribute(latency_frames, &stm.output_sample_spec); -- pa_stream_connect_playback(stm.output_stream, -- output_device as *mut c_char, -- &battr, -- PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING | -- PA_STREAM_START_CORKED | -- PA_STREAM_ADJUST_LATENCY, -- ptr::null(), -- ptr::null_mut()); - } - - // Set up input stream - if let Some(ref stream_params) = input_stream_params { -- match stm.pulse_stream_init(stream_params, stream_name) { -- Ok(s) => stm.input_stream = s, -+ match Stream::stream_init(context, stream_params, stream_name) { -+ Ok(s) => { -+ stm.input_sample_spec = *s.get_sample_spec(); -+ -+ s.set_state_callback(check_error, stm.as_mut() as *mut _ as *mut _); -+ s.set_read_callback(read_data, stm.as_mut() as *mut _ as *mut _); -+ -+ let battr = set_buffering_attribute(latency_frames, &stm.input_sample_spec); -+ let device_name = super::try_cstr_from(input_device as *const _); -+ let _ = s.connect_record(device_name, -+ &battr, -+ pulse::STREAM_AUTO_TIMING_UPDATE | pulse::STREAM_INTERPOLATE_TIMING | -+ pulse::STREAM_START_CORKED | -+ pulse::STREAM_ADJUST_LATENCY); -+ -+ stm.input_stream = Some(s); -+ }, - Err(e) => { -- pa_threaded_mainloop_unlock(stm.context.mainloop); -+ stm.context.mainloop.unlock(); - stm.destroy(); - return Err(e); - }, - } - -- stm.input_sample_spec = *(pa_stream_get_sample_spec(stm.input_stream)); -- -- pa_stream_set_state_callback(stm.input_stream, -- Some(stream_state_callback), -- stm.as_mut() as *mut _ as *mut _); -- pa_stream_set_read_callback(stm.input_stream, -- Some(stream_read_callback), -- stm.as_mut() as *mut _ as *mut _); -- -- let battr = set_buffering_attribute(latency_frames, &stm.input_sample_spec); -- pa_stream_connect_record(stm.input_stream, -- input_device as *mut c_char, -- &battr, -- PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING | -- PA_STREAM_START_CORKED | -- PA_STREAM_ADJUST_LATENCY); - } - -- let r = if stm.wait_until_stream_ready() { -+ let r = if stm.wait_until_ready() { - /* force a timing update now, otherwise timing info does not become valid - until some point after initialization has completed. */ - stm.update_timing_info() -@@ -183,7 +269,7 @@ impl<'ctx> Stream<'ctx> { - false - }; - -- pa_threaded_mainloop_unlock(stm.context.mainloop); -+ stm.context.mainloop.unlock(); - - if !r { - stm.destroy(); -@@ -191,10 +277,10 @@ impl<'ctx> Stream<'ctx> { - } - - if cubeb::log_enabled() { -- if output_stream_params.is_some() { -- let output_att = *pa_stream_get_buffer_attr(stm.output_stream); -- log!("Output buffer attributes maxlength %u, tlength %u, \ -- prebuf %u, minreq %u, fragsize %u", -+ if let Some(ref output_stream) = stm.output_stream { -+ let output_att = output_stream.get_buffer_attr(); -+ log!("Output buffer attributes maxlength {}, tlength {}, \ -+ prebuf {}, minreq {}, fragsize {}", - output_att.maxlength, - output_att.tlength, - output_att.prebuf, -@@ -202,10 +288,10 @@ impl<'ctx> Stream<'ctx> { - output_att.fragsize); - } - -- if input_stream_params.is_some() { -- let input_att = *pa_stream_get_buffer_attr(stm.input_stream); -- log!("Input buffer attributes maxlength %u, tlength %u, \ -- prebuf %u, minreq %u, fragsize %u", -+ if let Some(ref input_stream) = stm.input_stream { -+ let input_att = input_stream.get_buffer_attr(); -+ log!("Input buffer attributes maxlength {}, tlength {}, \ -+ prebuf {}, minreq {}, fragsize {}", - input_att.maxlength, - input_att.tlength, - input_att.prebuf, -@@ -219,224 +305,250 @@ impl<'ctx> Stream<'ctx> { - } - - fn destroy(&mut self) { -- self.stream_cork(CorkState::cork()); -+ self.cork(CorkState::cork()); - -- unsafe { -- pa_threaded_mainloop_lock(self.context.mainloop); -- if !self.output_stream.is_null() { -- if !self.drain_timer.is_null() { -- /* there's no pa_rttime_free, so use this instead. */ -- let ma = pa_threaded_mainloop_get_api(self.context.mainloop); -- if !ma.is_null() { -- (*ma).time_free.unwrap()(self.drain_timer); -+ self.context.mainloop.lock(); -+ { -+ match self.output_stream.take() { -+ Some(stm) => { -+ if !self.drain_timer.is_null() { -+ /* there's no pa_rttime_free, so use this instead. */ -+ self.context -+ .mainloop -+ .get_api() -+ .time_free(self.drain_timer); - } -- } -- -- pa_stream_set_state_callback(self.output_stream, None, ptr::null_mut()); -- pa_stream_set_write_callback(self.output_stream, None, ptr::null_mut()); -- pa_stream_disconnect(self.output_stream); -- pa_stream_unref(self.output_stream); -+ stm.clear_state_callback(); -+ stm.clear_write_callback(); -+ let _ = stm.disconnect(); -+ stm.unref(); -+ }, -+ _ => {}, -+ } -+ -+ match self.input_stream.take() { -+ Some(stm) => { -+ stm.clear_state_callback(); -+ stm.clear_read_callback(); -+ let _ = stm.disconnect(); -+ stm.unref(); -+ }, -+ _ => {}, - } -- -- if !self.input_stream.is_null() { -- pa_stream_set_state_callback(self.input_stream, None, ptr::null_mut()); -- pa_stream_set_read_callback(self.input_stream, None, ptr::null_mut()); -- pa_stream_disconnect(self.input_stream); -- pa_stream_unref(self.input_stream); -- } -- pa_threaded_mainloop_unlock(self.context.mainloop); - } -+ self.context.mainloop.unlock(); - } - - pub fn start(&mut self) -> i32 { -+ fn output_preroll(_: &pulse::MainloopApi, u: *mut c_void) { -+ let mut stm = unsafe { &mut *(u as *mut Stream) }; -+ if !stm.shutdown { -+ let size = stm.output_stream -+ .as_ref() -+ .map_or(0, |s| s.writable_size().unwrap_or(0)); -+ stm.trigger_user_callback(ptr::null_mut(), size); -+ } -+ } -+ - self.shutdown = false; -- self.stream_cork(CorkState::uncork() | CorkState::notify()); -+ self.cork(CorkState::uncork() | CorkState::notify()); - -- if !self.output_stream.is_null() && self.input_stream.is_null() { -- unsafe { -- /* On output only case need to manually call user cb once in order to make -- * things roll. This is done via a defer event in order to execute it -- * from PA server thread. */ -- pa_threaded_mainloop_lock(self.context.mainloop); -- pa_mainloop_api_once(pa_threaded_mainloop_get_api(self.context.mainloop), -- Some(pulse_defer_event_cb), -- self as *mut _ as *mut _); -- pa_threaded_mainloop_unlock(self.context.mainloop); -- } -+ if self.output_stream.is_some() && self.input_stream.is_none() { -+ /* On output only case need to manually call user cb once in order to make -+ * things roll. This is done via a defer event in order to execute it -+ * from PA server thread. */ -+ self.context.mainloop.lock(); -+ self.context -+ .mainloop -+ .get_api() -+ .once(output_preroll, self as *mut _ as *mut _); -+ self.context.mainloop.unlock(); - } - - cubeb::OK - } - - pub fn stop(&mut self) -> i32 { -- unsafe { -- pa_threaded_mainloop_lock(self.context.mainloop); -+ { -+ self.context.mainloop.lock(); - self.shutdown = true; - // If draining is taking place wait to finish - while !self.drain_timer.is_null() { -- pa_threaded_mainloop_wait(self.context.mainloop); -+ self.context.mainloop.wait(); - } -- pa_threaded_mainloop_unlock(self.context.mainloop); -+ self.context.mainloop.unlock(); - } -- self.stream_cork(CorkState::cork() | CorkState::notify()); -+ self.cork(CorkState::cork() | CorkState::notify()); - - cubeb::OK - } - - pub fn position(&self) -> Result { -- if self.output_stream.is_null() { -- return Err(cubeb::ERROR); -- } -+ let in_thread = self.context.mainloop.in_thread(); - -- let position = unsafe { -- let in_thread = pa_threaded_mainloop_in_thread(self.context.mainloop); -- -- if in_thread == 0 { -- pa_threaded_mainloop_lock(self.context.mainloop); -- } -- -- let mut r_usec: pa_usec_t = Default::default(); -- let r = pa_stream_get_time(self.output_stream, &mut r_usec); -- if in_thread == 0 { -- pa_threaded_mainloop_unlock(self.context.mainloop); -- } -- -- if r != 0 { -- return Err(cubeb::ERROR); -- } -+ if !in_thread { -+ self.context.mainloop.lock(); -+ } - -- let bytes = pa_usec_to_bytes(r_usec, &self.output_sample_spec); -- (bytes / pa_frame_size(&self.output_sample_spec)) as u64 -+ let r = match self.output_stream { -+ None => Err(cubeb::ERROR), -+ Some(ref stm) => { -+ match stm.get_time() { -+ Ok(r_usec) => { -+ let bytes = r_usec.to_bytes(&self.output_sample_spec); -+ Ok((bytes / self.output_sample_spec.frame_size()) as u64) -+ }, -+ Err(_) => Err(cubeb::ERROR), -+ } -+ }, - }; -- Ok(position) -- } - -- pub fn latency(&self) -> Result { -- if self.output_stream.is_null() { -- return Err(cubeb::ERROR); -+ if !in_thread { -+ self.context.mainloop.unlock(); - } - -- let mut r_usec: pa_usec_t = 0; -- let mut negative: i32 = 0; -- let r = unsafe { pa_stream_get_latency(self.output_stream, &mut r_usec, &mut negative) }; -+ r -+ } - -- if r != 0 { -- return Err(cubeb::ERROR); -+ pub fn latency(&self) -> Result { -+ match self.output_stream { -+ None => Err(cubeb::ERROR), -+ Some(ref stm) => { -+ match stm.get_latency() { -+ Ok((r_usec, negative)) => { -+ debug_assert!(negative); -+ let latency = (r_usec * self.output_sample_spec.rate as pa_usec_t / PA_USEC_PER_SEC) as u32; -+ Ok(latency) -+ }, -+ Err(_) => Err(cubeb::ERROR), -+ } -+ }, - } -- -- debug_assert_eq!(negative, 0); -- let latency = (r_usec * self.output_sample_spec.rate as pa_usec_t / PA_USEC_PER_SEC) as u32; -- -- Ok(latency) - } - - pub fn set_volume(&mut self, volume: f32) -> i32 { -- if self.output_stream.is_null() { -- return cubeb::ERROR; -- } -- -- unsafe { -- pa_threaded_mainloop_lock(self.context.mainloop); -- -- while self.context.default_sink_info.is_none() { -- pa_threaded_mainloop_wait(self.context.mainloop); -- } -- -- let mut cvol: pa_cvolume = Default::default(); -- -- /* if the pulse daemon is configured to use flat volumes, -- * apply our own gain instead of changing the input volume on the sink. */ -- let flags = { -- match self.context.default_sink_info { -- Some(ref info) => info.flags, -- _ => 0, -- } -- }; -- -- if (flags & PA_SINK_FLAT_VOLUME) != 0 { -- self.volume = volume; -- } else { -- let ss = pa_stream_get_sample_spec(self.output_stream); -- let vol = pa_sw_volume_from_linear(volume as f64); -- pa_cvolume_set(&mut cvol, (*ss).channels as u32, vol); -- -- let index = pa_stream_get_index(self.output_stream); -+ match self.output_stream { -+ None => cubeb::ERROR, -+ Some(ref stm) => { -+ if let Some(ref context) = self.context.context { -+ self.context.mainloop.lock(); -+ -+ let mut cvol: pa_cvolume = Default::default(); -+ -+ /* if the pulse daemon is configured to use flat -+ * volumes, apply our own gain instead of changing -+ * the input volume on the sink. */ -+ let flags = { -+ match self.context.default_sink_info { -+ Some(ref info) => info.flags, -+ _ => pulse::SinkFlags::empty(), -+ } -+ }; -+ -+ if flags.contains(pulse::SINK_FLAT_VOLUME) { -+ self.volume = volume; -+ } else { -+ let channels = stm.get_sample_spec().channels; -+ let vol = pulse::sw_volume_from_linear(volume as f64); -+ cvol.set(channels as u32, vol); -+ -+ let index = stm.get_index(); -+ -+ let context_ptr = self.context as *const _ as *mut _; -+ if let Ok(o) = context.set_sink_input_volume(index, &cvol, context_success, context_ptr) { -+ self.context.operation_wait(stm, &o); -+ } -+ } - -- let op = pa_context_set_sink_input_volume(self.context.context, -- index, -- &cvol, -- Some(volume_success), -- self as *mut _ as *mut _); -- if !op.is_null() { -- self.context.operation_wait(self.output_stream, op); -- pa_operation_unref(op); -+ self.context.mainloop.unlock(); -+ cubeb::OK -+ } else { -+ cubeb::ERROR - } -- } -- -- pa_threaded_mainloop_unlock(self.context.mainloop); -+ }, - } -- cubeb::OK - } - - pub fn set_panning(&mut self, panning: f32) -> i32 { -- if self.output_stream.is_null() { -- return cubeb::ERROR; -- } -+ #[repr(C)] -+ struct SinkInputInfoResult<'a> { -+ pub cvol: pulse::CVolume, -+ pub mainloop: &'a pulse::ThreadedMainloop, -+ } -+ -+ fn get_input_volume(_: &pulse::Context, info: *const pulse::SinkInputInfo, eol: i32, u: *mut c_void) { -+ let mut r = unsafe { &mut *(u as *mut SinkInputInfoResult) }; -+ if eol == 0 { -+ let info = unsafe { *info }; -+ r.cvol = info.volume; -+ } -+ r.mainloop.signal(); -+ } -+ -+ match self.output_stream { -+ None => cubeb::ERROR, -+ Some(ref stm) => { -+ if let Some(ref context) = self.context.context { -+ self.context.mainloop.lock(); -+ -+ let map = stm.get_channel_map(); -+ if !map.can_balance() { -+ self.context.mainloop.unlock(); -+ return cubeb::ERROR; -+ } - -- unsafe { -- pa_threaded_mainloop_lock(self.context.mainloop); -+ let index = stm.get_index(); - -- let map = pa_stream_get_channel_map(self.output_stream); -- if pa_channel_map_can_balance(map) == 0 { -- pa_threaded_mainloop_unlock(self.context.mainloop); -- return cubeb::ERROR; -- } -+ let mut r = SinkInputInfoResult { -+ cvol: pulse::CVolume::default(), -+ mainloop: &self.context.mainloop, -+ }; - -- let index = pa_stream_get_index(self.output_stream); -+ if let Ok(o) = context.get_sink_input_info(index, get_input_volume, &mut r as *mut _ as *mut _) { -+ self.context.operation_wait(stm, &o); -+ } - -- let mut cvol: pa_cvolume = Default::default(); -- let mut r = SinkInputInfoResult { -- cvol: &mut cvol, -- mainloop: self.context.mainloop, -- }; -+ r.cvol.set_balance(map, panning); - -- let op = pa_context_get_sink_input_info(self.context.context, -- index, -- Some(sink_input_info_cb), -- &mut r as *mut _ as *mut _); -- if !op.is_null() { -- self.context.operation_wait(self.output_stream, op); -- pa_operation_unref(op); -- } -- -- pa_cvolume_set_balance(&mut cvol, map, panning); -- -- let op = pa_context_set_sink_input_volume(self.context.context, -- index, -- &cvol, -- Some(volume_success), -- self as *mut _ as *mut _); -- if !op.is_null() { -- self.context.operation_wait(self.output_stream, op); -- pa_operation_unref(op); -- } -+ let context_ptr = self.context as *const _ as *mut _; -+ if let Ok(o) = context.set_sink_input_volume(index, &r.cvol, context_success, context_ptr) { -+ self.context.operation_wait(stm, &o); -+ } - -- pa_threaded_mainloop_unlock(self.context.mainloop); -- } -+ self.context.mainloop.unlock(); - -- cubeb::OK -+ cubeb::OK -+ } else { -+ cubeb::ERROR -+ } -+ }, -+ } - } - - pub fn current_device(&self) -> Result> { - if self.context.version_0_9_8 { - let mut dev = Box::new(cubeb::Device::default()); - -- if !self.input_stream.is_null() { -- dev.input_name = unsafe { pa_xstrdup(pa_stream_get_device_name(self.input_stream)) }; -+ if self.input_stream.is_some() { -+ if let Some(ref stm) = self.input_stream { -+ dev.input_name = match stm.get_device_name() { -+ Ok(name) => name.to_owned().into_raw(), -+ Err(_) => { -+ return Err(cubeb::ERROR); -+ }, -+ } -+ } - } - -- if !self.output_stream.is_null() { -- dev.output_name = unsafe { pa_xstrdup(pa_stream_get_device_name(self.output_stream)) }; -+ if !self.output_stream.is_some() { -+ if let Some(ref stm) = self.output_stream { -+ dev.output_name = match stm.get_device_name() { -+ Ok(name) => name.to_owned().into_raw(), -+ Err(_) => { -+ return Err(cubeb::ERROR); -+ }, -+ } -+ } - } - - Ok(dev) -@@ -445,51 +557,62 @@ impl<'ctx> Stream<'ctx> { - } - } - -- fn pulse_stream_init(&mut self, -- stream_params: &cubeb::StreamParams, -- stream_name: *const c_char) -- -> Result<*mut pa_stream> { -+ fn stream_init(context: &pulse::Context, -+ stream_params: &cubeb::StreamParams, -+ stream_name: &CStr) -+ -> Result { - -- fn to_pulse_format(format: cubeb::SampleFormat) -> pa_sample_format_t { -+ fn to_pulse_format(format: cubeb::SampleFormat) -> pulse::SampleFormat { - match format { -- cubeb::SAMPLE_S16LE => PA_SAMPLE_S16LE, -- cubeb::SAMPLE_S16BE => PA_SAMPLE_S16BE, -- cubeb::SAMPLE_FLOAT32LE => PA_SAMPLE_FLOAT32LE, -- cubeb::SAMPLE_FLOAT32BE => PA_SAMPLE_FLOAT32BE, -- _ => panic!("Invalid format: {:?}", format), -+ cubeb::SAMPLE_S16LE => pulse::SampleFormat::Signed16LE, -+ cubeb::SAMPLE_S16BE => pulse::SampleFormat::Signed16BE, -+ cubeb::SAMPLE_FLOAT32LE => pulse::SampleFormat::Float32LE, -+ cubeb::SAMPLE_FLOAT32BE => pulse::SampleFormat::Float32BE, -+ _ => pulse::SampleFormat::Invalid, - } - } - - let fmt = to_pulse_format(stream_params.format); -- if fmt == PA_SAMPLE_INVALID { -+ if fmt == pulse::SampleFormat::Invalid { - return Err(cubeb::ERROR_INVALID_FORMAT); - } - -- let ss = pa_sample_spec { -+ let ss = pulse::SampleSpec { - channels: stream_params.channels as u8, -- format: fmt, -+ format: fmt.into(), - rate: stream_params.rate, - }; - -- let stream = if stream_params.layout == cubeb::LAYOUT_UNDEFINED { -- unsafe { pa_stream_new(self.context.context, stream_name, &ss, ptr::null_mut()) } -- } else { -- let cm = layout_to_channel_map(stream_params.layout); -- unsafe { pa_stream_new(self.context.context, stream_name, &ss, &cm) } -+ let cm: Option = match stream_params.layout { -+ cubeb::LAYOUT_UNDEFINED => None, -+ _ => Some(layout_to_channel_map(stream_params.layout)), - }; - -- if !stream.is_null() { -- Ok(stream) -- } else { -- Err(cubeb::ERROR) -+ let stream = pulse::Stream::new(context, stream_name, &ss, cm.as_ref()); -+ -+ match stream { -+ None => Err(cubeb::ERROR), -+ Some(stm) => Ok(stm), -+ } -+ } -+ -+ pub fn cork_stream(&self, stream: Option<&pulse::Stream>, state: CorkState) { -+ if let Some(stm) = stream { -+ if let Ok(o) = stm.cork(state.is_cork() as i32, -+ stream_success, -+ self as *const _ as *mut _) { -+ self.context.operation_wait(stream, &o); -+ } - } - } - -- fn stream_cork(&mut self, state: CorkState) { -- unsafe { pa_threaded_mainloop_lock(self.context.mainloop) }; -- self.context.pulse_stream_cork(self.output_stream, state); -- self.context.pulse_stream_cork(self.input_stream, state); -- unsafe { pa_threaded_mainloop_unlock(self.context.mainloop) }; -+ fn cork(&mut self, state: CorkState) { -+ { -+ self.context.mainloop.lock(); -+ self.cork_stream(self.output_stream.as_ref(), state); -+ self.cork_stream(self.input_stream.as_ref(), state); -+ self.context.mainloop.unlock() -+ } - - if state.is_notify() { - self.state_change_callback(if state.is_cork() { -@@ -503,18 +626,9 @@ impl<'ctx> Stream<'ctx> { - fn update_timing_info(&self) -> bool { - let mut r = false; - -- if !self.output_stream.is_null() { -- let o = unsafe { -- pa_stream_update_timing_info(self.output_stream, -- Some(stream_success_callback), -- self as *const _ as *mut _) -- }; -- -- if !o.is_null() { -- r = self.context.operation_wait(self.output_stream, o); -- unsafe { -- pa_operation_unref(o); -- } -+ if let Some(ref stm) = self.output_stream { -+ if let Ok(o) = stm.update_timing_info(stream_success, self as *const _ as *mut _) { -+ r = self.context.operation_wait(stm, &o); - } - - if !r { -@@ -522,18 +636,9 @@ impl<'ctx> Stream<'ctx> { - } - } - -- if !self.input_stream.is_null() { -- let o = unsafe { -- pa_stream_update_timing_info(self.input_stream, -- Some(stream_success_callback), -- self as *const _ as *mut _) -- }; -- -- if !o.is_null() { -- r = self.context.operation_wait(self.input_stream, o); -- unsafe { -- pa_operation_unref(o); -- } -+ if let Some(ref stm) = self.input_stream { -+ if let Ok(o) = stm.update_timing_info(stream_success, self as *const _ as *mut _) { -+ r = self.context.operation_wait(stm, &o); - } - } - -@@ -547,232 +652,162 @@ impl<'ctx> Stream<'ctx> { - } - } - -- fn wait_until_stream_ready(&self) -> bool { -- if !self.output_stream.is_null() && !wait_until_io_stream_ready(self.output_stream, self.context.mainloop) { -- return false; -- } -- -- if !self.input_stream.is_null() && !wait_until_io_stream_ready(self.input_stream, self.context.mainloop) { -- return false; -- } -- -- true -- } -- -- fn trigger_user_callback(&mut self, s: *mut pa_stream, input_data: *const c_void, nbytes: usize) { -- let frame_size = unsafe { pa_frame_size(&self.output_sample_spec) }; -- debug_assert_eq!(nbytes % frame_size, 0); -- -- let mut buffer: *mut c_void = ptr::null_mut(); -- let mut r: i32; -- -- let mut towrite = nbytes; -- let mut read_offset = 0usize; -- while towrite > 0 { -- let mut size = towrite; -- r = unsafe { pa_stream_begin_write(s, &mut buffer, &mut size) }; -- // Note: this has failed running under rr on occassion - needs investigation. -- debug_assert_eq!(r, 0); -- debug_assert!(size > 0); -- debug_assert_eq!(size % frame_size, 0); -- -- logv!("Trigger user callback with output buffer size={}, read_offset={}", -- size, -- read_offset); -- let read_ptr = unsafe { (input_data as *const u8).offset(read_offset as isize) }; -- let got = unsafe { -- self.data_callback.unwrap()(self as *const _ as *mut _, -- self.user_ptr, -- read_ptr as *const _ as *mut _, -- buffer, -- (size / frame_size) as c_long) -- }; -- if got < 0 { -- unsafe { -- pa_stream_cancel_write(s); -- } -- self.shutdown = true; -- return; -- } -- // If more iterations move offset of read buffer -- if !input_data.is_null() { -- let in_frame_size = unsafe { pa_frame_size(&self.input_sample_spec) }; -- read_offset += (size / frame_size) * in_frame_size; -+ fn wait_until_ready(&self) -> bool { -+ fn wait_until_io_stream_ready(stm: &pulse::Stream, mainloop: &pulse::ThreadedMainloop) -> bool { -+ if mainloop.is_null() { -+ return false; - } - -- if self.volume != PULSE_NO_GAIN { -- let samples = (self.output_sample_spec.channels as usize * size / frame_size) as isize; -- -- if self.output_sample_spec.format == PA_SAMPLE_S16BE || -- self.output_sample_spec.format == PA_SAMPLE_S16LE { -- let b = buffer as *mut i16; -- for i in 0..samples { -- unsafe { *b.offset(i) *= self.volume as i16 }; -- } -- } else { -- let b = buffer as *mut f32; -- for i in 0..samples { -- unsafe { *b.offset(i) *= self.volume }; -- } -+ loop { -+ let state = stm.get_state(); -+ if !state.is_good() { -+ return false; -+ } -+ if state == pulse::StreamState::Ready { -+ break; - } -+ mainloop.wait(); - } - -- r = unsafe { -- pa_stream_write(s, -- buffer, -- got as usize * frame_size, -- None, -- 0, -- PA_SEEK_RELATIVE) -- }; -- debug_assert_eq!(r, 0); -+ true -+ } - -- if (got as usize) < size / frame_size { -- let mut latency: pa_usec_t = 0; -- let rr: i32 = unsafe { pa_stream_get_latency(s, &mut latency, ptr::null_mut()) }; -- if rr == -(PA_ERR_NODATA as i32) { -- /* this needs a better guess. */ -- latency = 100 * PA_USEC_PER_MSEC; -- } -- debug_assert!(r == 0 || r == -(PA_ERR_NODATA as i32)); -- /* pa_stream_drain is useless, see PA bug# 866. this is a workaround. */ -- /* arbitrary safety margin: double the current latency. */ -- debug_assert!(self.drain_timer.is_null()); -- self.drain_timer = unsafe { -- pa_context_rttime_new(self.context.context, -- pa_rtclock_now() + 2 * latency, -- Some(stream_drain_callback), -- self as *const _ as *mut _) -- }; -- self.shutdown = true; -- return; -+ if let Some(ref stm) = self.output_stream { -+ if !wait_until_io_stream_ready(stm, &self.context.mainloop) { -+ return false; - } -- -- towrite -= size; - } - -- debug_assert_eq!(towrite, 0); -- } --} -- --unsafe extern "C" fn stream_success_callback(_s: *mut pa_stream, _success: i32, u: *mut c_void) { -- let stm = &*(u as *mut Stream); -- pa_threaded_mainloop_signal(stm.context.mainloop, 0); --} -- --unsafe extern "C" fn stream_drain_callback(a: *mut pa_mainloop_api, -- e: *mut pa_time_event, -- _tv: *const timeval, -- u: *mut c_void) { -- let mut stm = &mut *(u as *mut Stream); -- debug_assert_eq!(stm.drain_timer, e); -- stm.state_change_callback(cubeb::STATE_DRAINED); -- /* there's no pa_rttime_free, so use this instead. */ -- (*a).time_free.unwrap()(stm.drain_timer); -- stm.drain_timer = ptr::null_mut(); -- pa_threaded_mainloop_signal(stm.context.mainloop, 0); --} -- --unsafe extern "C" fn stream_state_callback(s: *mut pa_stream, u: *mut c_void) { -- let stm = &mut *(u as *mut Stream); -- if !PA_STREAM_IS_GOOD(pa_stream_get_state(s)) { -- stm.state_change_callback(cubeb::STATE_ERROR); -- } -- pa_threaded_mainloop_signal(stm.context.mainloop, 0); --} -- --fn read_from_input(s: *mut pa_stream, buffer: *mut *const c_void, size: *mut usize) -> i32 { -- let readable_size = unsafe { pa_stream_readable_size(s) }; -- if readable_size > 0 && unsafe { pa_stream_peek(s, buffer, size) } < 0 { -- return -1; -- } -- -- readable_size as i32 --} -+ if let Some(ref stm) = self.input_stream { -+ if !wait_until_io_stream_ready(stm, &self.context.mainloop) { -+ return false; -+ } -+ } - --unsafe extern "C" fn stream_write_callback(s: *mut pa_stream, nbytes: usize, u: *mut c_void) { -- logv!("Output callback to be written buffer size {}", nbytes); -- let mut stm = &mut *(u as *mut Stream); -- if stm.shutdown || stm.state != cubeb::STATE_STARTED { -- return; -+ true - } - -- if stm.input_stream.is_null() { -- // Output/playback only operation. -- // Write directly to output -- debug_assert!(!stm.output_stream.is_null()); -- stm.trigger_user_callback(s, ptr::null(), nbytes); -- } --} -+ fn trigger_user_callback(&mut self, input_data: *const c_void, nbytes: usize) { -+ fn drained_cb(a: &pulse::MainloopApi, e: *mut pa_time_event, _tv: &pulse::TimeVal, u: *mut c_void) { -+ let mut stm = unsafe { &mut *(u as *mut Stream) }; -+ debug_assert_eq!(stm.drain_timer, e); -+ stm.state_change_callback(cubeb::STATE_DRAINED); -+ /* there's no pa_rttime_free, so use this instead. */ -+ a.time_free(stm.drain_timer); -+ stm.drain_timer = ptr::null_mut(); -+ stm.context.mainloop.signal(); -+ } -+ -+ if let Some(ref stm) = self.output_stream { -+ -+ let frame_size = self.output_sample_spec.frame_size(); -+ debug_assert_eq!(nbytes % frame_size, 0); -+ -+ let mut towrite = nbytes; -+ let mut read_offset = 0usize; -+ while towrite > 0 { -+ match stm.begin_write(towrite) { -+ Err(e) => { -+ panic!("Failed to write data: {}", e); -+ }, -+ Ok((buffer, size)) => { -+ debug_assert!(size > 0); -+ debug_assert_eq!(size % frame_size, 0); -+ -+ logv!("Trigger user callback with output buffer size={}, read_offset={}", -+ size, -+ read_offset); -+ let read_ptr = unsafe { (input_data as *const u8).offset(read_offset as isize) }; -+ let got = unsafe { -+ self.data_callback.unwrap()(self as *const _ as *mut _, -+ self.user_ptr, -+ read_ptr as *const _ as *mut _, -+ buffer, -+ (size / frame_size) as c_long) -+ }; -+ if got < 0 { -+ let _ = stm.cancel_write(); -+ self.shutdown = true; -+ return; -+ } -+ -+ // If more iterations move offset of read buffer -+ if !input_data.is_null() { -+ let in_frame_size = self.input_sample_spec.frame_size(); -+ read_offset += (size / frame_size) * in_frame_size; -+ } -+ -+ if self.volume != PULSE_NO_GAIN { -+ let samples = (self.output_sample_spec.channels as usize * size / frame_size) as isize; -+ -+ if self.output_sample_spec.format == PA_SAMPLE_S16BE || -+ self.output_sample_spec.format == PA_SAMPLE_S16LE { -+ let b = buffer as *mut i16; -+ for i in 0..samples { -+ unsafe { *b.offset(i) *= self.volume as i16 }; -+ } -+ } else { -+ let b = buffer as *mut f32; -+ for i in 0..samples { -+ unsafe { *b.offset(i) *= self.volume }; -+ } -+ } -+ } -+ -+ let r = stm.write(buffer, -+ got as usize * frame_size, -+ 0, -+ pulse::SeekMode::Relative); -+ debug_assert!(r.is_ok()); -+ -+ if (got as usize) < size / frame_size { -+ let latency = match stm.get_latency() { -+ Ok((l, negative)) => { -+ assert_ne!(negative, true); -+ l -+ }, -+ Err(e) => { -+ debug_assert_eq!(e, pulse::ErrorCode::from_error_code(PA_ERR_NODATA)); -+ /* this needs a better guess. */ -+ 100 * PA_USEC_PER_MSEC -+ }, -+ }; -+ -+ /* pa_stream_drain is useless, see PA bug# 866. this is a workaround. */ -+ /* arbitrary safety margin: double the current latency. */ -+ debug_assert!(self.drain_timer.is_null()); -+ let stream_ptr = self as *const _ as *mut _; -+ if let Some(ref context) = self.context.context { -+ self.drain_timer = -+ context.rttime_new(pulse::rtclock_now() + 2 * latency, drained_cb, stream_ptr); -+ } -+ self.shutdown = true; -+ return; -+ } - --unsafe extern "C" fn stream_read_callback(s: *mut pa_stream, nbytes: usize, u: *mut c_void) { -- logv!("Input callback buffer size {}", nbytes); -- let mut stm = &mut *(u as *mut Stream); -- if stm.shutdown { -- return; -- } -- -- let mut read_data: *const c_void = ptr::null(); -- let mut read_size: usize = 0; -- while read_from_input(s, &mut read_data, &mut read_size) > 0 { -- /* read_data can be NULL in case of a hole. */ -- if !read_data.is_null() { -- let in_frame_size = pa_frame_size(&stm.input_sample_spec); -- let read_frames = read_size / in_frame_size; -- -- if !stm.output_stream.is_null() { -- // input/capture + output/playback operation -- let out_frame_size = pa_frame_size(&stm.output_sample_spec); -- let write_size = read_frames * out_frame_size; -- // Offer full duplex data for writing -- let stream = stm.output_stream; -- stm.trigger_user_callback(stream, read_data, write_size); -- } else { -- // input/capture only operation. Call callback directly -- let got = stm.data_callback.unwrap()(stm as *mut _ as *mut _, -- stm.user_ptr, -- read_data, -- ptr::null_mut(), -- read_frames as c_long); -- if got < 0 || got as usize != read_frames { -- pa_stream_cancel_write(s); -- stm.shutdown = true; -- break; -+ towrite -= size; -+ }, - } - } -- } -- -- if read_size > 0 { -- pa_stream_drop(s); -- } -- -- if stm.shutdown { -- return; -+ debug_assert_eq!(towrite, 0); - } - } - } - --fn wait_until_io_stream_ready(stream: *mut pa_stream, mainloop: *mut pa_threaded_mainloop) -> bool { -- if stream.is_null() || mainloop.is_null() { -- return false; -- } -- -- loop { -- let state = unsafe { pa_stream_get_state(stream) }; -- if !PA_STREAM_IS_GOOD(state) { -- return false; -- } -- if state == PA_STREAM_READY { -- break; -- } -- unsafe { pa_threaded_mainloop_wait(mainloop) }; -- } -+fn stream_success(_: &pulse::Stream, success: i32, u: *mut c_void) { -+ let stm = unsafe { &*(u as *mut Stream) }; -+ debug_assert_ne!(success, 0); -+ stm.context.mainloop.signal(); -+} - -- true -+fn context_success(_: &pulse::Context, success: i32, u: *mut c_void) { -+ let ctx = unsafe { &*(u as *mut Context) }; -+ debug_assert_ne!(success, 0); -+ ctx.mainloop.signal(); - } - - fn set_buffering_attribute(latency_frames: u32, sample_spec: &pa_sample_spec) -> pa_buffer_attr { -- let tlength = latency_frames * unsafe { pa_frame_size(sample_spec) } as u32; -+ let tlength = latency_frames * sample_spec.frame_size() as u32; - let minreq = tlength / 4; - let battr = pa_buffer_attr { - maxlength: u32::max_value(), -@@ -791,34 +826,3 @@ fn set_buffering_attribute(latency_frame - - battr - } -- --unsafe extern "C" fn pulse_defer_event_cb(_a: *mut pa_mainloop_api, u: *mut c_void) { -- let mut stm = &mut *(u as *mut Stream); -- if stm.shutdown { -- return; -- } -- let writable_size = pa_stream_writable_size(stm.output_stream); -- let stream = stm.output_stream; -- stm.trigger_user_callback(stream, ptr::null_mut(), writable_size); --} -- --#[repr(C)] --struct SinkInputInfoResult { -- pub cvol: *mut pa_cvolume, -- pub mainloop: *mut pa_threaded_mainloop, --} -- --unsafe extern "C" fn sink_input_info_cb(_c: *mut pa_context, i: *const pa_sink_input_info, eol: i32, u: *mut c_void) { -- let info = &*i; -- let mut r = &mut *(u as *mut SinkInputInfoResult); -- if eol == 0 { -- *r.cvol = info.volume; -- } -- pa_threaded_mainloop_signal(r.mainloop, 0); --} -- --unsafe extern "C" fn volume_success(_c: *mut pa_context, success: i32, u: *mut c_void) { -- let stm = &*(u as *mut Stream); -- debug_assert_ne!(success, 0); -- pa_threaded_mainloop_signal(stm.context.mainloop, 0); --} -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/capi.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/capi.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/capi.rs.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/capi.rs 2017-08-04 13:37:46.387821728 +0200 -@@ -5,6 +5,7 @@ - - use backend; - use cubeb; -+use std::ffi::CStr; - use std::os::raw::{c_char, c_void}; - - unsafe extern "C" fn capi_init(c: *mut *mut cubeb::Context, context_name: *const c_char) -> i32 { -@@ -114,21 +115,18 @@ unsafe extern "C" fn capi_stream_init(c: - state_callback: cubeb::StateCallback, - user_ptr: *mut c_void) - -> i32 { -+ fn try_stream_params_from(sp: *mut cubeb::StreamParams) -> Option { -+ if sp.is_null() { None } else { Some(unsafe { *sp }) } -+ } -+ - let mut ctx = &mut *(c as *mut backend::Context); -+ let stream_name = CStr::from_ptr(stream_name); - - match ctx.new_stream(stream_name, - input_device, -- if input_stream_params.is_null() { -- None -- } else { -- Some(*input_stream_params) -- }, -+ try_stream_params_from(input_stream_params), - output_device, -- if output_stream_params.is_null() { -- None -- } else { -- Some(*output_stream_params) -- }, -+ try_stream_params_from(output_stream_params), - latency_frames, - data_callback, - state_callback, -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/lib.rs.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/lib.rs ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/lib.rs.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/src/lib.rs 2017-08-04 13:37:46.387821728 +0200 -@@ -8,6 +8,7 @@ - #[macro_use] - extern crate cubeb_ffi as cubeb; - extern crate pulse_ffi; -+extern crate pulse; - extern crate semver; - - mod capi; -diff -up firefox-55.0/media/libcubeb/cubeb-pulse-rs/update.sh.cubeb-pulse-arm firefox-55.0/media/libcubeb/cubeb-pulse-rs/update.sh ---- firefox-55.0/media/libcubeb/cubeb-pulse-rs/update.sh.cubeb-pulse-arm 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/media/libcubeb/cubeb-pulse-rs/update.sh 2017-08-04 13:37:46.383821740 +0200 -@@ -13,6 +13,9 @@ cp -pr $1/cubeb-ffi/src/* cubeb-ffi/src/ - test -d pulse-ffi/src || mkdir -p pulse-ffi/src - cp -pr $1/pulse-ffi/Cargo.toml pulse-ffi/ - cp -pr $1/pulse-ffi/src/* pulse-ffi/src/ -+test -d pulse-rs/src || mkdir -p pulse-rs/src -+cp -pr $1/pulse-rs/Cargo.toml pulse-rs/ -+cp -pr $1/pulse-rs/src/* pulse-rs/src/ - - if [ -d $1/.git ]; then - rev=$(cd $1 && git rev-parse --verify HEAD) -diff -up firefox-55.0/toolkit/library/gtest/rust/Cargo.lock.cubeb-pulse-arm firefox-55.0/toolkit/library/gtest/rust/Cargo.lock ---- firefox-55.0/toolkit/library/gtest/rust/Cargo.lock.cubeb-pulse-arm 2017-08-04 13:37:46.388821725 +0200 -+++ firefox-55.0/toolkit/library/gtest/rust/Cargo.lock 2017-08-04 13:59:15.592940994 +0200 -@@ -252,6 +252,7 @@ name = "cubeb-pulse" - version = "0.0.1" - dependencies = [ - "cubeb-ffi 0.0.1", -+ "pulse 0.1.0", - "pulse-ffi 0.1.0", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - ] -@@ -660,6 +661,14 @@ version = "0.1.1" - source = "registry+https://github.com/rust-lang/crates.io-index" - - [[package]] -+name = "pulse" -+version = "0.1.0" -+dependencies = [ -+ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "pulse-ffi 0.1.0", -+] -+ -+[[package]] - name = "pulse-ffi" - version = "0.1.0" - dependencies = [ -diff -up firefox-55.0/toolkit/library/rust/Cargo.lock.cubeb-pulse-arm firefox-55.0/toolkit/library/rust/Cargo.lock ---- firefox-55.0/toolkit/library/rust/Cargo.lock.cubeb-pulse-arm 2017-08-04 13:37:46.388821725 +0200 -+++ firefox-55.0/toolkit/library/rust/Cargo.lock 2017-08-04 13:52:24.551163669 +0200 -@@ -250,6 +250,7 @@ name = "cubeb-pulse" - version = "0.0.1" - dependencies = [ - "cubeb-ffi 0.0.1", -+ "pulse 0.1.0", - "pulse-ffi 0.1.0", - "semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - ] -@@ -647,6 +648,14 @@ version = "0.1.1" - source = "registry+https://github.com/rust-lang/crates.io-index" - - [[package]] -+name = "pulse" -+version = "0.1.0" -+dependencies = [ -+ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -+ "pulse-ffi 0.1.0", -+] -+ -+[[package]] - name = "pulse-ffi" - version = "0.1.0" - dependencies = [ diff --git a/build-disable-elfhack.patch b/build-disable-elfhack.patch deleted file mode 100644 index 04d49f2..0000000 --- a/build-disable-elfhack.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up firefox-97.0/toolkit/moz.configure.disable-elfhack firefox-97.0/toolkit/moz.configure ---- firefox-97.0/toolkit/moz.configure.disable-elfhack 2022-02-08 09:58:47.518047952 +0100 -+++ firefox-97.0/toolkit/moz.configure 2022-02-08 10:17:49.552945956 +0100 -@@ -1273,7 +1273,7 @@ with only_when("--enable-compile-environ - help="{Enable|Disable} elf hacks", - ) - -- set_config("USE_ELF_HACK", depends_if("--enable-elf-hack")(lambda _: True)) -+ set_config("USE_ELF_HACK", depends_if("--enable-elf-hack")(lambda _: False)) - - - @depends(build_environment) diff --git a/build-ppc-jit.patch b/build-ppc-jit.patch deleted file mode 100644 index a9dc6d1..0000000 --- a/build-ppc-jit.patch +++ /dev/null @@ -1,51 +0,0 @@ -diff -up firefox-55.0/js/src/jit/MIR.h.old firefox-55.0/js/src/jit/MIR.h ---- firefox-55.0/js/src/jit/MIR.h.old 2017-08-08 14:04:44.528460099 +0200 -+++ firefox-55.0/js/src/jit/MIR.h 2017-08-08 14:05:11.045364831 +0200 -@@ -12434,7 +12434,7 @@ class MNearbyInt - TRIVIAL_NEW_WRAPPERS - - static bool HasAssemblerSupport(RoundingMode mode) { -- return Assembler::HasRoundInstruction(mode); -+ return false; - } - - RoundingMode roundingMode() const { return roundingMode_; } -diff -up firefox-55.0/js/src/jit/ExecutableAllocator.h.old firefox-55.0/js/src/jit/ExecutableAllocator.h ---- firefox-55.0/js/src/jit/ExecutableAllocator.h.old 2017-08-09 09:24:18.784983505 +0200 -+++ firefox-55.0/js/src/jit/ExecutableAllocator.h 2017-08-09 09:28:01.471100075 +0200 -@@ -307,6 +307,10 @@ class ExecutableAllocator - { - sync_instruction_memory((caddr_t)code, size); - } -+#else -+ static void cacheFlush(void*, size_t) -+ { -+ } - #endif - - private: -diff -up firefox-55.0/js/src/wasm/WasmBuiltins.cpp.old firefox-55.0/js/src/wasm/WasmBuiltins.cpp ---- firefox-55.0/js/src/wasm/WasmBuiltins.cpp.old 2017-08-09 12:50:46.877450765 +0200 -+++ firefox-55.0/js/src/wasm/WasmBuiltins.cpp 2017-08-09 12:50:59.725406974 +0200 -@@ -881,7 +881,6 @@ wasm::EnsureBuiltinThunksInitialized() - MOZ_ASSERT(!masm.numSymbolicAccesses()); - #endif - -- ExecutableAllocator::cacheFlush(thunks->codeBase, thunks->codeSize); - if (!ExecutableAllocator::makeExecutable(thunks->codeBase, thunks->codeSize)) - return false; - -diff -up firefox-55.0/js/src/wasm/WasmCode.cpp.old firefox-55.0/js/src/wasm/WasmCode.cpp ---- firefox-55.0/js/src/wasm/WasmCode.cpp.old 2017-08-09 12:50:37.205483731 +0200 -+++ firefox-55.0/js/src/wasm/WasmCode.cpp 2017-08-09 12:51:10.365370708 +0200 -@@ -287,8 +287,6 @@ CodeSegment::initialize(Tier tier, - if (!StaticallyLink(*this, linkData)) - return false; - -- ExecutableAllocator::cacheFlush(bytes_.get(), RoundupCodeLength(codeLength)); -- - // Reprotect the whole region to avoid having separate RW and RX mappings. - if (!ExecutableAllocator::makeExecutable(bytes_.get(), RoundupCodeLength(codeLength))) - return false; -diff -up firefox-55.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.old firefox-55.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium -diff -up firefox-55.0/media/webrtc/trunk/Makefile.old firefox-55.0/media/webrtc/trunk/Makefile diff --git a/build-python.patch b/build-python.patch deleted file mode 100644 index eae8e18..0000000 --- a/build-python.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up firefox-95.0/build/mach_virtualenv_packages.txt.pytpatch firefox-95.0/build/mach_virtualenv_packages.txt ---- firefox-95.0/build/mach_virtualenv_packages.txt.pytpatch 2021-12-06 07:52:44.829038010 +0100 -+++ firefox-95.0/build/mach_virtualenv_packages.txt 2021-12-06 07:53:56.676269562 +0100 -@@ -1,7 +1,7 @@ - packages.txt:build/common_virtualenv_packages.txt - # glean-sdk may not be installable if a wheel isn't available - # and it has to be built from source. --pypi-optional:glean-sdk==40.0.0:telemetry will not be collected -+pypi-optional:glean-sdk>=40.0.0,<=42.2.0:telemetry will not be collected - # Mach gracefully handles the case where `psutil` is unavailable. - # We aren't (yet) able to pin packages in automation, so we have to - # support down to the oldest locally-installed version (5.4.2). diff --git a/build-rust-ppc64le.patch b/build-rust-ppc64le.patch deleted file mode 100644 index 2474c35..0000000 --- a/build-rust-ppc64le.patch +++ /dev/null @@ -1,25 +0,0 @@ -diff -up firefox-55.0/build/moz.configure/rust.configure.rust-ppc64le firefox-55.0/build/moz.configure/rust.configure ---- firefox-55.0/build/moz.configure/rust.configure.rust-ppc64le 2017-07-31 18:20:49.000000000 +0200 -+++ firefox-55.0/build/moz.configure/rust.configure 2017-08-02 10:19:03.254220003 +0200 -@@ -151,6 +151,9 @@ def rust_triple_alias(host_or_target): - ('sparc64', 'Linux'): 'sparc64-unknown-linux-gnu', - ('x86', 'Linux'): 'i686-unknown-linux-gnu', - ('x86_64', 'Linux'): 'x86_64-unknown-linux-gnu', -+ ('ppc64le', 'Linux'): 'powerpc64le-unknown-linux-gnu', -+ ('ppc64', 'Linux'): 'powerpc64-unknown-linux-gnu', -+ ('s390x', 'Linux'): 's390x-unknown-linux-gnu', - # OS X - ('x86', 'OSX'): 'i686-apple-darwin', - ('x86_64', 'OSX'): 'x86_64-apple-darwin', -@@ -174,8 +177,10 @@ def rust_triple_alias(host_or_target): - ('sparc64', 'SunOS'): 'sparcv9-sun-solaris', - }.get((host_or_target.cpu, os_or_kernel), None) - -+ if (rustc_target == 'powerpc64-unknown-linux-gnu' and host_or_target.endianness == 'little'): -+ rustc_target = 'powerpc64le-unknown-linux-gnu' - if rustc_target is None: -- die("Don't know how to translate {} for rustc".format(host_or_target.alias)) -+ die("Don't know how to translate {} for rustc, cpu: {}, os: {}".format(target.alias, target.cpu, os_or_kernel)) - - # Check to see whether our rustc has a reasonably functional stdlib - # for our chosen target. diff --git a/build-seccomp.patch b/build-seccomp.patch new file mode 100644 index 0000000..b57f65a --- /dev/null +++ b/build-seccomp.patch @@ -0,0 +1,11 @@ +diff -up thunderbird-145.0/security/sandbox/chromium/sandbox/linux/system_headers/linux_seccomp.h.seccomp thunderbird-145.0/security/sandbox/chromium/sandbox/linux/system_headers/linux_seccomp.h +--- thunderbird-145.0/security/sandbox/chromium/sandbox/linux/system_headers/linux_seccomp.h.seccomp 2025-12-09 13:42:31.378958842 +0100 ++++ thunderbird-145.0/security/sandbox/chromium/sandbox/linux/system_headers/linux_seccomp.h 2025-12-09 13:42:37.886937626 +0100 +@@ -6,6 +6,7 @@ + #define SANDBOX_LINUX_SYSTEM_HEADERS_LINUX_SECCOMP_H_ + + #include ++#include + #include + + #include "build/build_config.h" diff --git a/disable-openh264-download.patch b/disable-openh264-download.patch index 028b730..0631850 100644 --- a/disable-openh264-download.patch +++ b/disable-openh264-download.patch @@ -1,32 +1,30 @@ -diff -up firefox-81.0/toolkit/modules/GMPInstallManager.jsm.old firefox-81.0/toolkit/modules/GMPInstallManager.jsm ---- firefox-81.0/toolkit/modules/GMPInstallManager.jsm.old 2020-09-25 10:39:04.769458703 +0200 -+++ firefox-81.0/toolkit/modules/GMPInstallManager.jsm 2020-09-25 10:39:22.038504747 +0200 -@@ -54,10 +54,6 @@ function getScopedLogger(prefix) { - - const LOCAL_GMP_SOURCES = [ - { -- id: "gmp-gmpopenh264", -- src: "chrome://global/content/gmp-sources/openh264.json", -- }, -- { - id: "gmp-widevinecdm", - src: "chrome://global/content/gmp-sources/widevinecdm.json", - }, -diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn ---- a/toolkit/content/jar.mn -+++ b/toolkit/content/jar.mn -@@ -108,7 +108,6 @@ toolkit.jar: +diff -up firefox-121.0/toolkit/content/jar.mn.disable-openh264-download firefox-121.0/toolkit/content/jar.mn +--- firefox-121.0/toolkit/content/jar.mn.disable-openh264-download 2023-12-18 20:15:04.352014249 +0100 ++++ firefox-121.0/toolkit/content/jar.mn 2023-12-18 20:19:26.857929200 +0100 +@@ -130,7 +130,6 @@ toolkit.jar: #ifdef XP_MACOSX content/global/macWindowMenu.js #endif - content/global/gmp-sources/openh264.json (gmp-sources/openh264.json) content/global/gmp-sources/widevinecdm.json (gmp-sources/widevinecdm.json) + content/global/gmp-sources/widevinecdm_l1.json (gmp-sources/widevinecdm_l1.json) - # Third party files -diff --git a/toolkit/modules/GMPInstallManager.jsm b/toolkit/modules/GMPInstallManager.jsm ---- a/toolkit/modules/GMPInstallManager.jsm -+++ b/toolkit/modules/GMPInstallManager.jsm -@@ -238,6 +234,9 @@ GMPInstallManager.prototype = { +diff -up firefox-121.0/toolkit/modules/GMPInstallManager.sys.mjs.disable-openh264-download firefox-121.0/toolkit/modules/GMPInstallManager.sys.mjs +--- firefox-121.0/toolkit/modules/GMPInstallManager.sys.mjs.disable-openh264-download 2023-12-11 21:42:21.000000000 +0100 ++++ firefox-121.0/toolkit/modules/GMPInstallManager.sys.mjs 2023-12-18 20:18:52.665768579 +0100 +@@ -35,11 +35,6 @@ function getScopedLogger(prefix) { + + const LOCAL_GMP_SOURCES = [ + { +- id: "gmp-gmpopenh264", +- src: "chrome://global/content/gmp-sources/openh264.json", +- installByDefault: true, +- }, +- { + id: "gmp-widevinecdm", + src: "chrome://global/content/gmp-sources/widevinecdm.json", + installByDefault: true, +@@ -421,6 +416,9 @@ GMPInstallManager.prototype = { * downloaderr, verifyerr or previouserrorencountered */ installAddon(gmpAddon) { @@ -36,4 +34,3 @@ diff --git a/toolkit/modules/GMPInstallManager.jsm b/toolkit/modules/GMPInstallM if (this._deferred) { let log = getScopedLogger("GMPInstallManager.installAddon"); log.error("previous error encountered"); - diff --git a/distribution.ini b/distribution.ini deleted file mode 100644 index 11f1f96..0000000 --- a/distribution.ini +++ /dev/null @@ -1,9 +0,0 @@ -[Global] -id=fedora -version=1.0 -about=Mozilla Firefox for Fedora - -[Preferences] -app.distributor=fedora -app.distributor.channel=fedora -app.partner.fedora=fedora diff --git a/distribution.ini.in b/distribution.ini.in new file mode 100644 index 0000000..0eaacc7 --- /dev/null +++ b/distribution.ini.in @@ -0,0 +1,9 @@ +[Global] +id=__ID__ +version=1.0 +about=Mozilla Firefox for __NAME__ + +[Preferences] +app.distributor=__ID__ +app.distributor.channel=__ID__ +app.partner.fedora=__ID__ diff --git a/fedora-build.patch b/fedora-build.patch deleted file mode 100644 index 74127ec..0000000 --- a/fedora-build.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff -up firefox-54.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.old firefox-54.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium -diff -up firefox-54.0/media/mtransport/third_party/nICEr/nicer.gyp.old firefox-54.0/media/mtransport/third_party/nICEr/nicer.gyp ---- firefox-54.0/media/mtransport/third_party/nICEr/nicer.gyp.old 2017-06-08 14:59:08.786996664 +0200 -+++ firefox-54.0/media/mtransport/third_party/nICEr/nicer.gyp 2017-06-08 14:59:22.642946570 +0200 -@@ -211,7 +211,6 @@ - '-Wno-parentheses', - '-Wno-strict-prototypes', - '-Wmissing-prototypes', -- '-Wno-format', - ], - 'defines' : [ - 'LINUX', -diff -up firefox-54.0/media/mtransport/third_party/nrappkit/nrappkit.gyp.build firefox-54.0/media/mtransport/third_party/nrappkit/nrappkit.gyp ---- firefox-54.0/media/mtransport/third_party/nrappkit/nrappkit.gyp.build 2017-06-08 15:08:03.627063097 +0200 -+++ firefox-54.0/media/mtransport/third_party/nrappkit/nrappkit.gyp 2017-06-08 15:08:15.657019606 +0200 -@@ -206,7 +206,6 @@ - '-Wno-parentheses', - '-Wno-strict-prototypes', - '-Wmissing-prototypes', -- '-Wno-format', - ], - 'defines' : [ - 'LINUX', diff --git a/fedora-customization.patch b/fedora-customization.patch new file mode 100644 index 0000000..395f48d --- /dev/null +++ b/fedora-customization.patch @@ -0,0 +1,17 @@ +diff -up firefox-124.0/toolkit/xre/nsAppRunner.cpp.fedora-customization firefox-124.0/toolkit/xre/nsAppRunner.cpp +diff -up firefox-124.0/widget/gtk/nsWindow.cpp.fedora-customization firefox-124.0/widget/gtk/nsWindow.cpp +--- firefox-124.0/widget/gtk/nsWindow.cpp.fedora-customization 2024-03-13 12:35:57.098591719 +0100 ++++ firefox-124.0/widget/gtk/nsWindow.cpp 2024-03-13 12:43:17.375928494 +0100 +@@ -3459,6 +3459,12 @@ nsresult nsWindow::SetTitle(const nsAStr + return NS_OK; + } + ++ const char* appTitle = getenv("MOZ_APP_TITLE"); ++ if (appTitle) { ++ gtk_window_set_title(GTK_WINDOW(mShell), appTitle); ++ return NS_OK; ++ } ++ + // convert the string into utf8 and set the title. + #define UTF8_FOLLOWBYTE(ch) (((ch) & 0xC0) == 0x80) + NS_ConvertUTF16toUTF8 titleUTF8(aTitle); diff --git a/fedora-shebang-build.patch b/fedora-shebang-build.patch deleted file mode 100644 index 9ade86c..0000000 --- a/fedora-shebang-build.patch +++ /dev/null @@ -1,9 +0,0 @@ -diff -up firefox-73.0/build/unix/run-mozilla.sh.old firefox-73.0/build/unix/run-mozilla.sh ---- firefox-73.0/build/unix/run-mozilla.sh.old 2020-02-12 09:58:00.150895904 +0100 -+++ firefox-73.0/build/unix/run-mozilla.sh 2020-02-12 09:58:06.505860696 +0100 -@@ -1,4 +1,4 @@ --#!/bin/sh -+#!/usr/bin/sh - # - # This Source Code Form is subject to the terms of the Mozilla Public - # License, v. 2.0. If a copy of the MPL was not distributed with this diff --git a/firefox-enable-addons.patch b/firefox-enable-addons.patch index 15d0707..75e1403 100644 --- a/firefox-enable-addons.patch +++ b/firefox-enable-addons.patch @@ -1,10 +1,10 @@ -diff -up firefox-55.0/browser/app/profile/firefox.js.addons firefox-55.0/browser/app/profile/firefox.js ---- firefox-55.0/browser/app/profile/firefox.js.addons 2017-08-02 10:58:30.566363833 +0200 -+++ firefox-55.0/browser/app/profile/firefox.js 2017-08-02 10:59:15.377216959 +0200 -@@ -65,7 +65,8 @@ pref("extensions.systemAddon.update.url" +diff -up firefox-125.0/browser/app/profile/firefox.js.addons firefox-125.0/browser/app/profile/firefox.js +--- firefox-125.0/browser/app/profile/firefox.js.addons 2024-04-09 10:34:30.728405003 +0200 ++++ firefox-125.0/browser/app/profile/firefox.js 2024-04-09 10:36:01.444584632 +0200 +@@ -58,7 +58,8 @@ pref("extensions.systemAddon.update.enab // Disable add-ons that are not installed by the user in all scopes by default. - // See the SCOPE constants in AddonManager.jsm for values to use here. + // See the SCOPE constants in AddonManager.sys.mjs for values to use here. -pref("extensions.autoDisableScopes", 15); +pref("extensions.autoDisableScopes", 0); +pref("extensions.showMismatchUI", false); diff --git a/firefox-gcc-13-build.patch b/firefox-gcc-13-build.patch new file mode 100644 index 0000000..8512b76 --- /dev/null +++ b/firefox-gcc-13-build.patch @@ -0,0 +1,24 @@ +--- firefox-109.0.1/gfx/2d/Rect.h.old 2023-02-07 09:44:24.946279843 +0100 ++++ firefox-109.0.1/gfx/2d/Rect.h 2023-02-07 09:44:47.969032049 +0100 +@@ -324,8 +324,8 @@ IntRectTyped RoundedToInt(const R + + template + bool RectIsInt32Safe(const RectTyped& aRect) { +- float min = (float)std::numeric_limits::min(); +- float max = (float)std::numeric_limits::max(); ++ float min = (float)std::numeric_limits::min(); ++ float max = (float)std::numeric_limits::max(); + return aRect.x > min && aRect.y > min && aRect.width < max && + aRect.height < max && aRect.XMost() < max && aRect.YMost() < max; + } +diff -up firefox-109.0.1/toolkit/components/telemetry/pingsender/pingsender.cpp.old firefox-109.0.1/toolkit/components/telemetry/pingsender/pingsender.cpp +--- firefox-109.0.1/toolkit/components/telemetry/pingsender/pingsender.cpp.old 2023-02-07 11:03:41.788720090 +0100 ++++ firefox-109.0.1/toolkit/components/telemetry/pingsender/pingsender.cpp 2023-02-07 11:04:29.195345659 +0100 +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include + diff --git a/firefox-gcc-15.0-s390.patch b/firefox-gcc-15.0-s390.patch new file mode 100644 index 0000000..9cf82fc --- /dev/null +++ b/firefox-gcc-15.0-s390.patch @@ -0,0 +1,19 @@ +diff -up firefox-137.0.2/toolkit/components/protobuf/src/google/protobuf/port_def.inc.s390 firefox-137.0.2/toolkit/components/protobuf/src/google/protobuf/port_def.inc +--- firefox-137.0.2/toolkit/components/protobuf/src/google/protobuf/port_def.inc.s390 2025-04-22 11:42:00.650759505 +0200 ++++ firefox-137.0.2/toolkit/components/protobuf/src/google/protobuf/port_def.inc 2025-04-22 11:46:02.522031338 +0200 +@@ -257,12 +257,14 @@ + #if __has_cpp_attribute(clang::musttail) && !defined(__arm__) && \ + !defined(_ARCH_PPC) && !defined(__wasm__) && \ + !(defined(_MSC_VER) && defined(_M_IX86)) && \ +- !(defined(__NDK_MAJOR__) && __NDK_MAJOR <= 24) ++ !(defined(__NDK_MAJOR__) && __NDK_MAJOR <= 24) && \ ++ !defined(__s390__) + # ifndef PROTO2_OPENSOURCE + // Compilation fails on ARM32: b/195943306 + // Compilation fails on powerpc64le: b/187985113 + // Compilation fails on X86 Windows: + // https://github.com/llvm/llvm-project/issues/53271 ++// Compilation fails on S390 for calls with more than 4 arguments + # endif + #define PROTOBUF_MUSTTAIL [[clang::musttail]] + #define PROTOBUF_TAILCALL true diff --git a/firefox-gcc-always-inline.patch b/firefox-gcc-always-inline.patch new file mode 100644 index 0000000..d7af60f --- /dev/null +++ b/firefox-gcc-always-inline.patch @@ -0,0 +1,14 @@ +diff -up firefox-114.0.2/gfx/wr/swgl/src/gl.cc.inline firefox-114.0.2/gfx/wr/swgl/src/gl.cc +--- firefox-114.0.2/gfx/wr/swgl/src/gl.cc.inline 2023-06-22 11:08:53.294593327 +0200 ++++ firefox-114.0.2/gfx/wr/swgl/src/gl.cc 2023-06-22 11:12:43.663486734 +0200 +@@ -58,9 +58,7 @@ WINBASEAPI BOOL WINAPI QueryPerformanceF + } + + #else +-// GCC is slower when dealing with always_inline, especially in debug builds. +-// When using Clang, use always_inline more aggressively. +-# if defined(__clang__) || defined(NDEBUG) ++# if defined(__clang__) || defined (__GNUC__) || defined(NDEBUG) + # define ALWAYS_INLINE __attribute__((always_inline)) inline + # else + # define ALWAYS_INLINE inline diff --git a/firefox-glibc-dynstack.patch b/firefox-glibc-dynstack.patch deleted file mode 100644 index b0487d7..0000000 --- a/firefox-glibc-dynstack.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff -ur firefox-90.0.orig/js/xpconnect/src/XPCJSContext.cpp firefox-90.0/js/xpconnect/src/XPCJSContext.cpp ---- firefox-90.0.orig/js/xpconnect/src/XPCJSContext.cpp 2021-07-05 21:16:02.000000000 +0200 -+++ firefox-90.0/js/xpconnect/src/XPCJSContext.cpp 2021-07-19 15:01:24.083460460 +0200 -@@ -85,14 +85,6 @@ - using namespace xpc; - using namespace JS; - --// The watchdog thread loop is pretty trivial, and should not require much stack --// space to do its job. So only give it 32KiB or the platform minimum. --#if !defined(PTHREAD_STACK_MIN) --# define PTHREAD_STACK_MIN 0 --#endif --static constexpr size_t kWatchdogStackSize = -- PTHREAD_STACK_MIN < 32 * 1024 ? 32 * 1024 : PTHREAD_STACK_MIN; -- - static void WatchdogMain(void* arg); - class Watchdog; - class WatchdogManager; -@@ -163,7 +155,7 @@ - // watchdog, we need to join it on shutdown. - mThread = PR_CreateThread(PR_USER_THREAD, WatchdogMain, this, - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, -- PR_JOINABLE_THREAD, kWatchdogStackSize); -+ PR_JOINABLE_THREAD, 0); - if (!mThread) { - MOZ_CRASH("PR_CreateThread failed!"); - } -Only in firefox-90.0/js/xpconnect/src: XPCJSContext.cpp.firefox-glibc-dynstack -diff -ur firefox-90.0.orig/security/sandbox/linux/launch/SandboxLaunch.cpp firefox-90.0/security/sandbox/linux/launch/SandboxLaunch.cpp ---- firefox-90.0.orig/security/sandbox/linux/launch/SandboxLaunch.cpp 2021-07-05 18:20:36.000000000 +0200 -+++ firefox-90.0/security/sandbox/linux/launch/SandboxLaunch.cpp 2021-07-20 08:39:17.272136982 +0200 -@@ -501,8 +501,7 @@ - MOZ_NEVER_INLINE MOZ_ASAN_BLACKLIST static pid_t DoClone(int aFlags, - jmp_buf* aCtx) { - static constexpr size_t kStackAlignment = 16; -- uint8_t miniStack[PTHREAD_STACK_MIN] -- __attribute__((aligned(kStackAlignment))); -+ uint8_t miniStack[4096] __attribute__((aligned(kStackAlignment))); - #ifdef __hppa__ - void* stackPtr = miniStack; - #else -@@ -523,13 +522,19 @@ - CLONE_CHILD_CLEARTID; - MOZ_RELEASE_ASSERT((aFlags & kBadFlags) == 0); - -+ // Block signals due to small stack in DoClone. -+ sigset_t oldSigs; -+ BlockAllSignals(&oldSigs); -+ -+ int ret = 0; - jmp_buf ctx; - if (setjmp(ctx) == 0) { - // In the parent and just called setjmp: -- return DoClone(aFlags | SIGCHLD, &ctx); -+ ret = DoClone(aFlags | SIGCHLD, &ctx); - } -+ RestoreSignals(&oldSigs); - // In the child and have longjmp'ed: -- return 0; -+ return ret; - } - - static bool WriteStringToFile(const char* aPath, const char* aStr, -Only in firefox-90.0/security/sandbox/linux/launch: SandboxLaunch.cpp~ diff --git a/firefox-i686-build.patch b/firefox-i686-build.patch new file mode 100644 index 0000000..320199f --- /dev/null +++ b/firefox-i686-build.patch @@ -0,0 +1,12 @@ +diff -up firefox-105.0/mozglue/misc/SIMD_avx2.cpp.old firefox-105.0/mozglue/misc/SIMD_avx2.cpp +--- firefox-105.0/mozglue/misc/SIMD_avx2.cpp.old 2022-09-22 21:35:07.006221995 +0200 ++++ firefox-105.0/mozglue/misc/SIMD_avx2.cpp 2022-09-22 21:36:12.972480517 +0200 +@@ -55,7 +55,7 @@ __m256i CmpEq256(__m256i a, __m256i b) { + return _mm256_cmpeq_epi64(a, b); + } + +-# if defined(__GNUC__) && !defined(__clang__) ++# if 0 + + // See the comment in SIMD.cpp over Load32BitsIntoXMM. This is just adapted + // from that workaround. Testing this, it also yields the correct instructions diff --git a/firefox-kde-webrender.patch b/firefox-kde-webrender.patch deleted file mode 100644 index f5f4ac7..0000000 --- a/firefox-kde-webrender.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff -up firefox-87.0/widget/GfxInfoX11.cpp.firefox-kde-webrender firefox-87.0/widget/GfxInfoX11.cpp ---- firefox-87.0/widget/GfxInfoX11.cpp.firefox-kde-webrender 2021-03-22 19:55:59.169952960 +0100 -+++ firefox-87.0/widget/GfxInfoX11.cpp 2021-03-22 20:04:35.332183657 +0100 -@@ -738,6 +738,14 @@ const nsTArray& GfxInfo:: - DRIVER_GREATER_THAN_OR_EQUAL, V(17, 0, 0, 0), - "FEATURE_ROLLOUT_INTEL_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0"); - -+ APPEND_TO_DRIVER_BLOCKLIST_EXT( -+ OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All, -+ DesktopEnvironment::KDE, WindowProtocol::Wayland, -+ DriverVendor::MesaAll, DeviceFamily::IntelRolloutWebRender, -+ nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_ALLOW_ALWAYS, -+ DRIVER_GREATER_THAN_OR_EQUAL, V(17, 0, 0, 0), -+ "FEATURE_ROLLOUT_INTEL_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0"); -+ - // ATI Mesa baseline, chosen arbitrarily. - APPEND_TO_DRIVER_BLOCKLIST_EXT( - OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All, -@@ -754,6 +762,14 @@ const nsTArray& GfxInfo:: - DRIVER_GREATER_THAN_OR_EQUAL, V(17, 0, 0, 0), - "FEATURE_ROLLOUT_ATI_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0"); - -+ APPEND_TO_DRIVER_BLOCKLIST_EXT( -+ OperatingSystem::Linux, ScreenSizeStatus::All, BatteryStatus::All, -+ DesktopEnvironment::KDE, WindowProtocol::Wayland, -+ DriverVendor::MesaAll, DeviceFamily::AtiRolloutWebRender, -+ nsIGfxInfo::FEATURE_WEBRENDER, nsIGfxInfo::FEATURE_ALLOW_ALWAYS, -+ DRIVER_GREATER_THAN_OR_EQUAL, V(17, 0, 0, 0), -+ "FEATURE_ROLLOUT_ATI_GNOME_WAYLAND_MESA", "Mesa 17.0.0.0"); -+ - #ifdef EARLY_BETA_OR_EARLIER - // Intel Mesa baseline, chosen arbitrarily. - APPEND_TO_DRIVER_BLOCKLIST_EXT( diff --git a/firefox-mozconfig b/firefox-mozconfig index 90dfccf..2736abc 100644 --- a/firefox-mozconfig +++ b/firefox-mozconfig @@ -2,7 +2,6 @@ ac_add_options --with-system-zlib ac_add_options --disable-strip -#ac_add_options --enable-libnotify ac_add_options --enable-necko-wifi ac_add_options --disable-updater ac_add_options --enable-chrome-format=omni @@ -15,8 +14,7 @@ ac_add_options --allow-addon-sideload ac_add_options --with-system-fdk-aac ac_add_options --enable-js-shell ac_add_options --with-unsigned-addon-scopes=app,system -ac_add_options --without-sysroot -ac_add_options --without-wasm-sandboxed-libraries +ac_add_options --disable-bootstrap export BUILD_OFFICIAL=1 export MOZILLA_OFFICIAL=1 diff --git a/firefox-nss-version.patch b/firefox-nss-version.patch deleted file mode 100644 index 21985d1..0000000 --- a/firefox-nss-version.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up firefox-84.0.1/build/moz.configure/nss.configure.nss-version firefox-84.0.1/build/moz.configure/nss.configure ---- firefox-84.0.1/build/moz.configure/nss.configure.nss-version 2020-12-21 20:07:33.000000000 +0100 -+++ firefox-84.0.1/build/moz.configure/nss.configure 2020-12-22 10:23:02.156625919 +0100 -@@ -9,7 +9,7 @@ option("--with-system-nss", help="Use sy - imply_option("--with-system-nspr", True, when="--with-system-nss") - - nss_pkg = pkg_check_modules( -- "NSS", "nss >= 3.59.1", when="--with-system-nss", config=False -+ "NSS", "nss >= 3.59", when="--with-system-nss", config=False - ) - - set_config("MOZ_SYSTEM_NSS", True, when="--with-system-nss") diff --git a/firefox-redhat-default-prefs.js b/firefox-redhat-default-prefs.js index 6fcee25..979f21b 100644 --- a/firefox-redhat-default-prefs.js +++ b/firefox-redhat-default-prefs.js @@ -7,7 +7,6 @@ pref("toolkit.storage.synchronous", 0); pref("toolkit.networkmanager.disable", false); pref("offline.autoDetect", true); pref("browser.backspace_action", 2); -pref("browser.display.use_system_colors", true); pref("browser.download.folderList", 1); pref("browser.link.open_external", 3); pref("browser.shell.checkDefaultBrowser", false); @@ -22,8 +21,6 @@ pref("media.gmp-gmpopenh264.autoupdate",false); pref("media.gmp-gmpopenh264.enabled",false); pref("media.gmp.decoder.enabled", true); pref("plugins.notifyMissingFlash", false); -/* See https://bugzilla.redhat.com/show_bug.cgi?id=1226489 */ -pref("browser.display.use_system_colors", false); /* Allow sending credetials to all https:// sites */ pref("network.negotiate-auth.trusted-uris", "https://"); pref("spellchecker.dictionary_path","/usr/share/hunspell"); diff --git a/firefox-search-provider.ini b/firefox-search-provider.ini deleted file mode 100644 index 3868e3d..0000000 --- a/firefox-search-provider.ini +++ /dev/null @@ -1,5 +0,0 @@ -[Shell Search Provider] -DesktopId=firefox.desktop -BusName=org.mozilla.Firefox.SearchProvider -ObjectPath=/org/mozilla/Firefox/SearchProvider -Version=2 diff --git a/firefox-testing.patch b/firefox-testing.patch deleted file mode 100644 index d380b48..0000000 --- a/firefox-testing.patch +++ /dev/null @@ -1,69 +0,0 @@ -diff -up firefox-96.0.1/docshell/base/crashtests/crashtests.list.testing firefox-96.0.1/docshell/base/crashtests/crashtests.list ---- firefox-96.0.1/docshell/base/crashtests/crashtests.list.testing 2022-01-13 20:26:02.000000000 +0100 -+++ firefox-96.0.1/docshell/base/crashtests/crashtests.list 2022-01-18 10:42:02.642971427 +0100 -@@ -13,7 +13,6 @@ load 614499-1.html - load 678872-1.html - skip-if(Android) pref(dom.disable_open_during_load,false) load 914521.html # Android bug 1584562 - pref(browser.send_pings,true) asserts(0-2) load 1257730-1.html # bug 566159 --load 1331295.html - load 1341657.html - load 1584467.html - load 1614211-1.html -diff -up firefox-96.0.1/dom/media/tests/crashtests/crashtests.list.testing firefox-96.0.1/dom/media/tests/crashtests/crashtests.list ---- firefox-96.0.1/dom/media/tests/crashtests/crashtests.list.testing 2022-01-13 20:26:03.000000000 +0100 -+++ firefox-96.0.1/dom/media/tests/crashtests/crashtests.list 2022-01-18 10:42:02.642971427 +0100 -@@ -25,7 +25,6 @@ asserts-if(Android,0-1) pref(browser.lin - load 1443212.html - asserts-if(Android,0-2) load 1453030.html - load 1468451.html --skip-if(Android) load 1490700.html # No screenshare on Android - load 1505957.html - load 1509442.html - load 1511130.html -diff -up firefox-96.0.1/testing/marionette/harness/marionette_harness/tests/unit/test_marionette.py.testing firefox-96.0.1/testing/marionette/harness/marionette_harness/tests/unit/test_marionette.py ---- firefox-96.0.1/testing/marionette/harness/marionette_harness/tests/unit/test_marionette.py.testing 2022-01-13 20:26:09.000000000 +0100 -+++ firefox-96.0.1/testing/marionette/harness/marionette_harness/tests/unit/test_marionette.py 2022-01-18 10:42:02.642971427 +0100 -@@ -98,15 +98,7 @@ class TestMarionette(MarionetteTestCase) - - def test_application_update_disabled(self): - # Updates of the application should always be disabled by default -- with self.marionette.using_context("chrome"): -- update_allowed = self.marionette.execute_script( -- """ -- let aus = Cc['@mozilla.org/updates/update-service;1'] -- .getService(Ci.nsIApplicationUpdateService); -- return aus.canCheckForUpdates; -- """ -- ) -- -+ update_allowed = False - self.assertFalse(update_allowed) - - -diff -up firefox-96.0.1/testing/tools/websocketprocessbridge/websocketprocessbridge_requirements_3.txt.testing firefox-96.0.1/testing/tools/websocketprocessbridge/websocketprocessbridge_requirements_3.txt ---- firefox-96.0.1/testing/tools/websocketprocessbridge/websocketprocessbridge_requirements_3.txt.testing 2022-01-13 23:26:17.000000000 +0100 -+++ firefox-96.0.1/testing/tools/websocketprocessbridge/websocketprocessbridge_requirements_3.txt 2022-01-18 10:42:02.642971427 +0100 -@@ -1,6 +1,7 @@ - # This file is the websocketprocess requirements.txt used with python 3. - - six -+pyrsistent - vcversioner==2.16.0.0 - twisted>=18.7.0 - -diff -up firefox-96.0.1/toolkit/crashreporter/test/unit/xpcshell.ini.testing firefox-96.0.1/toolkit/crashreporter/test/unit/xpcshell.ini ---- firefox-96.0.1/toolkit/crashreporter/test/unit/xpcshell.ini.testing 2022-01-13 23:26:17.000000000 +0100 -+++ firefox-96.0.1/toolkit/crashreporter/test/unit/xpcshell.ini 2022-01-18 10:58:40.574277255 +0100 -@@ -37,7 +37,6 @@ skip-if = (os != 'win' && os != 'linux') - - [test_crash_AsyncShutdown.js] - [test_event_files.js] --[test_crash_terminator.js] - - [test_crash_backgroundtask_moz_crash.js] - skip-if = os == 'win' -@@ -123,4 +122,3 @@ head = head_crashreporter.js head_win64c - skip-if = !(os == 'win' && bits == 64 && processor == 'x86_64') - reason = Windows test specific to the x86-64 architecture - support-files = test_crash_win64cfi_not_a_pe.exe -- diff --git a/firefox-tests-reftest.patch b/firefox-tests-reftest.patch deleted file mode 100644 index 6800721..0000000 --- a/firefox-tests-reftest.patch +++ /dev/null @@ -1,514 +0,0 @@ -diff -U0 firefox-92.0/dom/canvas/test/reftest/filters/reftest.list.firefox-tests-reftest firefox-92.0/dom/canvas/test/reftest/filters/reftest.list ---- firefox-92.0/dom/canvas/test/reftest/filters/reftest.list.firefox-tests-reftest 2021-09-01 19:14:40.000000000 +0200 -+++ firefox-92.0/dom/canvas/test/reftest/filters/reftest.list 2021-09-03 18:44:02.933897050 +0200 -@@ -21 +21 @@ --== units-ex.html ref.html -+fuzzy-if(gtkWidget,0-255,0-100) == units-ex.html ref.html -diff -U0 firefox-92.0/dom/html/reftests/autofocus/reftest.list.firefox-tests-reftest firefox-92.0/dom/html/reftests/autofocus/reftest.list ---- firefox-92.0/dom/html/reftests/autofocus/reftest.list.firefox-tests-reftest 2021-09-01 19:14:40.000000000 +0200 -+++ firefox-92.0/dom/html/reftests/autofocus/reftest.list 2021-09-03 18:44:02.933897050 +0200 -@@ -7 +7 @@ --fuzzy-if(gtkWidget,0-18,0-1) needs-focus == textarea-load.html textarea-ref.html # One anti-aliased corner. -+fuzzy-if(gtkWidget,0-56,0-2) needs-focus == textarea-load.html textarea-ref.html # One anti-aliased corner. -diff -U0 firefox-92.0/dom/html/reftests/reftest.list.firefox-tests-reftest firefox-92.0/dom/html/reftests/reftest.list ---- firefox-92.0/dom/html/reftests/reftest.list.firefox-tests-reftest 2021-09-01 19:14:40.000000000 +0200 -+++ firefox-92.0/dom/html/reftests/reftest.list 2021-09-03 18:44:02.933897050 +0200 -@@ -46 +45,0 @@ --skip-if(isCoverageBuild) fuzzy(0-2,0-830) random-if(useDrawSnapshot) == bug917595-iframe-1.html bug917595-1-ref.html -diff -U0 firefox-92.0/dom/media/test/reftest/reftest.list.firefox-tests-reftest firefox-92.0/dom/media/test/reftest/reftest.list ---- firefox-92.0/dom/media/test/reftest/reftest.list.firefox-tests-reftest 2021-09-01 19:14:40.000000000 +0200 -+++ firefox-92.0/dom/media/test/reftest/reftest.list 2021-09-03 18:50:43.693907440 +0200 -@@ -0,0 +1,9 @@ -+skip-if(Android) fuzzy-if(OSX,0-80,0-76800) fuzzy-if(appleSilicon,92-92,76799-76799) fuzzy-if(winWidget,0-62,0-76799) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-70,0-2032) fuzzy-if(swgl,62-69,588-76737) HTTP(..) == short.mp4.firstframe.html short.mp4.firstframe-ref.html -+skip-if(Android) fuzzy-if(OSX,0-87,0-76797) fuzzy-if(appleSilicon,83-83,76797-76797) fuzzy-if(winWidget,0-60,0-76797) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-60,0-6070) fuzzy-if(swgl,52-76,1698-76545) HTTP(..) == short.mp4.lastframe.html short.mp4.lastframe-ref.html -+skip-if(Android) skip-if(cocoaWidget) skip-if(winWidget) fuzzy-if(gtkWidget&&layersGPUAccelerated,0-57,0-4282) fuzzy-if(OSX,55-80,4173-4417) fuzzy-if(swgl,54-54,3653-3653) HTTP(..) == bipbop_300_215kbps.mp4.lastframe.html bipbop_300_215kbps.mp4.lastframe-ref.html -+skip-if(Android) fuzzy-if(OSX,0-25,0-175921) fuzzy-if(appleSilicon,49-49,176063-176063) fuzzy-if(winWidget,0-71,0-179198) fuzzy-if((/^Windows\x20NT\x2010\.0/.test(http.oscpu))&&(/^aarch64-msvc/.test(xulRuntime.XPCOMABI)),0-255,0-179500) HTTP(..) == gizmo.mp4.seek.html gizmo.mp4.55thframe-ref.html -+skip-if(Android) skip-if(MinGW) skip-if((/^Windows\x20NT\x2010\.0/.test(http.oscpu))&&(/^aarch64-msvc/.test(xulRuntime.XPCOMABI))) fuzzy(0-10,0-778236) == image-10bits-rendering-video.html image-10bits-rendering-ref.html -+skip-if(Android) skip-if(MinGW) skip-if((/^Windows\x20NT\x2010\.0/.test(http.oscpu))&&(/^aarch64-msvc/.test(xulRuntime.XPCOMABI))) fuzzy(0-10,0-778536) == image-10bits-rendering-90-video.html image-10bits-rendering-90-ref.html -+skip-if(Android) fuzzy(0-27,0-573106) fuzzy-if(appleSilicon,46-46,575885-575885) == image-10bits-rendering-720-video.html image-10bits-rendering-720-ref.html -+skip-if(Android) fuzzy(0-31,0-573249) == image-10bits-rendering-720-90-video.html image-10bits-rendering-720-90-ref.html -+skip-if(Android) skip-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy(0-84,0-771156) fails-if(useDrawSnapshot) == uneven_frame_duration_video.html uneven_frame_duration_video-ref.html # Skip on Windows 7 as the resolution of the video is too high for test machines and will fail in the decoder. -diff -U0 firefox-92.0/dom/media/webvtt/test/reftest/reftest.list.firefox-tests-reftest firefox-92.0/dom/media/webvtt/test/reftest/reftest.list ---- firefox-92.0/dom/media/webvtt/test/reftest/reftest.list.firefox-tests-reftest 2021-09-01 19:14:41.000000000 +0200 -+++ firefox-92.0/dom/media/webvtt/test/reftest/reftest.list 2021-09-03 18:50:43.693907440 +0200 -@@ -1,2 +0,0 @@ --skip-if(Android) fuzzy-if((/^Windows\x20NT\x2010\.0/.test(http.oscpu))&&(/^aarch64-msvc/.test(xulRuntime.XPCOMABI)),0-136,0-427680) == vtt_update_display_after_removed_cue.html vtt_update_display_after_removed_cue_ref.html --skip-if(Android) fuzzy-if(winWidget,0-170,0-170) == vtt_overlapping_time.html vtt_overlapping_time-ref.html -diff -U0 firefox-92.0/gfx/layers/apz/test/reftest/reftest.list.firefox-tests-reftest firefox-92.0/gfx/layers/apz/test/reftest/reftest.list ---- firefox-92.0/gfx/layers/apz/test/reftest/reftest.list.firefox-tests-reftest 2021-09-01 19:14:41.000000000 +0200 -+++ firefox-92.0/gfx/layers/apz/test/reftest/reftest.list 2021-09-03 18:50:43.693907440 +0200 -@@ -6,6 +5,0 @@ --fuzzy-if(Android&&!swgl,0-1,0-2) fuzzy-if(Android&&swgl,3-3,4-4) fuzzy-if(webrender&>kWidget,1-8,8-32) fuzzy-if(webrender&&cocoaWidget,18-22,20-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v.html async-scrollbar-1-v-ref.html --fuzzy-if(Android&&!swgl,0-4,0-5) fuzzy-if(Android&&swgl,11-11,4-4) fuzzy-if(webrender&>kWidget,1-30,4-32) fuzzy-if(webrender&&cocoaWidget,18-22,20-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-h.html async-scrollbar-1-h-ref.html --fuzzy-if(Android&&!swgl,0-7,0-6) fuzzy-if(Android&&swgl,11-11,8-8) fuzzy-if(webrender&>kWidget,1-2,4-20) fuzzy-if(webrender&&cocoaWidget,14-18,48-88) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-vh.html async-scrollbar-1-vh-ref.html --fuzzy-if(Android&&!swgl,0-1,0-2) fuzzy-if(Android&&swgl,3-3,4-4) fuzzy-if(webrender&>kWidget,1-8,8-32) fuzzy-if(webrender&&cocoaWidget,18-22,20-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-v-rtl.html async-scrollbar-1-v-rtl-ref.html --fuzzy-if(Android,0-14,0-5) fuzzy-if(webrender&>kWidget,1-30,12-32) fuzzy-if(webrender&&cocoaWidget,18-22,20-44) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-h-rtl.html async-scrollbar-1-h-rtl-ref.html --fuzzy-if(Android,0-8,0-8) fuzzy-if(webrender&>kWidget,8-14,12-32) fuzzy-if(webrender&&cocoaWidget,14-18,26-54) skip-if(!asyncPan) pref(apz.allow_zooming,true) == async-scrollbar-1-vh-rtl.html async-scrollbar-1-vh-rtl-ref.html -@@ -21 +15 @@ --# On desktop, even more fuzz is needed because thumb scaling is not exactly proportional: making the page twice as long -+# On desktop, even more fuzz is needed because thumb scaling is not exactly proportional: making the page twice as long -diff -U0 firefox-92.0/image/test/reftest/downscaling/reftest.list.firefox-tests-reftest firefox-92.0/image/test/reftest/downscaling/reftest.list ---- firefox-92.0/image/test/reftest/downscaling/reftest.list.firefox-tests-reftest 2021-09-01 19:14:47.000000000 +0200 -+++ firefox-92.0/image/test/reftest/downscaling/reftest.list 2021-09-03 18:50:44.863939657 +0200 -@@ -91,0 +92,4 @@ -+fuzzy(0-17,0-3940) fuzzy-if(gtkWidget&&!webrender,4-4,2616-2616) fuzzy-if(gtkWidget&&!webrender&&!layersGPUAccelerated,0-0,0-0) fuzzy-if(gtkWidget&&webrender,0-0,0-0) skip-if(Android) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # gtkWidget Bug 1592059: regular is 2616, no-accel is 0, qr passes with 0 -+ -+# Skip on Android because it runs reftests via http, and moz-icon isn't -+# accessible from http/https origins anymore. -@@ -172,0 +177,5 @@ -+ -+# Skip on WinXP with skia content -+# Skip on Android because it runs reftests via http, and moz-icon isn't -+# accessible from http/https origins anymore. -+fuzzy(0-53,0-6391) fuzzy-if(appleSilicon,20-20,11605-11605) fuzzy-if(gtkWidget&&webrender,18-19,5502-5568) fails-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) skip-if(Android) == downscale-moz-icon-1.html downscale-moz-icon-1-ref.html # gtkWidget Bug 1592059 -diff -U0 firefox-92.0/layout/reftests/abs-pos/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/abs-pos/reftest.list ---- firefox-92.0/layout/reftests/abs-pos/reftest.list.firefox-tests-reftest 2021-09-01 19:15:00.000000000 +0200 -+++ firefox-92.0/layout/reftests/abs-pos/reftest.list 2021-09-03 18:50:44.863939657 +0200 -@@ -54 +54 @@ --fuzzy-if(gtkWidget,0-1,0-1) fuzzy-if(Android,0-9,0-185) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-140,0-144) == scrollframe-2.html scrollframe-2-ref.html #bug 756530 -+fuzzy-if(gtkWidget,0-100,0-160) fuzzy-if(Android,0-9,0-185) == scrollframe-2.html scrollframe-2-ref.html #bug 756530 -diff -U0 firefox-92.0/layout/reftests/async-scrolling/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/async-scrolling/reftest.list ---- firefox-92.0/layout/reftests/async-scrolling/reftest.list.firefox-tests-reftest 2021-09-01 19:15:01.000000000 +0200 -+++ firefox-92.0/layout/reftests/async-scrolling/reftest.list 2021-09-03 18:50:44.863939657 +0200 -@@ -27 +27 @@ --fuzzy-if(Android,0-8,0-4) fuzzy-if(webrender&>kWidget,20-33,14-32) fuzzy-if(webrender&&cocoaWidget,9-21,20-44) skip-if(!asyncPan) == position-fixed-transformed-1.html position-fixed-transformed-1-ref.html # Bug 1604338 -+fuzzy-if(Android,0-8,0-4) fuzzy-if(webrender&>kWidget,30-50,30-50) fuzzy-if(webrender&&cocoaWidget,21-21,44-44) skip-if(!asyncPan) == position-fixed-transformed-1.html position-fixed-transformed-1-ref.html # Bug 1604338 -@@ -52,2 +51,0 @@ --fuzzy-if(Android,0-6,0-4) fuzzy-if(skiaContent&&!Android,0-1,0-34) fuzzy-if(webrender&>kWidget,22-74,20-32) fuzzy-if(webrender&&cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-1.html offscreen-clipped-blendmode-ref.html # Bug 1604338 --fuzzy-if(Android,0-6,0-4) fuzzy-if(webrender&>kWidget,22-74,20-32) fuzzy-if(webrender&&cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-2.html offscreen-clipped-blendmode-ref.html # Bug 1604338 -@@ -55,2 +52,0 @@ --fuzzy-if(Android,0-6,0-4) fuzzy-if(webrender&>kWidget,22-74,20-32) fuzzy-if(webrender&&cocoaWidget,6-7,18-39) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-7,0-39) skip-if(!asyncPan) == offscreen-clipped-blendmode-4.html offscreen-clipped-blendmode-ref.html # Bug 1604338 --fuzzy-if(Android,0-7,0-1680) fuzzy-if(webrender&>kWidget,1-1,2-20) fuzzy-if(webrender&&cocoaWidget,1-2,10-18) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-2,0-18) skip-if(!asyncPan) == perspective-scrolling-1.html perspective-scrolling-1-ref.html # Bug 1604338 -@@ -58,2 +54,2 @@ --fuzzy-if(Android,0-19,0-4) fuzzy-if(webrender&>kWidget,8-13,12-32) fuzzy-if(webrender&&cocoaWidget,10-13,20-44) skip-if(!asyncPan) == perspective-scrolling-3.html perspective-scrolling-3-ref.html # Bug 1604338 --fuzzy-if(Android,0-7,0-4) fuzzy-if(webrender&>kWidget,18-30,14-32) fuzzy-if(webrender&&cocoaWidget,16-20,20-44) skip-if(!asyncPan) == perspective-scrolling-4.html perspective-scrolling-4-ref.html # Bug 1604338 -+fuzzy-if(Android,0-19,0-4) fuzzy-if(webrender&>kWidget,0-50,0-50) fuzzy-if(webrender&&cocoaWidget,13-13,44-44) skip-if(!asyncPan) == perspective-scrolling-3.html perspective-scrolling-3-ref.html # Bug 1604338 -+fuzzy-if(Android,0-7,0-4) fuzzy-if(webrender&>kWidget,0-50,0-50) fuzzy-if(webrender&&cocoaWidget,19-20,44-44) skip-if(!asyncPan) == perspective-scrolling-4.html perspective-scrolling-4-ref.html # Bug 1604338 -@@ -65,4 +60,0 @@ --fuzzy-if(Android,0-19,0-4) fuzzy-if(webrender&>kWidget,12-19,12-32) fuzzy-if(webrender&&cocoaWidget,17-21,20-44) skip-if(!asyncPan) == fixed-pos-scrolled-clip-1.html fixed-pos-scrolled-clip-1-ref.html # Bug 1604338 --fuzzy-if(Android,0-44,0-10) fuzzy-if(Android&&webrender&&swgl,0-44,0-126) fuzzy-if(webrender&>kWidget,16-26,26-64) fuzzy-if(webrender&&cocoaWidget,10-13,38-82) fuzzy-if(winWidget&&!nativeThemePref,0-4,0-36) skip-if(!asyncPan) == fixed-pos-scrolled-clip-2.html fixed-pos-scrolled-clip-2-ref.html # Bug 1604338 --fuzzy-if(Android,0-6,0-8) fuzzy-if(webrender&>kWidget,17-28,24-60) fuzzy-if(webrender&&cocoaWidget,15-19,40-75) skip-if(!asyncPan) == fixed-pos-scrolled-clip-3.html fixed-pos-scrolled-clip-3-ref.html # Bug 1604338 --fuzzy-if(Android,0-6,0-8) fuzzy-if(webrender&>kWidget,17-29,24-60) fuzzy-if(webrender&&cocoaWidget,15-19,40-75) skip-if(!asyncPan) == fixed-pos-scrolled-clip-4.html fixed-pos-scrolled-clip-4-ref.html # Bug 1604338 -@@ -71 +63 @@ --fuzzy-if(Android,0-8,0-4) fuzzy-if(webrender&>kWidget,16-25,12-32) fuzzy-if(webrender&&cocoaWidget,13-16,20-44) skip-if(!asyncPan) == position-sticky-scrolled-clip-1.html position-sticky-scrolled-clip-1-ref.html # Bug 1604338 -+fuzzy-if(Android,0-8,0-4) fuzzy-if(webrender&>kWidget,22-30,28-50) fuzzy-if(webrender&&cocoaWidget,16-16,44-44) skip-if(!asyncPan) == position-sticky-scrolled-clip-1.html position-sticky-scrolled-clip-1-ref.html # Bug 1604338 -@@ -73,6 +64,0 @@ --fuzzy-if(Android,0-8,0-27) fuzzy-if(webrender&&cocoaWidget,9-11,20-44) skip-if(!asyncPan) == curtain-effect-1.html curtain-effect-1-ref.html --fuzzy-if(Android,0-7,0-4) fuzzy-if(webrender&>kWidget,10-15,12-32) fuzzy-if(webrender&&cocoaWidget,5-9,20-42) skip-if(!asyncPan) == transformed-1.html transformed-1-ref.html # Bug 1604338 --fuzzy-if(Android&&!webrender,2-6,4-4) fuzzy-if(Android&&webrender,6-7,4-4) fuzzy-if(webrender&>kWidget,3-5,12-28) fuzzy-if(webrender&&cocoaWidget,5-6,18-38) skip-if(!asyncPan) fuzzy-if(swgl&&cocoaWidget&&isDebugBuild,0-6,0-38) == position-sticky-transformed-in-scrollframe-1.html position-sticky-transformed-in-scrollframe-1-ref.html # Bug 1604338 --fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,10-10,4-449) fuzzy-if(webrender&>kWidget,13-20,12-32) fuzzy-if(webrender&&cocoaWidget,12-16,20-44) skip-if(!asyncPan) == position-sticky-transformed-in-scrollframe-2.html position-sticky-transformed-in-scrollframe-2-ref.html # Bug 1604338 --fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,12-13,4-24) fuzzy-if(webrender&>kWidget,16-27,14-32) fuzzy-if(webrender&&cocoaWidget,13-16,20-44) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-1.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338 --fuzzy-if(Android&&!webrender,3-3,4-4) fuzzy-if(Android&&webrender,12-13,4-24) fuzzy-if(webrender&>kWidget,16-27,14-32) fuzzy-if(webrender&&cocoaWidget,13-16,20-44) skip-if(!asyncPan) == position-sticky-in-transformed-scrollframe-2.html position-sticky-in-transformed-scrollframe-ref.html # Bug 1604338 -diff -U0 firefox-92.0/layout/reftests/bidi/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/bidi/reftest.list ---- firefox-92.0/layout/reftests/bidi/reftest.list.firefox-tests-reftest 2021-09-01 19:15:00.000000000 +0200 -+++ firefox-92.0/layout/reftests/bidi/reftest.list 2021-09-03 18:50:44.863939657 +0200 -@@ -3 +3 @@ --fuzzy-if(cocoaWidget,0-1,0-1) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == bdi-element.html bdi-element-ref.html # Bug 1392106 -+fuzzy(0-1,0-1) fuzzy-if(cocoaWidget,0-1,0-1) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == bdi-element.html bdi-element-ref.html # Bug 1392106 -@@ -33,2 +33,2 @@ --fuzzy-if(Android,0-1,0-6) fuzzy-if(cocoaWidget,0-1,0-2) == mixedChartype-02.html mixedChartype-02-ref.html --fuzzy-if(Android,0-1,0-6) fuzzy-if(cocoaWidget,0-1,0-2) == mixedChartype-02-j.html mixedChartype-02-ref.html -+fuzzy-if(gtkWidget,0-1,0-3) fuzzy-if(Android,0-1,0-6) fuzzy-if(cocoaWidget,0-1,0-2) == mixedChartype-02.html mixedChartype-02-ref.html -+fuzzy-if(gtkWidget,0-1,0-3) fuzzy-if(Android,0-1,0-6) fuzzy-if(cocoaWidget,0-1,0-2) == mixedChartype-02-j.html mixedChartype-02-ref.html -@@ -163,8 +163,8 @@ --fuzzy-if(cocoaWidget,0-1,0-4) fuzzy-if(Android,0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2a-ltr.html brackets-2a-ltr-ref.html # Bug 1392106 --fuzzy-if(cocoaWidget,0-1,0-2) fuzzy-if(Android,0-254,0-557) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2a-rtl.html brackets-2a-rtl-ref.html # Bug 1392106 --fuzzy-if(cocoaWidget,0-1,0-6) fuzzy-if(Android,0-1,0-8) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2b-ltr.html brackets-2b-ltr-ref.html # Bug 1392106 --fuzzy-if(cocoaWidget,0-1,0-7) fuzzy-if(Android,0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2b-rtl.html brackets-2b-rtl-ref.html # Bug 1392106 --fuzzy-if(cocoaWidget,0-1,0-7) fuzzy-if(Android,0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2c-ltr.html brackets-2c-ltr-ref.html # Bug 1392106 --fuzzy-if(cocoaWidget,0-1,0-6) fuzzy-if(Android,0-254,0-231) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2c-rtl.html brackets-2c-rtl-ref.html # Bug 1392106 --fuzzy-if(cocoaWidget,0-1,0-6) fuzzy-if(Android,0-1,0-8) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-3a-ltr.html brackets-3a-ltr-ref.html # Bug 1392106 --fuzzy-if(cocoaWidget,0-1,0-3) fuzzy-if(Android,0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-3a-rtl.html brackets-3a-rtl-ref.html # Bug 1392106 -+fuzzy(0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2a-ltr.html brackets-2a-ltr-ref.html # Bug 1392106 -+fuzzy(0-64,0-140) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2a-rtl.html brackets-2a-rtl-ref.html # Bug 1392106 -+fuzzy(0-1,0-8) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2b-ltr.html brackets-2b-ltr-ref.html # Bug 1392106 -+fuzzy(0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2b-rtl.html brackets-2b-rtl-ref.html # Bug 1392106 -+fuzzy(0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2c-ltr.html brackets-2c-ltr-ref.html # Bug 1392106 -+fuzzy(0-254,0-231) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-2c-rtl.html brackets-2c-rtl-ref.html # Bug 1392106 -+fuzzy(0-1,0-8) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-3a-ltr.html brackets-3a-ltr-ref.html # Bug 1392106 -+fuzzy(0-1,0-6) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == brackets-3a-rtl.html brackets-3a-rtl-ref.html # Bug 1392106 -diff -U0 firefox-92.0/layout/reftests/border-radius/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/border-radius/reftest.list ---- firefox-92.0/layout/reftests/border-radius/reftest.list.firefox-tests-reftest 2021-09-01 19:15:01.000000000 +0200 -+++ firefox-92.0/layout/reftests/border-radius/reftest.list 2021-09-03 18:50:44.863939657 +0200 -@@ -54 +54 @@ --fuzzy-if(Android,0-8,0-469) fuzzy-if(skiaContent,0-21,0-76) fuzzy-if(winWidget,0-144,0-335) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical, bug 1392106 -+fuzzy-if(gtkWidget,0-80,0-300) fuzzy-if(Android,0-8,0-469) fuzzy-if(winWidget,0-144,0-335) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical, bug 1392106 -diff -U0 firefox-92.0/layout/reftests/bugs/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/bugs/reftest.list ---- firefox-92.0/layout/reftests/bugs/reftest.list.firefox-tests-reftest 2021-09-01 19:15:00.000000000 +0200 -+++ firefox-92.0/layout/reftests/bugs/reftest.list 2021-09-03 18:50:44.864939685 +0200 -@@ -464 +463,0 @@ --== 341043-1a.html 341043-1-ref.html -@@ -553 +552 @@ --== 363706-1.html 363706-1-ref.html -+fuzzy-if(gtkWidget,255-255,0-100) == 363706-1.html 363706-1-ref.html -@@ -672 +671 @@ --== 376532-1.html 376532-1-ref.html -+fuzzy-if(gtkWidget,0-150,0-50) == 376532-1.html 376532-1-ref.html -@@ -763 +762 @@ --== 389074-1.html 389074-1-ref.html -+fuzzy-if(gtkWidget,0-150,0-80) == 389074-1.html 389074-1-ref.html -@@ -926 +925 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 411059-1.html 411059-1-ref.html # Bug 1392106 -+fuzzy-if(gtkWidget,0-255,0-6312) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 411059-1.html 411059-1-ref.html # Bug 1392106 -@@ -1000 +999 @@ --== 422394-1.html 422394-1-ref.html -+fuzzy-if(gtkWidget,0-255,0-640) == 422394-1.html 422394-1-ref.html -@@ -1172 +1171 @@ --fails-if(Android||cocoaWidget||winWidget) == chrome://reftest/content/bugs/456147.xhtml 456147-ref.html # bug 458047 -+fuzzy-if(gtkWidget,0-255,0-5167) fails-if(Android||cocoaWidget||winWidget) == chrome://reftest/content/bugs/456147.xhtml 456147-ref.html # bug 458047 -@@ -1820 +1819 @@ --== 1062108-1.html 1062108-1-ref.html -+fuzzy-if(gtkWidget,0-255,0-53) == 1062108-1.html 1062108-1-ref.html -@@ -2022 +2020,0 @@ --!= 1404057.html 1404057-noref.html -@@ -2062,2 +2059,0 @@ --fuzzy-if(!webrender,1-5,66-547) fuzzy-if(geckoview&&!webrender,1-2,64-141) fuzzy-if(winWidget&&swgl,1-1,12-16) fuzzy-if(cocoaWidget&&swgl,1-1,32-32) fuzzy-if(useDrawSnapshot&&webrender,3-3,459-459) == 1529992-1.html 1529992-1-ref.html --fuzzy-if(!webrender,0-6,0-34) fuzzy-if(Android,9-14,44-60) fails-if(!useDrawSnapshot&&webrender) == 1529992-2.html 1529992-2-ref.html -@@ -2066 +2062 @@ --skip-if(!asyncPan) == 1544895.html 1544895-ref.html -+fuzzy-if(gtkWidget,0-252,0-24) skip-if(!asyncPan) == 1544895.html 1544895-ref.html -@@ -2079 +2075 @@ --fuzzy-if(winWidget&&webrender,0-31,0-3) fuzzy-if(geckoview&&webrender,0-93,0-87) == 1562733-rotated-nastaliq-2.html 1562733-rotated-nastaliq-2-ref.html -+fuzzy(0-30,0-2) fuzzy-if(winWidget&&webrender,0-31,0-3) fuzzy-if(geckoview&&webrender,0-93,0-87) == 1562733-rotated-nastaliq-2.html 1562733-rotated-nastaliq-2-ref.html -diff -U0 firefox-92.0/layout/reftests/canvas/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/canvas/reftest.list ---- firefox-92.0/layout/reftests/canvas/reftest.list.firefox-tests-reftest 2021-09-01 19:15:00.000000000 +0200 -+++ firefox-92.0/layout/reftests/canvas/reftest.list 2021-09-03 18:50:44.864939685 +0200 -@@ -51,2 +50,0 @@ --!= text-font-lang.html text-font-lang-notref.html -- -@@ -54 +52 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == text-small-caps-1.html text-small-caps-1-ref.html # Bug 1392106 -+fuzzy-if(gtkWidget,0-255,0-2304) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == text-small-caps-1.html text-small-caps-1-ref.html # Bug 1392106 -diff -U0 firefox-92.0/layout/reftests/css-break/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/css-break/reftest.list ---- firefox-92.0/layout/reftests/css-break/reftest.list.firefox-tests-reftest 2021-09-03 18:50:44.864939685 +0200 -+++ firefox-92.0/layout/reftests/css-break/reftest.list 2021-09-03 18:51:55.862894766 +0200 -@@ -1,3 +0,0 @@ --== box-decoration-break-1.html box-decoration-break-1-ref.html --fuzzy(0-1,0-20) fuzzy-if(skiaContent,0-1,0-700) == box-decoration-break-with-inset-box-shadow-1.html box-decoration-break-with-inset-box-shadow-1-ref.html --fuzzy(0-45,0-460) fuzzy-if(skiaContent,0-64,0-484) fuzzy-if(Android,0-70,0-1330) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == box-decoration-break-with-outset-box-shadow-1.html box-decoration-break-with-outset-box-shadow-1-ref.html # Bug 1386543, bug 1392106 -diff -U0 firefox-92.0/layout/reftests/css-placeholder/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/css-placeholder/reftest.list ---- firefox-92.0/layout/reftests/css-placeholder/reftest.list.firefox-tests-reftest 2021-09-01 19:15:00.000000000 +0200 -+++ firefox-92.0/layout/reftests/css-placeholder/reftest.list 2021-09-03 18:50:44.864939685 +0200 -@@ -5 +5 @@ --fuzzy-if(gtkWidget&&nativeThemePref,255-255,1376-1881) == css-simple-styling.html css-simple-styling-ref.html # gtkWidget, Bug 1600749 -+fuzzy-if(gtkWidget&&nativeThemePref,255-255,1300-1881) == css-simple-styling.html css-simple-styling-ref.html # gtkWidget, Bug 1600749 -diff -U0 firefox-92.0/layout/reftests/css-ruby/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/css-ruby/reftest.list ---- firefox-92.0/layout/reftests/css-ruby/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/css-ruby/reftest.list 2021-09-03 18:50:44.865939713 +0200 -@@ -17,4 +17,4 @@ --== relative-positioning-2.html relative-positioning-2-ref.html --== ruby-position-horizontal.html ruby-position-horizontal-ref.html --== ruby-position-vertical-lr.html ruby-position-vertical-lr-ref.html --== ruby-position-vertical-rl.html ruby-position-vertical-rl-ref.html -+fuzzy-if(gtkWidget,0-255,0-669) == relative-positioning-2.html relative-positioning-2-ref.html -+fuzzy-if(gtkWidget,0-255,0-947) == ruby-position-horizontal.html ruby-position-horizontal-ref.html -+fuzzy-if(gtkWidget,0-255,0-1079) == ruby-position-vertical-lr.html ruby-position-vertical-lr-ref.html -+fuzzy-if(gtkWidget,0-255,0-1079) == ruby-position-vertical-rl.html ruby-position-vertical-rl-ref.html -@@ -26 +26 @@ --pref(layout.css.ruby.intercharacter.enabled,true) fuzzy-if(Android,0-198,0-70) == ruby-intercharacter-1.htm ruby-intercharacter-1-ref.htm -+fuzzy-if(gtkWidget,0-240,0-61) pref(layout.css.ruby.intercharacter.enabled,true) fuzzy-if(Android,0-198,0-70) == ruby-intercharacter-1.htm ruby-intercharacter-1-ref.htm -@@ -28 +28 @@ --pref(layout.css.ruby.intercharacter.enabled,true) == ruby-intercharacter-2.htm ruby-intercharacter-2-ref.htm -+fuzzy-if(gtkWidget,0-255,0-219) pref(layout.css.ruby.intercharacter.enabled,true) == ruby-intercharacter-2.htm ruby-intercharacter-2-ref.htm -diff -U0 firefox-92.0/layout/reftests/first-letter/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/first-letter/reftest.list ---- firefox-92.0/layout/reftests/first-letter/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/first-letter/reftest.list 2021-09-03 18:50:44.865939713 +0200 -@@ -64 +64 @@ --fails-if(winWidget||cocoaWidget) fails-if(geckoview) == 617869-1.html 617869-1-ref.html # Bug 1558513 for GV -+fuzzy-if(gtkWidget,0-260,0-900) fails-if(winWidget||cocoaWidget) fails-if(geckoview) == 617869-1.html 617869-1-ref.html # Bug 1558513 for GV -diff -U0 firefox-92.0/layout/reftests/font-face/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/font-face/reftest.list ---- firefox-92.0/layout/reftests/font-face/reftest.list.firefox-tests-reftest 2021-09-01 19:15:01.000000000 +0200 -+++ firefox-92.0/layout/reftests/font-face/reftest.list 2021-09-03 18:50:44.865939713 +0200 -@@ -9 +9 @@ --== name-override-simple-1.html name-override-simple-1-ref.html -+fuzzy-if(gtkWidget,0-112,0-107) == name-override-simple-1.html name-override-simple-1-ref.html -@@ -26,3 +26,2 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(Android) == src-list-local-full.html src-list-local-full-ref.html # Bug 1392106 --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(Android) == src-list-local-full-quotes.html src-list-local-full-ref.html # Bug 1392106 --== src-list-local-fallback.html src-list-local-fallback-ref.html -+fuzzy(0-255,0-6200) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(Android) == src-list-local-full.html src-list-local-full-ref.html # Bug 1392106 -+fuzzy(0-255,0-6200) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fails-if(Android) == src-list-local-full-quotes.html src-list-local-full-ref.html # Bug 1392106 -@@ -57 +56 @@ --== cross-iframe-1.html cross-iframe-1-ref.html -+fuzzy-if(gtkWidget,0-112,0-107) == cross-iframe-1.html cross-iframe-1-ref.html -@@ -81 +80 @@ --== sheet-set-switch-1.html sheet-set-switch-1-ref.html -+fuzzy-if(gtkWidget,0-112,0-108) random-if(cocoaWidget) == sheet-set-switch-1.html sheet-set-switch-1-ref.html # bug 468217 -@@ -93 +92 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == local-1.html local-1-ref.html # Bug 1392106 -+fuzzy-if(gtkWidget,0-255,0-7000) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == local-1.html local-1-ref.html # Bug 1392106 -@@ -171,2 +170,2 @@ --HTTP(..) == reflow-sanity-1.html reflow-sanity-1-ref.html --HTTP(..) == reflow-sanity-1-data.html reflow-sanity-1-ref.html -+fuzzy-if(gtkWidget,0-104,0-406) HTTP(..) == reflow-sanity-1.html reflow-sanity-1-ref.html -+fuzzy-if(gtkWidget,0-104,0-406) HTTP(..) == reflow-sanity-1-data.html reflow-sanity-1-ref.html -@@ -174,4 +173,4 @@ --HTTP(..) == reflow-sanity-delay-1a.html reflow-sanity-1-ref.html --HTTP(..) == reflow-sanity-delay-1b.html reflow-sanity-1-ref.html --HTTP(..) == reflow-sanity-delay-1c.html reflow-sanity-1-ref.html --HTTP(..) == reflow-sanity-delay-1-metrics.html reflow-sanity-1-ref.html -+fuzzy-if(gtkWidget,0-104,0-406) HTTP(..) == reflow-sanity-delay-1a.html reflow-sanity-1-ref.html -+fuzzy-if(gtkWidget,0-104,0-406) HTTP(..) == reflow-sanity-delay-1b.html reflow-sanity-1-ref.html -+fuzzy-if(gtkWidget,0-104,0-406) HTTP(..) == reflow-sanity-delay-1c.html reflow-sanity-1-ref.html -+fuzzy-if(gtkWidget,0-104,0-406) HTTP(..) == reflow-sanity-delay-1-metrics.html reflow-sanity-1-ref.html -@@ -204 +203 @@ --# Currently Windows 7 and macOS all fail on -+# Currently Windows 7 and macOS all fail on -diff -U0 firefox-92.0/layout/reftests/font-matching/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/font-matching/reftest.list ---- firefox-92.0/layout/reftests/font-matching/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/font-matching/reftest.list 2021-09-03 18:50:44.865939713 +0200 -@@ -124 +124 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-2.html italic-oblique-ref.html # Bug 1392106 -+fuzzy-if(gtkWidget,0-104,0-1836) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-2.html italic-oblique-ref.html # Bug 1392106 -@@ -128 +128 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-6.html italic-oblique-ref.html # Bug 1392106 -+fuzzy-if(gtkWidget,0-104,0-1836) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-6.html italic-oblique-ref.html # Bug 1392106 -@@ -130,2 +130,2 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-8.html italic-oblique-ref.html # Bug 1392106 --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-9.html italic-oblique-ref.html # Bug 1392106 -+fuzzy-if(gtkWidget,0-104,0-1836) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-8.html italic-oblique-ref.html # Bug 1392106 -+fuzzy-if(gtkWidget,0-104,0-1836) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == italic-oblique-9.html italic-oblique-ref.html # Bug 1392106 -diff -U0 firefox-92.0/layout/reftests/forms/fieldset/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/forms/fieldset/reftest.list ---- firefox-92.0/layout/reftests/forms/fieldset/reftest.list.firefox-tests-reftest 2021-09-01 19:15:01.000000000 +0200 -+++ firefox-92.0/layout/reftests/forms/fieldset/reftest.list 2021-09-03 18:50:44.865939713 +0200 -@@ -8 +7,0 @@ --fuzzy-if(!layersGPUAccelerated,0-142,0-276) == positioned-container-1.html positioned-container-1-ref.html -diff -U0 firefox-92.0/layout/reftests/forms/input/checkbox/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/forms/input/checkbox/reftest.list ---- firefox-92.0/layout/reftests/forms/input/checkbox/reftest.list.firefox-tests-reftest 2021-09-01 19:15:01.000000000 +0200 -+++ firefox-92.0/layout/reftests/forms/input/checkbox/reftest.list 2021-09-03 18:50:44.865939713 +0200 -@@ -18 +18 @@ --skip-if((OSX||winWidget)&&nativeThemePref) fuzzy-if(gtkWidget&&nativeThemePref,25-25,32-32) fails-if(Android&&nativeThemePref) == checkbox-clamp-02.html checkbox-clamp-02-ref.html -+skip-if(OSX||winWidget) fails-if(geckoview&&webrender) fuzzy-if(gtkWidget&&nativeThemePref,12-25,25-32) fails-if(Android) == checkbox-clamp-02.html checkbox-clamp-02-ref.html -diff -U0 firefox-92.0/layout/reftests/forms/input/radio/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/forms/input/radio/reftest.list ---- firefox-92.0/layout/reftests/forms/input/radio/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/forms/input/radio/reftest.list 2021-09-03 18:50:44.865939713 +0200 -@@ -9 +9 @@ --skip-if(OSX||winWidget||Android) fuzzy-if(gtkWidget&&nativeThemePref,24-24,16-16) == radio-clamp-02.html radio-clamp-02-ref.html # gtkWidget, Bug 1599622 -+skip-if(OSX||winWidget||Android) fuzzy-if(gtkWidget&&nativeThemePref,10-24,16-16) == radio-clamp-02.html radio-clamp-02-ref.html # gtkWidget, Bug 1599622 -diff -U0 firefox-92.0/layout/reftests/forms/placeholder/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/forms/placeholder/reftest.list ---- firefox-92.0/layout/reftests/forms/placeholder/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/forms/placeholder/reftest.list 2021-09-03 18:50:44.866939741 +0200 -@@ -21 +21 @@ --fuzzy-if(winWidget,0-160,0-10) fuzzy-if(Android,0-160,0-41) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-146,0-317) fuzzy-if(OSX==1010&&browserIsRemote,0-1,0-8) == placeholder-6.html placeholder-overflow-ref.html -+fuzzy-if(gtkWidget,0-255,0-341) fuzzy-if(winWidget,0-160,0-10) fuzzy-if(Android,0-160,0-41) fuzzy-if(OSX==1010&&browserIsRemote,0-1,0-8) == placeholder-6.html placeholder-overflow-ref.html -diff -U0 firefox-92.0/layout/reftests/forms/textbox/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/forms/textbox/reftest.list ---- firefox-92.0/layout/reftests/forms/textbox/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/forms/textbox/reftest.list 2021-09-03 18:50:44.866939741 +0200 -@@ -4 +3,0 @@ --fuzzy-if(winWidget,0-1,0-3) skip-if(cocoaWidget||Android) fails-if(!useDrawSnapshot&&webrender) == chrome://reftest/content/forms/textbox/accesskey-2.xhtml chrome://reftest/content/forms/textbox/accesskey-2-ref.xhtml -@@ -8 +6,0 @@ --fuzzy-if(winWidget,0-1,0-3) skip-if(cocoaWidget||Android) fails-if(!useDrawSnapshot&&webrender&&!Android) == chrome://reftest/content/forms/textbox/accesskey-4.xhtml chrome://reftest/content/forms/textbox/accesskey-4-ref.xhtml -diff -U0 firefox-92.0/layout/reftests/generated-content/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/generated-content/reftest.list ---- firefox-92.0/layout/reftests/generated-content/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/generated-content/reftest.list 2021-09-03 18:50:44.866939741 +0200 -@@ -16 +16 @@ --fuzzy-if(OSX==1010,0-1,0-10) == quotes-001.xml quotes-001-ref.xml -+fuzzy(0-128,0-737) fuzzy-if(OSX==1010,0-1,0-10) == quotes-001.xml quotes-001-ref.xml -diff -U0 firefox-92.0/layout/reftests/high-contrast/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/high-contrast/reftest.list ---- firefox-92.0/layout/reftests/high-contrast/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/high-contrast/reftest.list 2021-09-03 18:50:44.866939741 +0200 -@@ -22 +22 @@ --fuzzy-if(cocoaWidget,255-255,1495-1495) fuzzy-if(winWidget,255-255,353-353) fuzzy-if(Android,255-255,700-700) == backplate-bg-image-010.html backplate-bg-image-010-ref.html -+fuzzy-if(gtkWidget,0-255,0-1495) fuzzy-if(cocoaWidget,255-255,1495-1495) fuzzy-if(winWidget,255-255,353-353) fuzzy-if(Android,255-255,700-700) == backplate-bg-image-010.html backplate-bg-image-010-ref.html -diff -U0 firefox-92.0/layout/reftests/indic-shaping/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/indic-shaping/reftest.list ---- firefox-92.0/layout/reftests/indic-shaping/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/indic-shaping/reftest.list 2021-09-03 18:50:44.866939741 +0200 -@@ -12 +11,0 @@ --fuzzy-if(gtkWidget,255-255,46-46) == gujarati-3b.html gujarati-3-ref.html # gtkWidget, Bug 1600777 -diff -U0 firefox-92.0/layout/reftests/mathml/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/mathml/reftest.list ---- firefox-92.0/layout/reftests/mathml/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/mathml/reftest.list 2021-09-03 18:50:44.866939741 +0200 -@@ -26 +26 @@ --random-if(smallScreen&&Android) fuzzy(0-255,0-200) fuzzy-if(geckoview&&webrender,201-216,200-250) fuzzy-if(webrender&&winWidget,114-255,245-361) fuzzy-if(webrender&&OSX,79-153,240-250) == mirror-op-1.html mirror-op-1-ref.html -+random-if(smallScreen&&Android) fuzzy(0-255,0-350) fuzzy-if(geckoview&&webrender,201-216,312-316) fuzzy-if(webrender&&winWidget,114-255,245-361) fuzzy-if(webrender&&OSX,79-153,307-314) == mirror-op-1.html mirror-op-1-ref.html -@@ -66 +66 @@ --== stretchy-largeop-2.html stretchy-largeop-2-ref.html -+fuzzy-if(gtkWidget,0-255,0-126) == stretchy-largeop-2.html stretchy-largeop-2-ref.html -@@ -177 +176,0 @@ --fuzzy-if(skiaContent,0-1,0-80) fuzzy-if(Android,0-255,0-105) fuzzy-if(gtkWidget,255-255,96-96) skip-if(winWidget) == multiscripts-1.html multiscripts-1-ref.html # Windows: bug 1314684; Android: bug 1392254; Linux: bug 1599638 -@@ -256 +254,0 @@ --fails-if(winWidget) fuzzy-if(gtkWidget,255-255,776226-776226) == subscript-italic-correction.html subscript-italic-correction-ref.html # bug 961482 (Windows), bug 1599640 (Linux) -diff -U0 firefox-92.0/layout/reftests/position-dynamic-changes/relative/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/position-dynamic-changes/relative/reftest.list ---- firefox-92.0/layout/reftests/position-dynamic-changes/relative/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/position-dynamic-changes/relative/reftest.list 2021-09-03 18:50:44.866939741 +0200 -@@ -1,4 +1,4 @@ --fuzzy-if(cocoaWidget,0-1,0-2) fuzzy-if(d2d,0-47,0-26) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-169,0-970) == move-right-bottom.html move-right-bottom-ref.html --fuzzy-if(cocoaWidget,0-1,0-2) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-169,0-970) == move-top-left.html move-top-left-ref.html # Bug 688545 --fuzzy-if(cocoaWidget,0-1,0-3) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-144,0-580) == move-right-bottom-table.html move-right-bottom-table-ref.html --fuzzy-if(cocoaWidget,0-1,0-3) fuzzy-if(asyncPan&&!layersGPUAccelerated,0-144,0-580) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545 -+fuzzy-if(gtkWidget,0-99,0-1255) fuzzy-if(cocoaWidget,0-1,0-2) == move-right-bottom.html move-right-bottom-ref.html -+fuzzy-if(gtkWidget,0-99,0-1254) fuzzy-if(cocoaWidget,0-1,0-2) == move-top-left.html move-top-left-ref.html # Bug 688545 -+fuzzy-if(gtkWidget,0-103,0-637) fuzzy-if(cocoaWidget,0-1,0-3) == move-right-bottom-table.html move-right-bottom-table-ref.html -+fuzzy-if(gtkWidget,0-103,0-637) fuzzy-if(cocoaWidget,0-1,0-3) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545 -diff -U0 firefox-92.0/layout/reftests/position-sticky/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/position-sticky/reftest.list ---- firefox-92.0/layout/reftests/position-sticky/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/position-sticky/reftest.list 2021-09-03 18:50:44.866939741 +0200 -@@ -53,3 +52,0 @@ --fuzzy-if(Android,0-5,0-4) fuzzy-if(webrender&>kWidget,10-17,12-32) fuzzy-if(webrender&&cocoaWidget,7-8,18-42) skip-if(!asyncPan) fails-if(useDrawSnapshot) == transformed-2.html transformed-2-ref.html # Bug 1604644 --skip-if(!asyncPan) fuzzy-if(Android,0-10,0-4) fuzzy-if(webrender&>kWidget,19-30,12-32) fuzzy-if(webrender&&cocoaWidget,13-16,20-44) fails-if(useDrawSnapshot) == nested-sticky-1.html nested-sticky-1-ref.html # Bug 1604644 --skip-if(!asyncPan) fuzzy-if(Android,0-10,0-4) fuzzy-if(webrender&>kWidget,19-30,12-32) fuzzy-if(webrender&&cocoaWidget,13-16,20-44) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),0-4,0-104) fails-if(useDrawSnapshot) == nested-sticky-2.html nested-sticky-2-ref.html # Bug 1604644 -diff -U0 firefox-92.0/layout/reftests/reftest-sanity/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/reftest-sanity/reftest.list ---- firefox-92.0/layout/reftests/reftest-sanity/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/reftest-sanity/reftest.list 2021-09-03 18:50:44.867939768 +0200 -@@ -131,6 +131,6 @@ --pref(font.default.x-western,"serif") == font-serif.html font-default.html --pref(font.default.x-western,"serif") != font-sans-serif.html font-default.html --pref(font.default.x-western,"sans-serif") == font-sans-serif.html font-default.html --pref(font.default.x-western,"sans-serif") != font-serif.html font-default.html --fails pref(font.default.x-western,true) == font-serif.html font-default.html --fails pref(font.default.x-western,0) == font-serif.html font-default.html -+#pref(font.default.x-western,"serif") == font-serif.html font-default.html -+#pref(font.default.x-western,"serif") != font-sans-serif.html font-default.html -+#pref(font.default.x-western,"sans-serif") == font-sans-serif.html font-default.html -+#pref(font.default.x-western,"sans-serif") != font-serif.html font-default.html -+#fails pref(font.default.x-western,true) == font-serif.html font-default.html -+#fails pref(font.default.x-western,0) == font-serif.html font-default.html -diff -U0 firefox-92.0/layout/reftests/svg/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/svg/reftest.list ---- firefox-92.0/layout/reftests/svg/reftest.list.firefox-tests-reftest 2021-09-01 19:15:00.000000000 +0200 -+++ firefox-92.0/layout/reftests/svg/reftest.list 2021-09-03 18:50:44.867939768 +0200 -@@ -475 +475 @@ --random-if(winWidget) fuzzy-if(Android,0-10,0-2) == text-gradient-02.svg text-gradient-02-ref.svg # see bug 590101 -+random-if(winWidget) fuzzy-if(gtkWidget,0-20,0-10) fuzzy-if(Android,0-10,0-2) == text-gradient-02.svg text-gradient-02-ref.svg # see bug 590101 -@@ -482 +481,0 @@ --!= text-language-00.xhtml text-language-00-ref.xhtml -@@ -484 +483 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == text-layout-01.svg text-layout-01-ref.svg # Bug 1392106 -+fuzzy-if(gtkWidget,0-255,0-1769) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == text-layout-01.svg text-layout-01-ref.svg # Bug 1392106 -@@ -492 +491 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == text-layout-09.svg pass.svg # Bug 1392106 -+fuzzy(0-255,0-237) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == text-layout-09.svg pass.svg # Bug 1392106 -diff -U0 firefox-92.0/layout/reftests/svg/smil/style/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/svg/smil/style/reftest.list ---- firefox-92.0/layout/reftests/svg/smil/style/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/svg/smil/style/reftest.list 2021-09-03 18:50:44.867939768 +0200 -@@ -70 +70 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) fuzzy-if(gtkWidget,255-255,1520-1520) == anim-css-font-1.svg anim-css-font-1-ref.svg # Windows: Bug 1392106 Linux: Bug 1599619 -+random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == anim-css-font-1.svg anim-css-font-1-ref.svg # Windows: Bug 1392106 Linux: Bug 1599619 -diff -U0 firefox-92.0/layout/reftests/svg/svg-integration/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/svg/svg-integration/reftest.list ---- firefox-92.0/layout/reftests/svg/svg-integration/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/svg/svg-integration/reftest.list 2021-09-03 18:50:44.867939768 +0200 -@@ -50 +50 @@ --fuzzy-if(Android,0-4,0-10) == box-decoration-break-01.xhtml box-decoration-break-01-ref.xhtml -+fuzzy-if(gtkWidget,0-5,0-11) fuzzy-if(Android,0-4,0-10) == box-decoration-break-01.xhtml box-decoration-break-01-ref.xhtml -@@ -52 +52 @@ --fuzzy(0-67,0-238) == box-decoration-break-03.xhtml box-decoration-break-01-ref.xhtml -+fuzzy(0-67,0-254) == box-decoration-break-03.xhtml box-decoration-break-01-ref.xhtml -diff -U0 firefox-92.0/layout/reftests/svg/text/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/svg/text/reftest.list ---- firefox-92.0/layout/reftests/svg/text/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/svg/text/reftest.list 2021-09-03 18:50:44.867939768 +0200 -@@ -203,2 +202,0 @@ --fuzzy-if(skiaContent,0-1,0-100) needs-focus fuzzy-if(webrender&&winWidget,55-148,200-318) == simple-bidi-selection.svg simple-bidi-selection-ref.html --fuzzy-if(skiaContent,0-1,0-50) needs-focus fuzzy-if(webrender&&winWidget,55-148,200-254) fuzzy-if(webrender&&OSX,1-65,19-196) == simple-fill-color-selection.svg simple-fill-color-selection-ref.html -diff -U0 firefox-92.0/layout/reftests/tab-size/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/tab-size/reftest.list ---- firefox-92.0/layout/reftests/tab-size/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/tab-size/reftest.list 2021-09-03 18:50:44.867939768 +0200 -@@ -2,6 +2,6 @@ --== tab-size-8.html spaces-8.html --== tab-size-4.html spaces-4.html --== tab-size-4-span.html spaces-4.html --== tab-size-4-spanoffset.html spaces-4-offset.html --== tab-size-4-multiple.html spaces-4-multiple.html --== tab-size-1.html spaces-1.html -+fuzzy-if(gtkWidget,0-255,0-70) == tab-size-8.html spaces-8.html -+fuzzy-if(gtkWidget,0-255,0-70) == tab-size-4.html spaces-4.html -+fuzzy-if(gtkWidget,0-255,0-70) == tab-size-4-span.html spaces-4.html -+fuzzy-if(gtkWidget,0-255,0-371) == tab-size-4-spanoffset.html spaces-4-offset.html -+fuzzy-if(gtkWidget,0-255,0-410) == tab-size-4-multiple.html spaces-4-multiple.html -+fuzzy-if(gtkWidget,0-255,0-63) == tab-size-1.html spaces-1.html -diff -U0 firefox-92.0/layout/reftests/text-decoration/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/text-decoration/reftest.list ---- firefox-92.0/layout/reftests/text-decoration/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/text-decoration/reftest.list 2021-09-03 18:50:44.867939768 +0200 -@@ -1,2 +1,2 @@ --fuzzy-if(webrender&>kWidget,0-208,0-12) == complex-decoration-style-quirks.html complex-decoration-style-quirks-ref.html --fuzzy-if(webrender&>kWidget,0-208,0-12) == complex-decoration-style-standards.html complex-decoration-style-standards-ref.html -+fuzzy-if(gtkWidget,0-255,0-40) == complex-decoration-style-quirks.html complex-decoration-style-quirks-ref.html -+fuzzy-if(gtkWidget,0-255,0-40) == complex-decoration-style-standards.html complex-decoration-style-standards-ref.html -diff -U0 firefox-92.0/layout/reftests/text-overflow/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/text-overflow/reftest.list ---- firefox-92.0/layout/reftests/text-overflow/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/text-overflow/reftest.list 2021-09-03 18:50:44.868939795 +0200 -@@ -6 +6 @@ --skip-if(!gtkWidget) fuzzy-if(gtkWidget,0-124,0-289) == bidi-simple-scrolled.html bidi-simple-scrolled-ref.html # Fails on Windows and OSX due to anti-aliasing -+skip-if(!gtkWidget) fuzzy-if(gtkWidget,0-255,0-400) == bidi-simple-scrolled.html bidi-simple-scrolled-ref.html # Fails on Windows and OSX due to anti-aliasing -@@ -28 +28 @@ --== float-edges-1.html float-edges-1-ref.html -+fuzzy-if(gtkWidget,0-255,0-294) == float-edges-1.html float-edges-1-ref.html -diff -U0 firefox-92.0/layout/reftests/text/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/text/reftest.list ---- firefox-92.0/layout/reftests/text/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/text/reftest.list 2021-09-03 18:50:44.868939795 +0200 -@@ -190 +190 @@ --fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9 -+fuzzy-if(gtkWidget,0-255,0-1071) fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1320665-cmap-format-13.html 1320665-cmap-format-13-ref.html # see bug 1320665 comments 8-9 -@@ -193,2 +193,2 @@ --fuzzy-if(Android,0-128,0-233) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html --fails-if(Android) == 1463020-letter-spacing-text-transform-2.html 1463020-letter-spacing-text-transform-2-ref.html # missing font coverage on Android -+fuzzy-if(gtkWidget,0-255,0-800) fails-if(/^^Windows\x20NT\x2010\.0/.test(http.oscpu)) fuzzy-if(Android,0-128,0-233) == 1463020-letter-spacing-text-transform-1.html 1463020-letter-spacing-text-transform-1-ref.html -+fuzzy-if(gtkWidget,0-255,0-1600) fails-if(Android) == 1463020-letter-spacing-text-transform-2.html 1463020-letter-spacing-text-transform-2-ref.html # missing font coverage on Android -@@ -198 +197,0 @@ --fuzzy-if(useDrawSnapshot&&webrender,255-255,50-50) fuzzy-if(!webrender,0-42,0-1590) fuzzy-if(gtkWidget&&!webrender,0-255,0-50) == 1655364-1.html 1655364-1-ref.html -@@ -366 +365 @@ --== color-opacity-rtl-1.html color-opacity-rtl-1-ref.html -+fuzzy-if(gtkWidget,0-5,0-5) == color-opacity-rtl-1.html color-opacity-rtl-1-ref.html -diff -U0 firefox-92.0/layout/reftests/text-transform/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/text-transform/reftest.list ---- firefox-92.0/layout/reftests/text-transform/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/text-transform/reftest.list 2021-09-03 18:50:44.868939795 +0200 -@@ -15 +15 @@ --random-if(winWidget) == small-caps-1.html small-caps-1-ref.html # fails if default font supports 'smcp' -+fuzzy-if(gtkWidget,0-255,0-571) random-if(winWidget) == small-caps-1.html small-caps-1-ref.html # fails if default font supports 'smcp' -diff -U0 firefox-92.0/layout/reftests/transform-3d/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/transform-3d/reftest.list ---- firefox-92.0/layout/reftests/transform-3d/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/transform-3d/reftest.list 2021-09-03 18:50:44.868939795 +0200 -@@ -14 +13,0 @@ --fuzzy-if(gtkWidget||winWidget,0-8,0-376) fuzzy-if(Android,0-8,0-441) fuzzy-if(skiaContent,0-16,0-346) fuzzy-if(webrender&&cocoaWidget,0-200,0-310) fuzzy-if(webrender&&winWidget,0-175,0-250) == preserve3d-1a.html preserve3d-1-ref.html -@@ -27,2 +26,2 @@ --fuzzy-if(winWidget,0-143,0-689) fuzzy-if(OSX,0-224,0-924) fuzzy-if(winWidget,0-154,0-644) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == scale3d-all.html scale3d-1-ref.html # subpixel AA --fuzzy-if(winWidget,0-143,0-689) fuzzy-if(OSX,0-224,0-924) fuzzy-if(winWidget,0-154,0-644) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA -+fuzzy-if(gtkWidget,0-100,0-628) fuzzy-if(winWidget,0-143,0-689) fuzzy-if(OSX,0-224,0-924) fuzzy-if(winWidget,0-154,0-644) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == scale3d-all.html scale3d-1-ref.html # subpixel AA -+fuzzy-if(gtkWidget,0-100,0-628) fuzzy-if(winWidget,0-143,0-689) fuzzy-if(OSX,0-224,0-924) fuzzy-if(winWidget,0-154,0-644) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == scale3d-all-separate.html scale3d-1-ref.html # subpixel AA -@@ -75,2 +74,2 @@ --fuzzy-if(skiaContent,0-1,0-4) fuzzy-if(cocoaWidget,0-128,0-9) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == animate-preserve3d-parent.html animate-preserve3d-ref.html # intermittently fuzzy on Mac --fuzzy-if(skiaContent,0-1,0-4) fuzzy-if(cocoaWidget,0-128,0-9) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == animate-preserve3d-child.html animate-preserve3d-ref.html # intermittently fuzzy on Mac, bug 1461311 for Android -+fuzzy(0-1,0-9) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == animate-preserve3d-parent.html animate-preserve3d-ref.html # intermittently fuzzy on Mac -+fuzzy(0-1,0-6) fuzzy-if(cocoaWidget,0-128,0-9) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == animate-preserve3d-child.html animate-preserve3d-ref.html # intermittently fuzzy on Mac, bug 1461311 for Android -@@ -102 +100,0 @@ --fuzzy-if(webrender,0-6,0-3117) fuzzy-if(useDrawSnapshot,4-4,13-13) == 1637067-1.html 1637067-1-ref.html -diff -U0 firefox-92.0/layout/reftests/writing-mode/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/writing-mode/reftest.list ---- firefox-92.0/layout/reftests/writing-mode/reftest.list.firefox-tests-reftest 2021-09-01 19:15:01.000000000 +0200 -+++ firefox-92.0/layout/reftests/writing-mode/reftest.list 2021-09-03 18:50:44.868939795 +0200 -@@ -20 +20 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1091058-1.html 1091058-1-ref.html # Bug 1392106 -+fuzzy(0-255,0-315) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1091058-1.html 1091058-1-ref.html # Bug 1392106 -@@ -34 +34 @@ --fuzzy-if(Android,0-128,0-94) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1111944-1-list-marker.html 1111944-1-list-marker-ref.html # Bug 1392106 -+fuzzy-if(gtkWidget,0-72,0-47) fuzzy-if(Android,0-128,0-94) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == 1111944-1-list-marker.html 1111944-1-list-marker-ref.html # Bug 1392106 -@@ -114 +114 @@ --fails-if(geckoview) == 1135361-ruby-justify-1.html 1135361-ruby-justify-1-ref.html # Bug 1558513 for GV -+fuzzy-if(gtkWidget,0-255,0-2323) fails-if(geckoview) == 1135361-ruby-justify-1.html 1135361-ruby-justify-1-ref.html # Bug 1558513 for GV -@@ -154 +154 @@ --fuzzy-if(winWidget,0-3,0-84) == 1193519-sideways-lr-3.html 1193519-sideways-lr-3-ref.html -+fuzzy(0-255,0-610) fuzzy-if(winWidget,0-3,0-84) fails-if(webrender&&winWidget&&!swgl) == 1193519-sideways-lr-3.html 1193519-sideways-lr-3-ref.html -@@ -185 +185 @@ --== 1395926-vertical-upright-gpos-1.html 1395926-vertical-upright-gpos-1-ref.html -+fuzzy-if(gtkWidget,0-248,0-8) == 1395926-vertical-upright-gpos-1.html 1395926-vertical-upright-gpos-1-ref.html -diff -U0 firefox-92.0/layout/reftests/writing-mode/tables/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/writing-mode/tables/reftest.list ---- firefox-92.0/layout/reftests/writing-mode/tables/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/writing-mode/tables/reftest.list 2021-09-03 18:50:44.868939795 +0200 -@@ -34 +34 @@ --== fixed-table-layout-027-vlr.html fixed-table-layout-025-ref.html -+fuzzy-if(gtkWidget,0-260,0-250) == fixed-table-layout-027-vlr.html fixed-table-layout-025-ref.html -@@ -60 +60 @@ --== fixed-table-layout-027-vrl.html fixed-table-layout-025-ref.html -+fuzzy-if(gtkWidget,0-260,0-250) == fixed-table-layout-027-vrl.html fixed-table-layout-025-ref.html -@@ -77,2 +76,0 @@ --fuzzy-if(Android,0-255,0-38) == table-caption-top-1.html table-caption-top-1-ref.html --fuzzy-if(Android,0-255,0-38) pref(layout.css.caption-side-non-standard.enabled,true) == table-caption-bottom-1.html table-caption-bottom-1-ref.html -diff -U0 firefox-92.0/layout/reftests/xul/reftest.list.firefox-tests-reftest firefox-92.0/layout/reftests/xul/reftest.list ---- firefox-92.0/layout/reftests/xul/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/reftests/xul/reftest.list 2021-09-03 18:50:44.869939823 +0200 -@@ -15 +15 @@ --random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == chrome://reftest/content/xul/text-small-caps-1.xhtml chrome://reftest/content/xul/text-small-caps-1-ref.xhtml -+fuzzy-if(gtkWidget,0-255,0-5159) random-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) == chrome://reftest/content/xul/text-small-caps-1.xhtml chrome://reftest/content/xul/text-small-caps-1-ref.xhtml -diff -U0 firefox-92.0/layout/xul/reftest/reftest.list.firefox-tests-reftest firefox-92.0/layout/xul/reftest/reftest.list ---- firefox-92.0/layout/xul/reftest/reftest.list.firefox-tests-reftest 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/layout/xul/reftest/reftest.list 2021-09-03 18:50:44.869939823 +0200 -@@ -13,2 +12,0 @@ --# This test is fuzzy as the marks cannot be positioned exactly as the real ones are measured in dev pixels. --fuzzy(0-10,0-102) fuzzy-if(winWidget&&isDebugBuild&&layersGPUAccelerated&&!is64Bit,1-1,102-102) == chrome://reftest/content/xul/reftest/scrollbar-marks-overlay.html chrome://reftest/content/xul/reftest/scrollbar-marks-overlay-ref.html diff --git a/firefox-tests-xpcshell-freeze.patch b/firefox-tests-xpcshell-freeze.patch deleted file mode 100644 index 1115417..0000000 --- a/firefox-tests-xpcshell-freeze.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up firefox-88.0/testing/xpcshell/runxpcshelltests.py.old firefox-88.0/testing/xpcshell/runxpcshelltests.py ---- firefox-88.0/testing/xpcshell/runxpcshelltests.py.old 2021-04-30 10:45:14.466616224 +0200 -+++ firefox-88.0/testing/xpcshell/runxpcshelltests.py 2021-04-30 10:45:21.339525085 +0200 -@@ -1382,8 +1382,8 @@ class XPCShellTests(object): - self.log.info("Process %s" % label) - self.log.info(msg) - -- dumpOutput(proc.stdout, "stdout") -- dumpOutput(proc.stderr, "stderr") -+ #dumpOutput(proc.stdout, "stdout") -+ #dumpOutput(proc.stderr, "stderr") - self.nodeProc = {} - - def startHttp3Server(self): diff --git a/firefox-tests-xpcshell.patch b/firefox-tests-xpcshell.patch deleted file mode 100644 index a342668..0000000 --- a/firefox-tests-xpcshell.patch +++ /dev/null @@ -1,147 +0,0 @@ -diff -U0 firefox-92.0/browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini ---- firefox-92.0/browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:14:33.000000000 +0200 -+++ firefox-92.0/browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini 2021-09-03 18:39:17.386058157 +0200 -@@ -9 +8,0 @@ --[test_appupdateurl.js] -@@ -27 +25,0 @@ --[test_sorted_alphabetically.js] -diff -U0 firefox-92.0/netwerk/test/unit_ipc/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/netwerk/test/unit_ipc/xpcshell.ini ---- firefox-92.0/netwerk/test/unit_ipc/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:15:11.000000000 +0200 -+++ firefox-92.0/netwerk/test/unit_ipc/xpcshell.ini 2021-09-03 18:41:07.754088004 +0200 -@@ -73 +72,0 @@ --[test_dns_service_wrap.js] -@@ -114 +112,0 @@ --[test_trr_httpssvc_wrap.js] -diff -U0 firefox-92.0/netwerk/test/unit/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/netwerk/test/unit/xpcshell.ini ---- firefox-92.0/netwerk/test/unit/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:15:11.000000000 +0200 -+++ firefox-92.0/netwerk/test/unit/xpcshell.ini 2021-09-03 18:41:58.545482327 +0200 -@@ -205 +204,0 @@ --[test_dns_service.js] -@@ -221 +219,0 @@ --[test_file_protocol.js] -@@ -328 +325,0 @@ --[test_unix_domain.js] -@@ -340 +336,0 @@ --[test_udp_multicast.js] -@@ -390,2 +385,0 @@ --[test_tls_flags.js] --skip-if = (os == "android" && processor == "x86_64") -@@ -406 +399,0 @@ --[test_network_connectivity_service.js] -@@ -503 +495,0 @@ --[test_httpssvc_retry_with_ech.js] -@@ -513 +504,0 @@ --[test_odoh.js] -diff -U0 firefox-92.0/security/manager/ssl/tests/unit/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/security/manager/ssl/tests/unit/xpcshell.ini ---- firefox-92.0/security/manager/ssl/tests/unit/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:15:06.000000000 +0200 -+++ firefox-92.0/security/manager/ssl/tests/unit/xpcshell.ini 2021-09-03 18:41:07.755088031 +0200 -@@ -115,4 +114,0 @@ --[test_encrypted_client_hello.js] --run-sequentially = hardcoded ports --[test_encrypted_client_hello_client_only.js] --run-sequentially = hardcoded ports -@@ -180 +175,0 @@ --[test_oskeystore.js] -diff -U0 firefox-92.0/security/manager/ssl/tests/unit/xpcshell-smartcards.ini.firefox-tests-xpcshell firefox-92.0/security/manager/ssl/tests/unit/xpcshell-smartcards.ini ---- firefox-92.0/security/manager/ssl/tests/unit/xpcshell-smartcards.ini.firefox-tests-xpcshell 2021-09-01 19:15:18.000000000 +0200 -+++ firefox-92.0/security/manager/ssl/tests/unit/xpcshell-smartcards.ini 2021-09-03 18:41:07.755088031 +0200 -@@ -10 +9,0 @@ --[test_pkcs11_module.js] -diff -U0 firefox-92.0/toolkit/components/antitracking/test/xpcshell/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/toolkit/components/antitracking/test/xpcshell/xpcshell.ini ---- firefox-92.0/toolkit/components/antitracking/test/xpcshell/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:15:34.000000000 +0200 -+++ firefox-92.0/toolkit/components/antitracking/test/xpcshell/xpcshell.ini 2021-09-03 18:41:07.755088031 +0200 -@@ -11 +10,0 @@ --[test_staticPartition_font.js] -diff -U0 firefox-92.0/toolkit/components/commandlines/test/unit/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/toolkit/components/commandlines/test/unit/xpcshell.ini ---- firefox-92.0/toolkit/components/commandlines/test/unit/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:16:05.000000000 +0200 -+++ firefox-92.0/toolkit/components/commandlines/test/unit/xpcshell.ini 2021-09-03 18:41:07.755088031 +0200 -@@ -10 +9,0 @@ --[test_resolvefile.js] -diff -U0 firefox-92.0/toolkit/components/corroborator/test/xpcshell/test_verify_jar.js.firefox-tests-xpcshell firefox-92.0/toolkit/components/corroborator/test/xpcshell/test_verify_jar.js ---- firefox-92.0/toolkit/components/corroborator/test/xpcshell/test_verify_jar.js.firefox-tests-xpcshell 2021-09-01 19:16:00.000000000 +0200 -+++ firefox-92.0/toolkit/components/corroborator/test/xpcshell/test_verify_jar.js 2021-09-03 18:41:07.755088031 +0200 -@@ -30,5 +29,0 @@ -- -- result = await Corroborate.verifyJar( -- do_get_file("data/signed-components.xpi") -- ); -- equal(result, true, "Components signed files do verify"); -diff -U0 firefox-92.0/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini.firefox-tests-xpcshell firefox-92.0/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini ---- firefox-92.0/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini.firefox-tests-xpcshell 2021-09-01 19:16:05.000000000 +0200 -+++ firefox-92.0/toolkit/components/extensions/test/xpcshell/xpcshell-common.ini 2021-09-03 18:41:07.755088031 +0200 -@@ -97,10 +96,0 @@ --skip-if = appname == "thunderbird" || os == "android" || tsan # tsan: bug 1612707 --[test_ext_downloads_misc.js] --skip-if = -- os == "android" -- os == 'linux' && bits == 32 # bug 1324870 -- tsan # bug 1612707 -- os == "win" && bits == 32 # bug 1559476 --[test_ext_downloads_partitionKey.js] --skip-if = os == "android" --[test_ext_downloads_private.js] -@@ -288,2 +277,0 @@ --[test_proxy_listener.js] --skip-if = appname == "thunderbird" -diff -U0 firefox-92.0/toolkit/components/search/tests/xpcshell/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/toolkit/components/search/tests/xpcshell/xpcshell.ini ---- firefox-92.0/toolkit/components/search/tests/xpcshell/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:16:05.000000000 +0200 -+++ firefox-92.0/toolkit/components/search/tests/xpcshell/xpcshell.ini 2021-09-03 18:41:07.755088031 +0200 -@@ -124 +123,0 @@ --[test_reload_engines.js] -@@ -131 +129,0 @@ --[test_searchSuggest.js] -@@ -142,2 +139,0 @@ --[test_settings.js] --[test_sort_orders-no-hints.js] -diff -U0 firefox-92.0/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js.firefox-tests-xpcshell firefox-92.0/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js ---- firefox-92.0/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js.firefox-tests-xpcshell 2021-09-01 19:16:00.000000000 +0200 -+++ firefox-92.0/toolkit/components/telemetry/tests/unit/test_TelemetrySession.js 2021-09-03 18:41:07.755088031 +0200 -@@ -594,20 +593,0 @@ -- Assert.ok( -- withSuspend - withoutSuspend <= max_delta_ms, -- "In test condition, the two uptimes should be close to each other" -- ); -- -- // This however should always hold, except on Windows < 10, where the two -- // clocks are from different system calls, and it can fail in test condition -- // because the machine has not been suspended. -- if ( -- AppConstants.platform != "win" || -- AppConstants.isPlatformAndVersionAtLeast("win", "10.0") -- ) { -- Assert.greaterOrEqual( -- withSuspend, -- withoutSuspend, -- `The uptime with suspend must always been greater or equal to the uptime -- without suspend` -- ); -- } -- -diff -U0 firefox-92.0/toolkit/mozapps/downloads/tests/unit/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/toolkit/mozapps/downloads/tests/unit/xpcshell.ini ---- firefox-92.0/toolkit/mozapps/downloads/tests/unit/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:16:01.000000000 +0200 -+++ firefox-92.0/toolkit/mozapps/downloads/tests/unit/xpcshell.ini 2021-09-03 18:41:07.755088031 +0200 -@@ -4 +3,0 @@ --[test_DownloadUtils.js] -diff -U0 firefox-92.0/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini ---- firefox-92.0/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:16:01.000000000 +0200 -+++ firefox-92.0/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini 2021-09-03 18:41:07.756088058 +0200 -@@ -91 +90,0 @@ --[test_sideloads_after_rebuild.js] -@@ -106 +104,0 @@ --[test_startup_scan.js] -@@ -187,2 +184,0 @@ --tags = webextensions --[test_webextension_theme.js] -diff -U0 firefox-92.0/toolkit/profile/xpcshell/xpcshell.ini.firefox-tests-xpcshell firefox-92.0/toolkit/profile/xpcshell/xpcshell.ini ---- firefox-92.0/toolkit/profile/xpcshell/xpcshell.ini.firefox-tests-xpcshell 2021-09-01 19:15:35.000000000 +0200 -+++ firefox-92.0/toolkit/profile/xpcshell/xpcshell.ini 2021-09-03 18:41:07.756088058 +0200 -@@ -32,3 +31,0 @@ --[test_snatch_environment.js] --[test_skip_locked_environment.js] --[test_snatch_environment_default.js] -diff -U0 firefox-92.0/uriloader/exthandler/tests/unit/test_handlerService.js.firefox-tests-xpcshell firefox-92.0/uriloader/exthandler/tests/unit/test_handlerService.js ---- firefox-92.0/uriloader/exthandler/tests/unit/test_handlerService.js.firefox-tests-xpcshell 2021-09-01 19:16:05.000000000 +0200 -+++ firefox-92.0/uriloader/exthandler/tests/unit/test_handlerService.js 2021-09-03 18:41:07.756088058 +0200 -@@ -145 +145 @@ -- Assert.ok(!protoInfo.alwaysAskBeforeHandling); -+ //Assert.ok(!protoInfo.alwaysAskBeforeHandling); diff --git a/firefox.1 b/firefox.1 index 556cf07..318f2af 100644 --- a/firefox.1 +++ b/firefox.1 @@ -1,4 +1,4 @@ -.TH FIREFOX 1 "November 30, 2017" firefox "Linux User's Manual" +.TH FIREFOX 1 "July 10, 2019" firefox "Linux User's Manual" .SH NAME firefox \- a Web browser for X11 derived from the Mozilla browser @@ -6,17 +6,10 @@ firefox \- a Web browser for X11 derived from the Mozilla browser .B firefox [\fIOPTIONS\fR ...] [\fIURL\fR] -.B firefox-bin -[\fIOPTIONS\fR] [\fIURL\fR] - .SH DESCRIPTION \fBMozilla Firefox\fR is an open-source web browser, designed for standards compliance, performance and portability. -.SH USAGE -\fBfirefox\fR is a simple shell script that will set up the -environment for the actual executable, \fBfirefox-bin\fR. - .SH OPTIONS A summary of the options supported by \fBfirefox\fR is included below. @@ -33,10 +26,10 @@ Make all warnings fatal .SS "Firefox options" .TP -.B \-h, \-help +.B \-h, \--help Show summary of options. .TP -.B \-v, \-version +.B \-v, \--version Print Firefox version. .TP \fB\-P\fR \fIprofile\fR @@ -63,11 +56,22 @@ Start with \fIlocale\fR resources as UI Locale. \fB\-\-safe\-mode\fR Disables extensions and themes for this session. .TP +\fB\--allow-downgrade\fR +Allows downgrading a profile. +.TP +\fB\--MOZ_LOG\fR=\fImodules\fR +Treated as \fBMOZ_LOG\fR=\fImodules\fR environment variable, overrides it. +.TP +\fB\--MOZ_LOG_FILE\fR=\fIfile\fR +Treated as \fBMOZ_LOG_FILE\fR=\fIfile\fR environment variable, overrides it. If +MOZ_LOG_FILE is not specified as an argument or as an environment variable, +logging will be written to stdout. +.TP \fB\-\-headless\fR Run without a GUI. .TP -\fB\-\-marionette\fR -Enable remote control server. +\fB\-\-save-recordings\fR +Save recordings for all content processes to a directory. .TP \fB\-\-browser\fR Open a browser window. @@ -93,8 +97,9 @@ Width and optionally height of screenshot. \fB\-\-search\fR \fIterm\fR Search \fIterm\fR with your default search engine. .TP - - +\fB\-\-setDefaultBrowser\fR +Set this app as the default browser. +.TP \fB\-\-jsconsole\fR Open the Browser Console. .TP @@ -115,19 +120,16 @@ Record drawing for a given URL. .TP \fB\-\-recording-output\fR \fIfile\fR Specify destination file for a drawing recording. -.TP -\fB\-\-setDefaultBrowser\fR -Set this app as the default browser. .SH FILES \fI/usr/bin/firefox\fR - shell script wrapping \fBfirefox\fR .br -\fI/usr/lib64/firefox/firefox-bin\fR - \fBfirefox\fR +\fI/usr/lib64/firefox/firefox\fR - \fBfirefox\fR executable .SH VERSION -57.0 +68.0 .SH BUGS To report a bug, please visit \fIhttp://bugzilla.mozilla.org/\fR diff --git a/firefox.desktop b/firefox.desktop index 6e51fb3..bd09aa8 100644 --- a/firefox.desktop +++ b/firefox.desktop @@ -1,47 +1,520 @@ [Desktop Entry] Version=1.0 Name=Firefox -GenericName=Web Browser -GenericName[ca]=Navegador web -GenericName[cs]=Webový prohlížeč -GenericName[es]=Navegador web -GenericName[fa]=مرورگر اینترنتی -GenericName[fi]=WWW-selain -GenericName[fr]=Navigateur Web -GenericName[hu]=Webböngésző -GenericName[it]=Browser Web -GenericName[ja]=ウェブ・ブラウザ -GenericName[ko]=웹 브라우저 -GenericName[nb]=Nettleser -GenericName[nl]=Webbrowser -GenericName[nn]=Nettlesar -GenericName[no]=Nettleser -GenericName[pl]=Przeglądarka WWW -GenericName[pt]=Navegador Web -GenericName[pt_BR]=Navegador Web -GenericName[sk]=Internetový prehliadač -GenericName[sv]=Webbläsare -Comment=Browse the Web -Comment[ca]=Navegueu per el web +Name[ach]=Firefox +Name[af]=Firefox +Name[an]=Firefox +Name[ar]=Firefox +Name[ast]=Firefox +Name[az]=Firefox +Name[be]=Firefox +Name[bg]=Firefox +Name[bn]=Firefox +Name[br]=Firefox +Name[bs]=Firefox +Name[ca]=Firefox +Name[ca_valencia]=Firefox +Name[cak]=Firefox +Name[cs]=Firefox +Name[cy]=Firefox +Name[da]=Firefox +Name[de]=Firefox +Name[dsb]=Firefox +Name[el]=Firefox +Name[en_CA]=Firefox +Name[en_GB]=Firefox +Name[eo]=Firefox +Name[es_AR]=Firefox +Name[es_CL]=Firefox +Name[es_ES]=Firefox +Name[es_MX]=Firefox +Name[et]=Firefox +Name[eu]=Firefox +Name[fa]=Firefox +Name[ff]=Firefox +Name[fi]=Firefox +Name[fr]=Firefox +Name[fur]=Firefox +Name[fy_NL]=Firefox +Name[ga_IE]=Firefox +Name[gd]=Firefox +Name[gl]=Firefox +Name[gn]=Firefox +Name[gu_IN]=Firefox +Name[he]=Firefox +Name[hi_IN]=Firefox +Name[hr]=Firefox +Name[hsb]=Firefox +Name[hu]=Firefox +Name[hy_AM]=Firefox +Name[ia]=Firefox +Name[id]=Firefox +Name[is]=Firefox +Name[it]=Firefox +Name[ja]=Firefox +Name[ka]=Firefox +Name[kab]=Firefox +Name[kk]=Firefox +Name[km]=Firefox +Name[kn]=Firefox +Name[ko]=Firefox +Name[lij]=Firefox +Name[lt]=Firefox +Name[lv]=Firefox +Name[mk]=Firefox +Name[mr]=Firefox +Name[ms]=Firefox +Name[my]=Firefox +Name[nb_NO]=Firefox +Name[ne_NP]=Firefox +Name[nl]=Firefox +Name[nn_NO]=Firefox +Name[oc]=Firefox +Name[pa_IN]=Firefox +Name[pl]=Firefox +Name[pt_BR]=Firefox +Name[pt_PT]=Firefox +Name[rm]=Firefox +Name[ro]=Firefox +Name[ru]=Firefox +Name[sat]=Firefox +Name[sc]=Firefox +Name[sco]=Firefox +Name[si]=Firefox +Name[sk]=Firefox +Name[skr]=Firefox +Name[sl]=Firefox +Name[son]=Firefox +Name[sq]=Firefox +Name[sr]=Firefox +Name[sv_SE]=Firefox +Name[szl]=Firefox +Name[ta]=Firefox +Name[te]=Firefox +Name[tg]=Firefox +Name[th]=Firefox +Name[tl]=Firefox +Name[tr]=Firefox +Name[trs]=Firefox +Name[uk]=Firefox +Name[ur]=Firefox +Name[uz]=Firefox +Name[vi]=Firefox +Name[xh]=Firefox +Name[zh_CN]=Firefox +Name[zh_TW]=Firefox +Comment=Browse the World Wide Web +Comment[ach]=Browse the World Wide Web +Comment[af]=Browse the World Wide Web +Comment[an]=Browse the World Wide Web +Comment[ar]=تصفح شبكة الوِب العالمية +Comment[ast]=Browse the World Wide Web +Comment[az]=Browse the World Wide Web +Comment[be]=Аглядайце Сеціва +Comment[bg]=Разгледайте световната мрежа +Comment[bn]=ওয়ার্ল্ড ওয়াইড ওয়েব ব্রাউজ করুন +Comment[br]=Ergerzhout ar World Wide Web +Comment[bs]=Pretražujte World Wide Web +Comment[ca]=Navegeu pel Web +Comment[ca_valencia]=Browse the World Wide Web +Comment[cak]=Tok chupam Word Wide Web Comment[cs]=Prohlížení stránek World Wide Webu +Comment[cy]=Pori'r We Fyd Eang +Comment[da]=Brug internettet Comment[de]=Im Internet surfen -Comment[es]=Navegue por la web -Comment[fa]=صفحات شبکه جهانی اینترنت را مرور نمایید -Comment[fi]=Selaa Internetin WWW-sivuja -Comment[fr]=Navigue sur Internet -Comment[hu]=A világháló böngészése -Comment[it]=Esplora il web -Comment[ja]=ウェブを閲覧します -Comment[ko]=웹을 돌아 다닙니다 -Comment[nb]=Surf på nettet -Comment[nl]=Verken het internet -Comment[nn]=Surf på nettet -Comment[no]=Surf på nettet -Comment[pl]=Przeglądanie stron WWW -Comment[pt]=Navegue na Internet -Comment[pt_BR]=Navegue na Internet -Comment[sk]=Prehliadanie internetu -Comment[sv]=Surfa på webben +Comment[dsb]=Pśeglědajśo World Wide Web +Comment[el]=Περιηγηθείτε στον παγκόσμιο ιστό +Comment[en_CA]=Browse the World Wide Web +Comment[en_GB]=Browse the World Wide Web +Comment[eo]=Retumi en la reto +Comment[es_AR]=Navegar la World Wide Web +Comment[es_CL]=Navegar por la World Wide Web +Comment[es_ES]=Navegar por la web +Comment[es_MX]=Navegar por la web +Comment[et]=Browse the World Wide Web +Comment[eu]=Arakatu World Wide Web-a +Comment[fa]=Browse the World Wide Web +Comment[ff]=Browse the World Wide Web +Comment[fi]=Selaa Internetiä +Comment[fr]=Naviguer sur le Web +Comment[fur]=Navighe sul Web +Comment[fy_NL]=Navigearje op it wrâldwide web +Comment[ga_IE]=Browse the World Wide Web +Comment[gd]=Rùraich lìon na cruinne +Comment[gl]=Navegar pola World Wide Web +Comment[gn]=Eikundaha World Wide Web rupi +Comment[gu_IN]=Browse the World Wide Web +Comment[he]=גלישה באינטרנט +Comment[hi_IN]=Browse the World Wide Web +Comment[hr]=Pregledaj World Wide Web +Comment[hsb]=Přehladajće World Wide Web +Comment[hu]=Böngésszen a világhálón +Comment[hy_AM]=Զննի՛ր համաշխարհային սարդոստայնը +Comment[ia]=Navigar sur le Web +Comment[id]=Jelajahi World Wide Web +Comment[is]=Vafraðu um veraldarvefinn +Comment[it]=Naviga sul Web +Comment[ja]=World Wide Web をブラウジング +Comment[ka]=მსოფლიო ქსელთან წვდომა +Comment[kab]=Inig deg Web +Comment[kk]=Ғаламторды шолу +Comment[km]=Browse the World Wide Web +Comment[kn]=Browse the World Wide Web +Comment[ko]=월드 와이드 웹 탐색 +Comment[lij]=Browse the World Wide Web +Comment[lt]=Browse the World Wide Web +Comment[lv]=Pārlūkojiet globālo tīmekli +Comment[mk]=Browse the World Wide Web +Comment[mr]=Browse the World Wide Web +Comment[ms]=Browse the World Wide Web +Comment[my]=Browse the World Wide Web +Comment[nb_NO]=Surf på nettet +Comment[ne_NP]=वर्ल्ड वाइड वेब ब्राउज गर्नुहोस् +Comment[nl]=Navigeren op het wereldwijde web +Comment[nn_NO]=Surf på nettet +Comment[oc]=Navegar pel Web +Comment[pa_IN]=ਵਰਲਡ ਵਾਈਡ ਵੈੱਬ ਬਰਾਊਜ਼ਰ ਕਰੋ +Comment[pl]=Przeglądaj Internet +Comment[pt_BR]=Navegue na World Wide Web +Comment[pt_PT]=Navegar na Internet +Comment[rm]=Navigar en il web +Comment[ro]=Browse the World Wide Web +Comment[ru]=Доступ в Интернет +Comment[sat]=World Wide Web ᱠᱷᱩᱞᱟᱹᱭ ᱢᱮ +Comment[sc]=Nàviga su Web +Comment[sco]=Browse the World Wide Web +Comment[si]=ලෝක ව්‍යාප්ත වියමන පිරික්සන්න +Comment[sk]=Prehľadávať web (www) +Comment[skr]=ورلڈ وائیڈ ویب براؤز کرو +Comment[sl]=Brskanje po svetovnem spletu +Comment[son]=Browse the World Wide Web +Comment[sq]=Shfletoni në World Wide Web +Comment[sr]=Истражите интернет +Comment[sv_SE]=Surfa på webben +Comment[szl]=Browse the World Wide Web +Comment[ta]=Browse the World Wide Web +Comment[te]=ప్రపంచ వ్యాప్త జాలంలో విహరించండి +Comment[tg]=Ба шабакаи ҷаҳонии Интернет дастрасӣ пайдо намоед +Comment[th]=เรียกดูเวิลด์ไวด์เว็บ +Comment[tl]=Browse the World Wide Web +Comment[tr]=Web’de gezin +Comment[trs]=Gāchē nu ngà World Wide Web +Comment[uk]=Переглядайте всесвітню мережу +Comment[ur]=Browse the World Wide Web +Comment[uz]=Browse the World Wide Web +Comment[vi]=Duyệt web trên toàn thế giới +Comment[xh]=Browse the World Wide Web +Comment[zh_CN]=浏览万维网 +Comment[zh_TW]=瀏覽全球資訊網 +GenericName=Web Browser +GenericName[ach]=Web Browser +GenericName[af]=Web Browser +GenericName[an]=Web Browser +GenericName[ar]=متصفح الإنترنت +GenericName[ast]=Web Browser +GenericName[az]=Web Browser +GenericName[be]=Вэб-браўзер +GenericName[bg]=Уеб браузър +GenericName[bn]=ওয়েব ব্রাউজার +GenericName[br]=Merdeer Web +GenericName[bs]=Web pretraživač +GenericName[ca]=Navegador web +GenericName[ca_valencia]=Web Browser +GenericName[cak]=Web Okik'amaya'l +GenericName[cs]=Webový prohlížeč +GenericName[cy]=Porwr Gwe +GenericName[da]=Webbrowser +GenericName[de]=Internet-Browser +GenericName[dsb]=Webwobglědowak +GenericName[el]=Πρόγραμμα περιήγησης +GenericName[en_CA]=Web Browser +GenericName[en_GB]=Web Browser +GenericName[eo]=Retumilo +GenericName[es_AR]=Navegador web +GenericName[es_CL]=Navegador Web +GenericName[es_ES]=Navegador web +GenericName[es_MX]=Navegador Web +GenericName[et]=Web Browser +GenericName[eu]=Web nabigatzailea +GenericName[fa]=Web Browser +GenericName[ff]=Web Browser +GenericName[fi]=Verkkoselain +GenericName[fr]=Navigateur web +GenericName[fur]=Navigadôr Web +GenericName[fy_NL]=Webbrowser +GenericName[ga_IE]=Web Browser +GenericName[gd]=Brabhsair-lìn +GenericName[gl]=Navegador web +GenericName[gn]=Ñanduti Kundahára +GenericName[gu_IN]=Web Browser +GenericName[he]=דפדפן אינטרנט +GenericName[hi_IN]=Web Browser +GenericName[hr]=Web preglednik +GenericName[hsb]=Webwobhladowak +GenericName[hu]=Webböngésző +GenericName[hy_AM]=Վեբ դիտարկիչ +GenericName[ia]=Navigator web +GenericName[id]=Peramban Web +GenericName[is]=Vafri +GenericName[it]=Browser web +GenericName[ja]=ウェブブラウザー +GenericName[ka]=ბრაუზერი +GenericName[kab]=Iminig web +GenericName[kk]=Веб-браузері +GenericName[km]=Web Browser +GenericName[kn]=Web Browser +GenericName[ko]=웹 브라우저 +GenericName[lij]=Navegatô Web +GenericName[lt]=Web Browser +GenericName[lv]=Tīmekļa pārlūks +GenericName[mk]=Web Browser +GenericName[mr]=Web Browser +GenericName[ms]=Web Browser +GenericName[my]=Web Browser +GenericName[nb_NO]=Nettleser +GenericName[ne_NP]=वेब ब्राउजर +GenericName[nl]=Webbrowser +GenericName[nn_NO]=Nettlesar +GenericName[oc]=Navegador Web +GenericName[pa_IN]=ਵੈੱਬ ਬਰਾਊਜ਼ਰ +GenericName[pl]=Przeglądarka internetowa +GenericName[pt_BR]=Navegador web +GenericName[pt_PT]=Navegador Web +GenericName[rm]=Navigatur web +GenericName[ro]=Web Browser +GenericName[ru]=Веб-браузер +GenericName[sat]=ᱣᱮᱵᱽ ᱵᱽᱨᱟᱣᱡᱚᱨ +GenericName[sc]=Navigadore web +GenericName[sco]=Web Browser +GenericName[si]=වියමන අතිරික්සුව +GenericName[sk]=Webový prehliadač +GenericName[skr]=ویب براؤزر +GenericName[sl]=Spletni brskalnik +GenericName[son]=Web Browser +GenericName[sq]=Shfletues +GenericName[sr]=Веб прегледач +GenericName[sv_SE]=Webbläsare +GenericName[szl]=Web Browser +GenericName[ta]=Web Browser +GenericName[te]=జాల విహారిణి +GenericName[tg]=Браузери веб +GenericName[th]=เว็บเบราว์เซอร์ +GenericName[tl]=Web Browser +GenericName[tr]=Web Tarayıcısı +GenericName[trs]=Web riña gāchē nu’ +GenericName[uk]=Браузер +GenericName[ur]=Web Browser +GenericName[uz]=Web Browser +GenericName[vi]=Trình duyệt web +GenericName[xh]=Web Browser +GenericName[zh_CN]=Web 浏览器 +GenericName[zh_TW]=網頁瀏覽器 +Keywords=Internet;WWW;Browser;Web;Explorer; +Keywords[ach]=Internet;WWW;Browser;Web;Explorer; +Keywords[af]=Internet;WWW;Browser;Web;Explorer; +Keywords[an]=Internet;WWW;Browser;Web;Explorer; +Keywords[ar]=إنترنت;WWW;متصفح;ويب;مستكشف; +Keywords[ast]=Internet;WWW;Browser;Web;Explorer; +Keywords[az]=Internet;WWW;Browser;Web;Explorer; +Keywords[be]=Internet;WWW;Browser;Web;Explorer; +Keywords[bg]=Internet;WWW;Browser;Web;Explorer; +Keywords[bn]=ইন্টারনেট;WWW;ব্রাউজার;ওয়েব;এক্সপ্লোরার; +Keywords[br]=Internet;WWW;Merdeer;Web;Ergerzhout; +Keywords[bs]=Internet;WWW;Pretraživač;Web;Istraživač; +Keywords[ca]=Internet;WWW;Browser;Web;Explorador;Navegador; +Keywords[ca_valencia]=Internet;WWW;Browser;Web;Explorer; +Keywords[cak]=K'amaya'l;WWW;Okik'amaya'l;Kanob'äl; +Keywords[cs]=internet;WWW;prohlížeč;web; +Keywords[cy]=Rhyngrwyd;WWW;Porwr;Gwe;Archwiliwr; +Keywords[da]=Internet;WWW;Browser;Nettet;Explorer; +Keywords[de]=Internet;WWW;Browser;Web;Explorer; +Keywords[dsb]=Internet;WWW;wobglědowak;Web;Explorer; +Keywords[el]=Internet;WWW;Browser;Web;Explorer;Διαδίκτυο;Ιστός;Ίντερνετ; +Keywords[en_CA]=Internet;WWW;Browser;Web;Explorer; +Keywords[en_GB]=Internet;WWW;Browser;Web;Explorer; +Keywords[eo]=Interreto;Retumilo;TTT;Teksaĵo;Reto;Internet;WWW;Browser;Web;Explorer; +Keywords[es_AR]=Internet;WWW;Navegador;Web;Explorador; +Keywords[es_CL]=Internet;WWW;Navegador;Web;Explorador; +Keywords[es_ES]=Internet;WWW;Navegador;Web;Explorador; +Keywords[es_MX]=Internet;WWW;Navegador;Web;Explorador; +Keywords[et]=Internet;WWW;Browser;Web;Explorer; +Keywords[eu]=Internet;WWW;Nabigatzailea;Web;Arakatzailea; +Keywords[fa]=Internet;WWW;Browser;Web;Explorer; +Keywords[ff]=Internet;WWW;Browser;Web;Explorer; +Keywords[fi]=Internet;WWW;Browser;Web;Explorer;netti;webbi;selain; +Keywords[fr]=Internet;WWW;Navigateur;Web;Explorer; +Keywords[fur]=Internet;WWW;Browser;Navigadôr;Web;Esploradôr;Explorer; +Keywords[fy_NL]=Ynternet;WWW;Browser;Web;Ferkenner; +Keywords[ga_IE]=Internet;WWW;Browser;Web;Explorer; +Keywords[gd]=Internet;WWW;Browser;Web;Explorer;eadar-lìon;brabhsair;brobhsair;lìon;taisgealaiche; +Keywords[gl]=Internet;WWW;Navegador;Web;Explorador; +Keywords[gn]=Internet;WWW;Browser;Web;Explorer; +Keywords[gu_IN]=Internet;WWW;Browser;Web;Explorer; +Keywords[he]=אינטרנט;WWW;דפדפן;רשת;סייר;מרשתת; +Keywords[hi_IN]=Internet;WWW;Browser;Web;Explorer; +Keywords[hr]=Internet;WWW;Preglednik;Web;Istraživač; +Keywords[hsb]=Internet;WWW;wobhladowak;Web;Explorer; +Keywords[hu]=Internet;WWW;Böngésző;Web;Világháló; +Keywords[hy_AM]=Համացանց,WWW,Զննիչ,Վեբ,Ցանցախույզ: +Keywords[ia]=Internet;WWW;Navigator;Web;Explorator; +Keywords[id]=Internet;WWW;Browser;Web;Explorer; +Keywords[is]=Internet;WWW; Vafri; Vefur; Explorer; +Keywords[it]=Internet;WWW;Browser;Web;Explorer;Navigatore; +Keywords[ja]=Internet;WWW;Browser;Web;Explorer;インターネット;ブラウザー;ウェブ; +Keywords[ka]=ინტერნეტი;WWW;ბრაუზერი;ქსელი;ქსელთან წვდომა; +Keywords[kab]=Internet;WWW;Browser;Web;Explorer; +Keywords[kk]=Internet;WWW;Browser;Web;Explorer;Интернет;Ғаламтор;Браузер;Желі;Шолғыш; +Keywords[km]=Internet;WWW;Browser;Web;Explorer; +Keywords[kn]=Internet;WWW;Browser;Web;Explorer; +Keywords[ko]=인터넷;브라우저;웹;탐색기;Internet;WWW;Browser;Web;Explorer; +Keywords[lij]=Internet;WWW;Browser;Web;Explorer;Navegatô; +Keywords[lt]=Internet;WWW;Browser;Web;Explorer; +Keywords[lv]=Internets;WWW;Pārlūkprogramma;Tīmeklis; +Keywords[mk]=Internet;WWW;Browser;Web;Explorer; +Keywords[mr]=Internet;WWW;Browser;Web;Explorer; +Keywords[ms]=Internet;WWW;Browser;Web;Explorer; +Keywords[my]=Internet;WWW;Browser;Web;Explorer; +Keywords[nb_NO]=Internett;WWW;Nettleser;Web;Utforsker; +Keywords[ne_NP]=Internet;WWW;Browser;Web;Explorer; +Keywords[nl]=Internet;WWW;Browser;Web;Verkenner; +Keywords[nn_NO]=Internett;WWW;Nettlesar;Web;Utforskar; +Keywords[oc]=Internet;WWW;Navegador;Navigador;Navegator;Navigator;Web;Explorer; +Keywords[pa_IN]=ਇੰਟਰਨੈੱਟ;WWW;ਬਰਾਊਜ਼ਰ;ਵੈੱਬ;ਐਕਸਪਲਰੋਰ;ਵੈਬ;ਇੰਟਰਨੈਟ; +Keywords[pl]=Internet;WWW;Przeglądarka;Browser;Wyszukiwarka;Web;Sieć;Explorer;Eksplorer;Strony;Witryny;internetowe; +Keywords[pt_BR]=Internet;WWW;Browser;Web;Explorer;Navegador; +Keywords[pt_PT]=Internet;WWW;Navegador;Web;Explorador; +Keywords[rm]=Internet;WWW;Browser;Web;Explorer;navigatur; +Keywords[ro]=Internet;WWW;Browser;Web;Explorer; +Keywords[ru]=Сеть;Интернет;Браузер;Доступ в Интернет; +Keywords[sat]=Internet;WWW;Browser;Web;Explorer; +Keywords[sc]=Internet;WWW;Navigadore;Web;Explorer; +Keywords[sco]=Internet;WWW;Browser;Web;Explorer; +Keywords[si]=අන්තර්ජාලය;අතිරික්සුව;පිරික්සන්න;ගවේශකය;Internet;WWW;Browser;Web;Explorer; +Keywords[sk]=Internet;WWW;Prehliadač;Web;Prieskumník; +Keywords[skr]=Internet;WWW;Browser;Web;Explorer; +Keywords[sl]=internet;www;brskalnik;splet; +Keywords[son]=Internet;WWW;Browser;Web;Explorer; +Keywords[sq]=Internet;WWW;Shfletues;Web;Eksplorues; +Keywords[sr]=Internet;WWW;Browser;Web;Explorer;интернет;прегледач;веб;мрежа;прегледач; +Keywords[sv_SE]=Internet;WWW;Webbläsare;Webb;Utforskare; +Keywords[szl]=Internet;WWW;Browser;Web;Explorer; +Keywords[ta]=Internet;WWW;Browser;Web;Explorer; +Keywords[te]=Internet;WWW;Browser;Web;Explorer; +Keywords[tg]=Интернет;WWW;Браузер;Сомона;Ҷустуҷӯгар; +Keywords[th]=อินเทอร์เน็ต;เบราว์เซอร์;เว็บ;Internet;WWW;Browser;Web;Explorer; +Keywords[tl]=Internet;WWW;Browser;Web;Explorer; +Keywords[tr]=Internet;WWW;Browser;Web;Explorer;İnternet;Tarayıcı; +Keywords[trs]=Internet;WWW;Browser;Web;Explorer; +Keywords[uk]=Інтернет;WWW;Браузер;Веб;Переглядач; +Keywords[ur]=Internet;WWW;Browser;Web;Explorer; +Keywords[uz]=Internet;WWW;Browser;Web;Explorer; +Keywords[vi]=Internet;WWW;Trình duyệt;Web;Duyệt web; +Keywords[xh]=Internet;WWW;Browser;Web;Explorer; +Keywords[zh_CN]=Internet;WWW;Browser;Web;Explorer; +Keywords[zh_TW]=網際網路;網路;瀏覽器;網頁;上網;Internet;WWW;Browser;Web;Explorer; +X-GNOME-FullName=Firefox Web Browser +X-GNOME-FullName[ach]=Firefox Web Browser +X-GNOME-FullName[af]=Firefox Web Browser +X-GNOME-FullName[an]=Firefox Web Browser +X-GNOME-FullName[ar]=متصفح Firefox +X-GNOME-FullName[ast]=Firefox Web Browser +X-GNOME-FullName[az]=Firefox Web Browser +X-GNOME-FullName[be]=Вэб-браўзер Firefox +X-GNOME-FullName[bg]=Firefox Уеб браузър +X-GNOME-FullName[bn]=Firefox Web Browser +X-GNOME-FullName[br]=Merdeer Web Firefox +X-GNOME-FullName[bs]=Firefox web pretraživač +X-GNOME-FullName[ca]=Navegador web Firefox +X-GNOME-FullName[ca_valencia]=Firefox Web Browser +X-GNOME-FullName[cak]=Firefox Web Browser +X-GNOME-FullName[cs]=Webový prohlížeč Firefox +X-GNOME-FullName[cy]=Porwr Gwe Firefox +X-GNOME-FullName[da]=Firefox-browser +X-GNOME-FullName[de]=Firefox-Web-Browser +X-GNOME-FullName[dsb]=Webwobglědowak Firefox +X-GNOME-FullName[el]=Πρόγραμμα περιήγησης Firefox +X-GNOME-FullName[en_CA]=Firefox Web Browser +X-GNOME-FullName[en_GB]=Firefox Web Browser +X-GNOME-FullName[eo]=Retumilo Firefox +X-GNOME-FullName[es_AR]=Navegador web Firefox +X-GNOME-FullName[es_CL]=Navegador web Firefox +X-GNOME-FullName[es_ES]=Navegador web Firefox +X-GNOME-FullName[es_MX]=Navegador web Firefox +X-GNOME-FullName[et]=Firefox Web Browser +X-GNOME-FullName[eu]=Firefox web nabigatzailea +X-GNOME-FullName[fa]=Firefox Web Browser +X-GNOME-FullName[ff]=Firefox Web Browser +X-GNOME-FullName[fi]=Firefox-verkkoselain +X-GNOME-FullName[fr]=Navigateur web Firefox +X-GNOME-FullName[fur]=Navigadôr web Firefox +X-GNOME-FullName[fy_NL]=Firefox-webbrowser +X-GNOME-FullName[ga_IE]=Firefox Web Browser +X-GNOME-FullName[gd]=Brabhsair-lìn Firefox +X-GNOME-FullName[gl]=Navegador web Firefox +X-GNOME-FullName[gn]=Firefox Ñanduti Kundahára +X-GNOME-FullName[gu_IN]=Firefox Web Browser +X-GNOME-FullName[he]=דפדפן אינטרנט Firefox +X-GNOME-FullName[hi_IN]=Firefox वेब ब्राउज़र +X-GNOME-FullName[hr]=Firefox web preglednik +X-GNOME-FullName[hsb]=Webwobhladowak Firefox +X-GNOME-FullName[hu]=Firefox webböngésző +X-GNOME-FullName[hy_AM]=Firefox վեբ դիտարկիչ +X-GNOME-FullName[ia]=Navigator web Firefox +X-GNOME-FullName[id]=Firefox Peramban Web +X-GNOME-FullName[is]=Firefox-vafri +X-GNOME-FullName[it]=Browser web Firefox +X-GNOME-FullName[ja]=Firefox ウェブブラウザー +X-GNOME-FullName[ka]=Firefox-ბრაუზერი +X-GNOME-FullName[kab]=Iminig web Firefox +X-GNOME-FullName[kk]=Firefox веб-браузері +X-GNOME-FullName[km]=Firefox Web Browser +X-GNOME-FullName[kn]=Firefox Web Browser +X-GNOME-FullName[ko]=Firefox 웹 브라우저 +X-GNOME-FullName[lij]=Firefox Navegatô Web +X-GNOME-FullName[lt]=Firefox Web Browser +X-GNOME-FullName[lv]=Firefox tīmekļa pārlūks +X-GNOME-FullName[mk]=Firefox Web Browser +X-GNOME-FullName[mr]=Firefox Web Browser +X-GNOME-FullName[ms]=Firefox Web Browser +X-GNOME-FullName[my]=Firefox Web Browser +X-GNOME-FullName[nb_NO]=Firefox-nettleser +X-GNOME-FullName[ne_NP]=Firefox वेब ब्राउजर +X-GNOME-FullName[nl]=Firefox-webbrowser +X-GNOME-FullName[nn_NO]=Firefox-nettlesar +X-GNOME-FullName[oc]=Navegador web Firefox +X-GNOME-FullName[pa_IN]=Firefox ਵੈੱਬ ਬਰਾਊਜ਼ਰ +X-GNOME-FullName[pl]=Przeglądarka Firefox +X-GNOME-FullName[pt_BR]=Navegador web Firefox +X-GNOME-FullName[pt_PT]=Navegador Web Firefox +X-GNOME-FullName[rm]=Navigatur-web Firefox +X-GNOME-FullName[ro]=Firefox Web Browser +X-GNOME-FullName[ru]=Веб-браузер Firefox +X-GNOME-FullName[sat]=Firefox ᱣᱮᱵᱽ ᱵᱽᱨᱟᱣᱡᱚᱨ +X-GNOME-FullName[sc]=Navigadore web Firefox +X-GNOME-FullName[sco]=Firefox Web Browser +X-GNOME-FullName[si]=Firefox අතිරික්සුව +X-GNOME-FullName[sk]=Webový prehliadač Firefox +X-GNOME-FullName[skr]=Firefox ویب براؤزر +X-GNOME-FullName[sl]=Spletni brskalnik Firefox +X-GNOME-FullName[son]=Firefox Web Browser +X-GNOME-FullName[sq]=Shfletuesi Firefox +X-GNOME-FullName[sr]=Firefox веб прегледач +X-GNOME-FullName[sv_SE]=Firefox webbläsare +X-GNOME-FullName[szl]=Firefox Web Browser +X-GNOME-FullName[ta]=Firefox Web Browser +X-GNOME-FullName[te]=Firefox Web Browser +X-GNOME-FullName[tg]=Браузери интернетии «Firefox» +X-GNOME-FullName[th]=เว็บเบราว์เซอร์ Firefox +X-GNOME-FullName[tl]=Firefox Web Browser +X-GNOME-FullName[tr]=Firefox Web Tarayıcısı +X-GNOME-FullName[trs]=Firefox Web riña gāchē nu’ +X-GNOME-FullName[uk]=Браузер Firefox +X-GNOME-FullName[ur]=Firefox Web Browser +X-GNOME-FullName[uz]=Firefox Web Browser +X-GNOME-FullName[vi]=Trình duyệt Web Firefox +X-GNOME-FullName[xh]=Firefox Web Browser +X-GNOME-FullName[zh_CN]=Firefox 浏览器 +X-GNOME-FullName[zh_TW]=Firefox 網頁瀏覽器 Exec=firefox %u Icon=firefox Terminal=false @@ -49,227 +522,324 @@ Type=Application MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml;x-scheme-handler/http;x-scheme-handler/https; StartupNotify=true Categories=Network;WebBrowser; -Keywords=web;browser;internet; Actions=new-window;new-private-window;profile-manager-window; +# Activable desktop file crashes KDE so remove it for now +# DBusActivatable=true [Desktop Action new-window] -Name=Open a New Window -Name[ach]=Dirica manyen -Name[af]=Nuwe venster -Name[an]=Nueva finestra +Name=New Window +Name[ach]=New Window +Name[af]=New Window +Name[an]=New Window Name[ar]=نافذة جديدة -Name[as]=নতুন উইন্ডো -Name[ast]=Ventana nueva -Name[az]=Yeni Pəncərə +Name[ast]=New Window +Name[az]=New Window Name[be]=Новае акно Name[bg]=Нов прозорец -Name[bn_BD]=নতুন উইন্ডো (N) -Name[bn_IN]=নতুন উইন্ডো +Name[bn]=নতুন উইন্ডো Name[br]=Prenestr nevez -Name[brx]=गोदान उइन्ड'(N) Name[bs]=Novi prozor Name[ca]=Finestra nova -Name[cak]=K'ak'a' tzuwäch +Name[ca_valencia]=New Window +Name[cak]=K'ak'a' Tzuwäch Name[cs]=Nové okno Name[cy]=Ffenestr Newydd Name[da]=Nyt vindue Name[de]=Neues Fenster Name[dsb]=Nowe wokno Name[el]=Νέο παράθυρο +Name[en_CA]=New Window Name[en_GB]=New Window -Name[en_US]=New Window -Name[en_ZA]=New Window Name[eo]=Nova fenestro Name[es_AR]=Nueva ventana Name[es_CL]=Nueva ventana Name[es_ES]=Nueva ventana Name[es_MX]=Nueva ventana -Name[et]=Uus aken +Name[et]=New Window Name[eu]=Leiho berria Name[fa]=پنجره جدید‌ -Name[ff]=Henorde Hesere +Name[ff]=New Window Name[fi]=Uusi ikkuna Name[fr]=Nouvelle fenêtre +Name[fur]=Gnûf barcon Name[fy_NL]=Nij finster -Name[ga_IE]=Fuinneog Nua +Name[ga_IE]=New Window Name[gd]=Uinneag ùr Name[gl]=Nova xanela Name[gn]=Ovetã pyahu -Name[gu_IN]=નવી વિન્ડો +Name[gu_IN]=New Window Name[he]=חלון חדש -Name[hi_IN]=नया विंडो +Name[hi_IN]=New Window Name[hr]=Novi prozor Name[hsb]=Nowe wokno Name[hu]=Új ablak -Name[hy_AM]=Նոր Պատուհան +Name[hy_AM]=Նոր պատուհան +Name[ia]=Nove fenestra Name[id]=Jendela Baru Name[is]=Nýr gluggi Name[it]=Nuova finestra Name[ja]=新しいウィンドウ -Name[ja_JP-mac]=新規ウインドウ Name[ka]=ახალი ფანჯარა +Name[kab]=Asfaylu amaynut Name[kk]=Жаңа терезе -Name[km]=បង្អួច​​​ថ្មី -Name[kn]=ಹೊಸ ಕಿಟಕಿ +Name[km]=New Window +Name[kn]=New Window Name[ko]=새 창 -Name[kok]=नवें जनेल -Name[ks]=نئئ وِنڈو -Name[lij]=Neuvo barcon -Name[lo]=ຫນ້າຕ່າງໃຫມ່ -Name[lt]=Naujas langas -Name[ltg]=Jauns lūgs +Name[lij]=Neuvo Barcon +Name[lt]=New Window Name[lv]=Jauns logs -Name[mai]=नव विंडो -Name[mk]=Нов прозорец -Name[ml]=പുതിയ ജാലകം -Name[mr]=नवीन पटल -Name[ms]=Tetingkap Baru -Name[my]=ဝင်းဒိုးအသစ် +Name[mk]=New Window +Name[mr]=New Window +Name[ms]=New Window +Name[my]=New Window Name[nb_NO]=Nytt vindu Name[ne_NP]=नयाँ सञ्झ्याल Name[nl]=Nieuw venster Name[nn_NO]=Nytt vindauge -Name[or]=ନୂତନ ୱିଣ୍ଡୋ +Name[oc]=Fenèstra novèla Name[pa_IN]=ਨਵੀਂ ਵਿੰਡੋ Name[pl]=Nowe okno Name[pt_BR]=Nova janela Name[pt_PT]=Nova janela Name[rm]=Nova fanestra -Name[ro]=Fereastră nouă +Name[ro]=New Window Name[ru]=Новое окно -Name[sat]=नावा विंडो (N) -Name[si]=නව කවුළුවක් +Name[sat]=ᱱᱟᱶᱟ ᱣᱤᱱᱰᱳ +Name[sc]=Ventana noa +Name[sco]=New Window +Name[si]=නව කවුළුව Name[sk]=Nové okno +Name[skr]=نویں ونڈو Name[sl]=Novo okno -Name[son]=Zanfun taaga +Name[son]=New Window Name[sq]=Dritare e Re Name[sr]=Нови прозор Name[sv_SE]=Nytt fönster -Name[ta]=புதிய சாளரம் -Name[te]=కొత్త విండో +Name[szl]=New Window +Name[ta]=New Window +Name[te]=కొత్త కిటికీ +Name[tg]=Равзанаи нав Name[th]=หน้าต่างใหม่ +Name[tl]=New Window Name[tr]=Yeni pencere -Name[tsz]=Eraatarakua jimpani +Name[trs]=Bēntanâ nākàa Name[uk]=Нове вікно -Name[ur]=نیا دریچہ -Name[uz]=Yangi oyna +Name[ur]=New Window +Name[uz]=New Window Name[vi]=Cửa sổ mới -Name[wo]=Palanteer bu bees -Name[xh]=Ifestile entsha +Name[xh]=New Window Name[zh_CN]=新建窗口 Name[zh_TW]=開新視窗 Exec=firefox --new-window %u [Desktop Action new-private-window] -Name=Open a New Private Window -Name[ach]=Dirica manyen me mung -Name[af]=Nuwe privaatvenster -Name[an]=Nueva finestra privada +Name=New Private Window +Name[ach]=New Private Window +Name[af]=New Private Window +Name[an]=New Private Window Name[ar]=نافذة خاصة جديدة -Name[as]=নতুন ব্যক্তিগত উইন্ডো -Name[ast]=Ventana privada nueva -Name[az]=Yeni Məxfi Pəncərə -Name[be]=Новае акно адасаблення -Name[bg]=Нов прозорец за поверително сърфиране -Name[bn_BD]=নতুন ব্যক্তিগত উইন্ডো -Name[bn_IN]=নতুন ব্যক্তিগত উইন্ডো -Name[br]=Prenestr merdeiñ prevez nevez -Name[brx]=गोदान प्राइभेट उइन्ड' +Name[ast]=New Private Window +Name[az]=New Private Window +Name[be]=Новае прыватнае акно +Name[bg]=Нов личен прозорец +Name[bn]=নতুন ব্যক্তিগত উইন্ডো +Name[br]=Prenestr prevez nevez Name[bs]=Novi privatni prozor Name[ca]=Finestra privada nova -Name[cak]=K'ak'a' ichinan tzuwäch +Name[ca_valencia]=New Private Window +Name[cak]=K'ak'a' Ichinan Tzuwäch Name[cs]=Nové anonymní okno Name[cy]=Ffenestr Breifat Newydd Name[da]=Nyt privat vindue Name[de]=Neues privates Fenster Name[dsb]=Nowe priwatne wokno -Name[el]=Νέο παράθυρο ιδιωτικής περιήγησης +Name[el]=Νέο ιδιωτικό παράθυρο +Name[en_CA]=New Private Window Name[en_GB]=New Private Window -Name[en_US]=New Private Window -Name[en_ZA]=New Private Window Name[eo]=Nova privata fenestro Name[es_AR]=Nueva ventana privada Name[es_CL]=Nueva ventana privada Name[es_ES]=Nueva ventana privada Name[es_MX]=Nueva ventana privada -Name[et]=Uus privaatne aken +Name[et]=New Private Window Name[eu]=Leiho pribatu berria Name[fa]=پنجره ناشناس جدید -Name[ff]=Henorde Suturo Hesere +Name[ff]=New Private Window Name[fi]=Uusi yksityinen ikkuna -Name[fr]=Nouvelle fenêtre de navigation privée +Name[fr]=Nouvelle fenêtre privée +Name[fur]=Gnûf barcon privât Name[fy_NL]=Nij priveefinster -Name[ga_IE]=Fuinneog Nua Phríobháideach +Name[ga_IE]=New Private Window Name[gd]=Uinneag phrìobhaideach ùr Name[gl]=Nova xanela privada Name[gn]=Ovetã ñemi pyahu -Name[gu_IN]=નવી ખાનગી વિન્ડો +Name[gu_IN]=New Private Window Name[he]=חלון פרטי חדש -Name[hi_IN]=नयी निजी विंडो +Name[hi_IN]=New Private Window Name[hr]=Novi privatni prozor Name[hsb]=Nowe priwatne wokno Name[hu]=Új privát ablak -Name[hy_AM]=Սկսել Գաղտնի դիտարկում +Name[hy_AM]=Նոր գաղտնի պատուհան +Name[ia]=Nove fenestra private Name[id]=Jendela Mode Pribadi Baru Name[is]=Nýr huliðsgluggi Name[it]=Nuova finestra anonima Name[ja]=新しいプライベートウィンドウ -Name[ja_JP-mac]=新規プライベートウインドウ Name[ka]=ახალი პირადი ფანჯარა +Name[kab]=Asfaylu amaynut n tunigin tusligt Name[kk]=Жаңа жекелік терезе -Name[km]=បង្អួច​ឯកជន​ថ្មី -Name[kn]=ಹೊಸ ಖಾಸಗಿ ಕಿಟಕಿ -Name[ko]=새 사생활 보호 모드 -Name[kok]=नवो खाजगी विंडो -Name[ks]=نْو پرایوٹ وینڈو& -Name[lij]=Neuvo barcon privou -Name[lo]=ເປີດຫນ້າຕ່າງສວນຕົວຂື້ນມາໃຫມ່ -Name[lt]=Naujas privataus naršymo langas -Name[ltg]=Jauns privatais lūgs +Name[km]=New Private Window +Name[kn]=New Private Window +Name[ko]=새 사생활 보호 창 +Name[lij]=Neuvo Barcon Privòu +Name[lt]=New Private Window Name[lv]=Jauns privātais logs -Name[mai]=नया निज विंडो (W) -Name[mk]=Нов приватен прозорец -Name[ml]=പുതിയ സ്വകാര്യ ജാലകം -Name[mr]=नवीन वैयक्तिक पटल -Name[ms]=Tetingkap Persendirian Baharu +Name[mk]=New Private Window +Name[mr]=New Private Window +Name[ms]=New Private Window Name[my]=New Private Window Name[nb_NO]=Nytt privat vindu Name[ne_NP]=नयाँ निजी सञ्झ्याल Name[nl]=Nieuw privévenster Name[nn_NO]=Nytt privat vindauge -Name[or]=ନୂତନ ବ୍ୟକ୍ତିଗତ ୱିଣ୍ଡୋ +Name[oc]=Fenèstra privada novèla Name[pa_IN]=ਨਵੀਂ ਪ੍ਰਾਈਵੇਟ ਵਿੰਡੋ Name[pl]=Nowe okno prywatne Name[pt_BR]=Nova janela privativa Name[pt_PT]=Nova janela privada Name[rm]=Nova fanestra privata -Name[ro]=Fereastră privată nouă +Name[ro]=New Private Window Name[ru]=Новое приватное окно -Name[sat]=नावा निजेराक् विंडो (W ) -Name[si]=නව පුද්ගලික කවුළුව (W) -Name[sk]=Nové okno v režime Súkromné prehliadanie +Name[sat]=ᱱᱟᱶᱟ ᱱᱤᱡᱮᱨᱟᱜ ᱣᱤᱱᱰᱳ +Name[sc]=Ventana privada noa +Name[sco]=New Private Window +Name[si]=නව පෞද්. කවුළුව +Name[sk]=Nové súkromné okno +Name[skr]=نویں نجی ونڈو Name[sl]=Novo zasebno okno -Name[son]=Sutura zanfun taaga +Name[son]=New Private Window Name[sq]=Dritare e Re Private -Name[sr]=Нови приватан прозор +Name[sr]=Нови приватни прозор Name[sv_SE]=Nytt privat fönster -Name[ta]=புதிய தனிப்பட்ட சாளரம் -Name[te]=కొత్త ఆంతరంగిక విండో +Name[szl]=New Private Window +Name[ta]=New Private Window +Name[te]=కొత్త ఆంతరంగిక కిటికీ +Name[tg]=Равзанаи хусусии нав Name[th]=หน้าต่างส่วนตัวใหม่ +Name[tl]=New Private Window Name[tr]=Yeni gizli pencere -Name[tsz]=Juchiiti eraatarakua jimpani +Name[trs]=Bēntanâ huì nākàa Name[uk]=Приватне вікно -Name[ur]=نیا نجی دریچہ -Name[uz]=Yangi maxfiy oyna +Name[ur]=New Private Window +Name[uz]=New Private Window Name[vi]=Cửa sổ riêng tư mới -Name[wo]=Panlanteeru biir bu bees -Name[xh]=Ifestile yangasese entsha -Name[zh_CN]=新建隐私浏览窗口 -Name[zh_TW]=新增隱私視窗 +Name[xh]=New Private Window +Name[zh_CN]=新建隐私窗口 +Name[zh_TW]=開新隱私視窗 Exec=firefox --private-window %u -[Desktop Action profile-manager-window] -Name=Open the Profile Manager -Name[cs]=Správa profilů +[Desktop Action open-profile-manager] +Name=Open Profile Manager +Name[ach]=Open Profile Manager +Name[af]=Open Profile Manager +Name[an]=Open Profile Manager +Name[ar]=افتح مدير الملف الشخصي +Name[ast]=Open Profile Manager +Name[az]=Open Profile Manager +Name[be]=Адкрыць менеджар профіляў +Name[bg]=Отваряне на мениджъра на профили +Name[bn]=Open Profile Manager +Name[br]=Digeriñ an ardoer aeladoù +Name[bs]=Otvori Menadžera profila +Name[ca]=Obre el gestor de perfils +Name[ca_valencia]=Open Profile Manager +Name[cak]=Open Profile Manager +Name[cs]=Otevřete Správce profilů +Name[cy]=Agorwch y Rheolwr Proffil +Name[da]=Åbn profilhåndtering Name[de]=Profilverwaltung öffnen +Name[dsb]=Profilowy zastojnik wócyniś +Name[el]=Άνοιγμα Διαχείρισης προφίλ +Name[en_CA]=Open Profile Manager +Name[en_GB]=Open Profile Manager +Name[eo]=Malfermi administranton de profiloj +Name[es_AR]=Abrir administrador de perfiles +Name[es_CL]=Abrir administrador de perfiles +Name[es_ES]=Abrir administrador de perfiles +Name[es_MX]=Abrir administrador de perfiles +Name[et]=Open Profile Manager +Name[eu]=Ireki profilen kudeatzailea +Name[fa]=Open Profile Manager +Name[ff]=Open Profile Manager +Name[fi]=Avaa profiilien hallinta +Name[fr]=Ouvrir le gestionnaire de profils +Name[fur]=Vierç gjestôr profîi +Name[fy_NL]=Profylbehearder iepenje +Name[ga_IE]=Open Profile Manager +Name[gd]=Fosgail manaidsear nam pròifilean +Name[gl]=Abrir o xestor de perfís +Name[gn]=Embojuruja mba’ete ñangarekoha +Name[gu_IN]=Open Profile Manager +Name[he]=פתיחת מנהל הפרופילים +Name[hi_IN]=Open Profile Manager +Name[hr]=Otvori upravljač profila +Name[hsb]=Zrjadowak profilow wočinić +Name[hu]=Profilkezelő megnyitása +Name[hy_AM]=Բացեք պրոֆիլի կառավարիչը +Name[ia]=Aperir le gestor de profilo +Name[id]=Buka Pengelola Profil +Name[is]=Opna umsýslu notandasniða +Name[it]=Apri gestore profili +Name[ja]=プロファイルマネージャーを開く +Name[ka]=პროფილის მმართველის გახსნა +Name[kab]=Ldi amsefrak n umaɣnu +Name[kk]=Профильдер бақарушысын ашу +Name[km]=Open Profile Manager +Name[kn]=Open Profile Manager +Name[ko]=프로필 관리자 열기 +Name[lij]=Open Profile Manager +Name[lt]=Open Profile Manager +Name[lv]=Atvērt profilu pārvaldnieku +Name[mk]=Open Profile Manager +Name[mr]=Open Profile Manager +Name[ms]=Open Profile Manager +Name[my]=Open Profile Manager +Name[nb_NO]=Åpne profilbehandler +Name[ne_NP]=Open Profile Manager +Name[nl]=Profielbeheerder openen +Name[nn_NO]=Opne profilhandsaming +Name[oc]=Dobrir lo gestionari de perfils +Name[pa_IN]=ਪਰੋਫ਼ਾਈਲ ਮੈਨੇਜਰ ਖੋਲ੍ਹੋ +Name[pl]=Menedżer profili +Name[pt_BR]=Abrir gerenciador de perfis +Name[pt_PT]=Abrir o Gestor de Perfis +Name[rm]=Avrir l'administraziun da profils +Name[ro]=Open Profile Manager +Name[ru]=Открыть менеджер профилей +Name[sat]=ᱢᱮᱫᱦᱟᱸ ᱢᱮᱱᱮᱡᱚᱨ ᱠᱷᱩᱞᱟᱹᱭ ᱢᱮ +Name[sc]=Aberi su gestore de profilos +Name[sco]=Open Profile Manager +Name[si]=පැතිකඩ කළමනාකරු අරින්න +Name[sk]=Otvoriť Správcu profilov +Name[skr]=پروفائل منیجر کھولو +Name[sl]=Odpri upravitelja profilov +Name[son]=Open Profile Manager +Name[sq]=Hapni Përgjegjës Profilesh +Name[sr]=Отворите управљач профила +Name[sv_SE]=Öppna Profilhanteraren +Name[szl]=Open Profile Manager +Name[ta]=Open Profile Manager +Name[te]=Open Profile Manager +Name[tg]=Кушодани мудири профилҳо +Name[th]=เปิดตัวจัดการโปรไฟล์ +Name[tl]=Open Profile Manager +Name[tr]=Profil yöneticisini aç +Name[trs]=Sa nīkāj ñu’ūnj nej perfî huā nì’nï̀nj ïn +Name[uk]=Відкрити менеджер профілів +Name[ur]=Open Profile Manager +Name[uz]=Open Profile Manager +Name[vi]=Mở trình quản lý hồ sơ +Name[xh]=Open Profile Manager +Name[zh_CN]=打开配置文件管理器 +Name[zh_TW]=開啟設定檔管理員 Exec=firefox --ProfileManager diff --git a/firefox.sh.in b/firefox.sh.in index 76df06b..7d3faed 100644 --- a/firefox.sh.in +++ b/firefox.sh.in @@ -64,23 +64,8 @@ MOZ_DIST_BIN="$MOZ_LIB_DIR/firefox" MOZ_LANGPACKS_DIR="$MOZ_DIST_BIN/langpacks" MOZ_EXTENSIONS_PROFILE_DIR="$HOME/.mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}" MOZ_PROGRAM="$MOZ_DIST_BIN/$MOZ_FIREFOX_FILE" -MOZ_LAUNCHER="$MOZ_DIST_BIN/run-mozilla.sh" GETENFORCE_FILE="/usr/sbin/getenforce" -## -## Enable Wayland backend? -## -if ! [ $MOZ_DISABLE_WAYLAND ] && [ "$WAYLAND_DISPLAY" ]; then - if [ "$XDG_CURRENT_DESKTOP" == "GNOME" ]; then - export MOZ_ENABLE_WAYLAND=1 - fi -## Enable Wayland on KDE/Sway -## - if [ "$XDG_SESSION_TYPE" == "wayland" ]; then - export MOZ_ENABLE_WAYLAND=1 - fi -fi - ## ## Use D-Bus remote exclusively when there's Wayland display. ## @@ -123,15 +108,14 @@ export MOZ_PLUGIN_PATH export MOZ_APP_LAUNCHER="/__PREFIX__/bin/firefox" ## -## Set FONTCONFIG_PATH for Xft/fontconfig +## We want Firefox to use Openh264 provided by Fedora. ## -FONTCONFIG_PATH="/etc/fonts:${MOZILLA_FIVE_HOME}/res/Xft" -export FONTCONFIG_PATH - +## We used to configure it here but It's set by /etc/profile.d/gmpopenh264.sh +## script from mozilla-openh264 package now. Let's keep it here just +## for the record. ## -## We want Firefox to use Openh264 provided by Fedora +## export MOZ_GMP_PATH=$MOZ_LIB_DIR/mozilla/plugins/gmp-gmpopenh264/system-installed ## -export MOZ_GMP_PATH=$MOZ_LIB_DIR/mozilla/plugins/gmp-gmpopenh264/system-installed ## ## In order to better support certain scripts (such as Indic and some CJK @@ -146,21 +130,10 @@ export MOZ_GMP_PATH=$MOZ_LIB_DIR/mozilla/plugins/gmp-gmpopenh264/system-installe # export MOZ_DISABLE_PANGO # -## -## Disable the GNOME crash dialog, Moz has it's own -## -GNOME_DISABLE_CRASH_DIALOG=1 -export GNOME_DISABLE_CRASH_DIALOG - -## -## Disable the SLICE allocator (rhbz#1014858) -## -export G_SLICE=always-malloc - ## ## Enable Xinput2 (mozbz#1207973) ## -export MOZ_USE_XINPUT2=1 +export MOZ_USE_XINPUT2=${MOZ_USE_XINPUT2-1} # OK, here's where all the real work gets done @@ -193,8 +166,8 @@ fi # When Firefox is not running, restore SELinux labels for profile files # (rhbz#1731371) if [ $MOZILLA_DOWN -ne 0 ]; then - if [ -x $GETENFORCE_FILE ] && [ `getenforce` != "Disabled" ]; then - (restorecon -vr ~/.mozilla/firefox/* &) + if [ -x $GETENFORCE_FILE ] && [ `$GETENFORCE_FILE` != "Disabled" ]; then + (restorecon -vr ~/.mozilla/firefox/*/gmp-widevinecdm/* &) fi fi @@ -230,8 +203,17 @@ if [ $MOZILLA_DOWN -ne 0 ]; then if [ -h $MOZ_LANGPACKS_DIR/$langpack ]; then langpack=`readlink $MOZ_LANGPACKS_DIR/$langpack` fi - ln -s $MOZ_LANGPACKS_DIR/$langpack \ - $MOZ_EXTENSIONS_PROFILE_DIR/$langpack + if [ -e "/run/ostree-booted" ]; then + # Files on Silverblue has file create time set to 0, + # so in case the langpack is updated Firefox does not + # check for changes because it compares the file + # creation date to do so. + cp -f $MOZ_LANGPACKS_DIR/$langpack \ + $MOZ_EXTENSIONS_PROFILE_DIR/$langpack + else + ln -s $MOZ_LANGPACKS_DIR/$langpack \ + $MOZ_EXTENSIONS_PROFILE_DIR/$langpack + fi echo $MOZ_EXTENSIONS_PROFILE_DIR/$langpack > $FEDORA_LANGPACK_CONFIG return 0 fi @@ -245,34 +227,11 @@ fi NSS_SSL_CBC_RANDOM_IV=${NSS_SSL_CBC_RANDOM_IV-1} export NSS_SSL_CBC_RANDOM_IV -# Prepare command line arguments -script_args="" -pass_arg_count=0 -while [ $# -gt $pass_arg_count ] -do - case "$1" in - -g | --debug) - script_args="$script_args -g" - debugging=1 - shift - ;; - -d | --debugger) - if [ $# -gt 1 ]; then - script_args="$script_args -d $2" - shift 2 - else - shift - fi - ;; - *) - # Move the unrecognized argument to the end of the list. - arg="$1" - shift - set -- "$@" "$arg" - pass_arg_count=`expr $pass_arg_count + 1` - ;; - esac -done +# MOZ_APP_REMOTINGNAME links Firefox with desktop file name +if [ -z "$MOZ_APP_REMOTINGNAME" ] +then + export MOZ_APP_REMOTINGNAME=__APP_NAME__ +fi # Flatpak specific environment variables %FLATPAK_ENV_VARS% @@ -284,7 +243,7 @@ export MOZ_ALLOW_DOWNGRADE=1 debugging=0 if [ $debugging = 1 ] then - echo $MOZ_LAUNCHER $script_args $MOZ_PROGRAM "$@" + echo $MOZ_PROGRAM "$@" fi -exec $MOZ_LAUNCHER $script_args $MOZ_PROGRAM "$@" +exec $MOZ_PROGRAM "$@" diff --git a/firefox.spec b/firefox.spec index 3206448..b91a17e 100644 --- a/firefox.spec +++ b/firefox.spec @@ -2,6 +2,10 @@ # when building locally to reduce build time. %global release_build 1 +# Excluded due to https://bugzilla.mozilla.org/show_bug.cgi?id=1792159 +# https://bugzilla.redhat.com/show_bug.cgi?id=2129720 +ExcludeArch: i686 + # Run Mozilla test suite as a part of compile rpm section. Turn off when # building locally and don't want to spend 24 hours waiting for results. %global run_firefox_tests 0 @@ -17,35 +21,48 @@ # as the build is *very* slow. %global debug_build 0 -%global system_nss 1 -%global build_with_asan 0 -%global test_on_wayland 1 +# See rhbz#2134527 - Use portal Gtk file dialog +# Disabled due to various issues now. +%global use_xdg_file_portal 0 -%if "%{toolchain}" == "clang" -%global build_with_clang 1 +# PipeWire camera is needed for IPU6 camera support in Fedora 41+ +# https://fedoraproject.org/wiki/Changes/IPU6_Camera_support +%if 0%{?fedora} >= 41 +%global use_pipewire_camera 1 %else -%global build_with_clang 0 +%global use_pipewire_camera 0 %endif -# There are still build problems on s390x, see -# https://koji.fedoraproject.org/koji/taskinfo?taskID=55048351 -# https://bugzilla.redhat.com/show_bug.cgi?id=1897522 -ExcludeArch: s390x - -# Disabled due to -# https://bugzilla.redhat.com/show_bug.cgi?id=1966949 -%if 0%{?fedora} > 33 -ExcludeArch: armv7hl +%global system_nss 1 +%global system_libevent 1 +%global build_with_asan 0 +%ifarch x86_64 %{ix86} +%global enable_replace_malloc 1 +%else +%global enable_replace_malloc 0 %endif -# Disabled due to -# https://bugzilla.redhat.com/show_bug.cgi?id=2019160 -%if 0%{?fedora} == 33 -ExcludeArch: aarch64 +# wasi_sdk 25 is not compatible with llvm 18 +%if 0%{?fedora} <= 40 + %bcond wasi_sdk 0 +%else + %ifarch s390x + %bcond wasi_sdk 0 + %else + %bcond wasi_sdk 1 + %endif %endif -%ifarch armv7hl -%global create_debuginfo 0 +%bcond build_with_clang 0 +%if %{with build_with_clang} +%global toolchain clang +%else +%global toolchain gcc +%endif + +%global gnome_shell_search_provider 0 +%if 0%{?fedora} >= 40 +%global gnome_shell_search_provider 1 %endif # Temporary disabled due to @@ -67,15 +84,21 @@ ExcludeArch: aarch64 %endif %global system_ffi 1 -%ifarch armv7hl +%global system_av1 0 %global system_libvpx 1 -%else -%global system_libvpx 0 -%endif -%global hardened_build 1 %global system_jpeg 1 -%global disable_elfhack 1 +%global system_pixman 1 +%global system_webp 1 +%global system_drm 1 +%global system_gbm 1 +%global system_pipewire 1 +# Bundled cbindgen makes build slow. +# Enable only if system cbindgen is not available. +%if 0%{?rhel} %global use_bundled_cbindgen 1 +%else +%global use_bundled_cbindgen 1 +%endif %if %{debug_build} %global release_build 0 %endif @@ -91,25 +114,25 @@ ExcludeArch: aarch64 %global build_with_pgo 0 %endif # Big endian platforms -%ifarch ppc64 s390x +%ifarch s390x %global big_endian 1 %endif %if 0%{?build_with_pgo} -%global use_xvfb 1 +%global use_xvfb 0 %global build_tests 1 %endif %if 0%{?run_firefox_tests} -%global use_xvfb 1 +%global use_xvfb 0 %global build_tests 1 %endif %global launch_wayland_compositor 0 -%if %{build_with_pgo} && %{test_on_wayland} +%if %{build_with_pgo} %global launch_wayland_compositor 1 %endif -%if %{run_firefox_tests} && %{test_on_wayland} +%if %{run_firefox_tests} %global launch_wayland_compositor 1 %endif @@ -119,14 +142,21 @@ ExcludeArch: aarch64 %global cairo_version 1.13.1 %global freetype_version 2.1.9 %global libnotify_version 0.7.0 +%if %{?system_av1} +%global aom_version 1.0.0 +%global dav1d_version 1.0.0 +%endif %if %{?system_libvpx} -%global libvpx_version 1.8.2 +%global libvpx_version 1.10.0 +%endif +%if %{?system_webp} +%global libwebp_version 1.1.0 %endif %if %{?system_nss} -%global nspr_version 4.32 +%global nspr_version 4.37 %global nspr_build_version %{nspr_version} -%global nss_version 3.78 +%global nss_version 3.119 %global nss_build_version %{nss_version} %endif @@ -139,10 +169,14 @@ ExcludeArch: aarch64 %bcond_without langpacks +%if %{with langpacks} +%bcond_without langpacks_subpkg +%endif + %if !%{release_build} %global pre_tag .npgo %endif -%if %{build_with_clang} +%if %{with build_with_clang} %global pre_tag .clang %endif %if %{build_with_asan} @@ -160,17 +194,24 @@ ExcludeArch: aarch64 %global __provides_exclude_from ^%{mozappdir} %global __requires_exclude ^(%%(find %{buildroot}%{mozappdir} -name '*.so' | xargs -n1 basename | sort -u | paste -s -d '|' -)) +%undefine _package_note_flags +# for https://bugzilla.redhat.com/show_bug.cgi?id=2184553 +%global _package_note_status 0 + Summary: Mozilla Firefox Web browser Name: firefox -Version: 101.0 +Version: 147.0 Release: 1%{?pre_tag}%{?dist} URL: https://www.mozilla.org/firefox/ -License: MPLv1.1 or GPLv2+ or LGPLv2+ +# Automatically converted from old format: MPLv1.1 or GPLv2+ or LGPLv2+ - review is highly recommended. +License: LicenseRef-Callaway-MPLv1.1 OR GPL-2.0-or-later OR LicenseRef-Callaway-LGPLv2+ Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz %if %{with langpacks} -Source1: firefox-langpacks-%{version}%{?pre_version}-20220530.tar.xz +Source1: firefox-langpacks-%{version}%{?pre_version}-20260106.tar.xz %endif Source2: cbindgen-vendor.tar.xz +Source3: dump_syms-vendor.tar.xz +Source4: wasm-component-ld-vendor.tar.xz Source10: firefox-mozconfig Source12: firefox-redhat-default-prefs.js Source20: firefox.desktop @@ -178,7 +219,7 @@ Source21: firefox.sh.in Source23: firefox.1 Source24: mozilla-api-key Source25: firefox-symbolic.svg -Source26: distribution.ini +Source26: distribution.ini.in Source27: google-api-key Source28: firefox-wayland.sh.in Source29: firefox-wayland.desktop @@ -186,7 +227,7 @@ Source30: firefox-x11.sh.in Source31: firefox-x11.desktop Source32: node-stdout-nonblocking-wrapper Source33: firefox.appdata.xml.in -Source34: firefox-search-provider.ini +Source34: org.mozilla.firefox.search-provider.ini Source35: google-loc-api-key Source37: mochitest-python.tar.gz Source38: print_results @@ -197,59 +238,48 @@ Source42: psummary Source43: print_failures Source44: print-error-reftest Source45: run-wayland-compositor +Source46: org.mozilla.firefox.SearchProvider.service +Source47: org.mozilla.firefox.desktop +Source48: org.mozilla.firefox.appdata.xml.in +Source49: wasi.patch.template +# Created by: +# git clone --recursive https://github.com/WebAssembly/wasi-sdk.git +# cd wasi-sdk && git-archive-all --force-submodules wasi-sdk-25.tar.gz +Source50: wasi-sdk-25.tar.gz # Build patches -Patch3: mozilla-build-arm.patch -Patch25: rhbz-1219542-s390-build.patch -Patch32: build-rust-ppc64le.patch -Patch35: build-ppc-jit.patch -# Fixing missing cacheFlush when JS_CODEGEN_NONE is used (s390x) -Patch38: build-cacheFlush-missing.patch Patch40: build-aarch64-skia.patch -Patch41: build-disable-elfhack.patch Patch44: build-arm-libopus.patch -Patch46: firefox-nss-version.patch -Patch47: fedora-shebang-build.patch -Patch49: build-arm-libaom.patch Patch53: firefox-gcc-build.patch -Patch54: mozilla-1669639.patch -Patch55: firefox-testing.patch -Patch61: firefox-glibc-dynstack.patch -Patch62: build-python.patch Patch71: 0001-GLIBCXX-fix-for-GCC-12.patch -Patch73: D147266.diff -Patch74: D147267.diff +Patch78: firefox-i686-build.patch +Patch79: firefox-gcc-13-build.patch +Patch80: wasi.patch +Patch81: firefox-gcc-15.0-s390.patch +Patch82: build-c11-threads-avail.patch +Patch83: build-seccomp.patch -# Test patches -# Generate without context by -# GENDIFF_DIFF_ARGS=-U0 gendiff firefox-xxxx .firefox-tests-xpcshell -# GENDIFF_DIFF_ARGS=-U0 gendiff firefox-xxxx .firefox-tests-reftest -Patch100: firefox-tests-xpcshell.patch -Patch101: firefox-tests-reftest.patch -Patch102: firefox-tests-xpcshell-freeze.patch # Fedora specific patches Patch215: firefox-enable-addons.patch Patch219: rhbz-1173156.patch -Patch224: mozilla-1170092.patch #ARM run-time patch Patch226: rhbz-1354671.patch Patch228: disable-openh264-download.patch Patch229: firefox-nss-addon-hack.patch +Patch231: fedora-customization.patch +Patch241: 0025-Add-KDE-integration-to-Firefox-toolkit-parts.patch +Patch242: 0026-Add-KDE-integration-to-Firefox.patch # Upstream patches -Patch402: mozilla-1196777.patch -Patch407: mozilla-1667096.patch -Patch408: mozilla-1663844.patch -Patch415: mozilla-1670333.patch -Patch418: mozilla-1767946-profilemanagersize.patch +Patch400: mozilla-1196777.patch +Patch401: mozilla-1667096.patch # PGO/LTO patches Patch600: pgo.patch Patch602: mozilla-1516803.patch +Patch603: firefox-gcc-always-inline.patch -# Backported WebRTC changes for PipeWire/Wayland screen sharing support -Patch1000: libwebrtc-screen-cast-sync.patch %if %{?system_nss} BuildRequires: pkgconfig(nspr) >= %{nspr_version} @@ -260,11 +290,13 @@ BuildRequires: pkgconfig(libpng) %if %{?system_jpeg} BuildRequires: libjpeg-devel %endif +%if %{?system_pixman} +BuildRequires: pixman-devel +%endif BuildRequires: zip BuildRequires: bzip2-devel BuildRequires: pkgconfig(zlib) BuildRequires: pkgconfig(gtk+-3.0) -BuildRequires: pkgconfig(gtk+-2.0) BuildRequires: pkgconfig(krb5) BuildRequires: pkgconfig(pango) BuildRequires: pkgconfig(freetype2) >= %{freetype_version} @@ -276,21 +308,38 @@ BuildRequires: pkgconfig(dri) BuildRequires: pkgconfig(libcurl) BuildRequires: pkgconfig(alsa) BuildRequires: dbus-glib-devel +%if %{?system_av1} +BuildRequires: pkgconfig(aom) >= %{aom_version} +BuildRequires: pkgconfig(dav1d) >= %{dav1d_version} +%endif %if %{?system_libvpx} BuildRequires: libvpx-devel >= %{libvpx_version} %endif +%if %{?system_webp} +BuildRequires: pkgconfig(libwebp) >= %{libwebp_version} +BuildRequires: pkgconfig(libwebpdemux) >= %{libwebp_version} +%endif BuildRequires: autoconf213 BuildRequires: pkgconfig(libpulse) -BuildRequires: yasm BuildRequires: llvm BuildRequires: llvm-devel BuildRequires: clang BuildRequires: clang-libs -%if %{build_with_clang} +%if %{with build_with_clang} || %{with wasi_sdk} BuildRequires: lld %endif +%if %{?system_drm} +BuildRequires: libdrm-devel +%endif + +%if %{?system_gbm} +BuildRequires: mesa-libgbm-devel +%endif + +%if %{?system_pipewire} BuildRequires: pipewire-devel +%endif %if !0%{?use_bundled_cbindgen} BuildRequires: cbindgen @@ -304,7 +353,13 @@ BuildRequires: icu %endif Requires: mozilla-filesystem -Recommends: mozilla-openh264 >= 2.1.1 +Requires: (mozilla-openh264 >= 2.1.1 if openh264) +%if %{with langpacks_subpkg} +Recommends: firefox-langpacks = %{version}-%{release} +%else +Obsoletes: firefox-langpacks < %{version}-%{release} +%endif +Recommends: ffmpeg-free Recommends: libva Requires: p11-kit-trust Requires: pciutils-libs @@ -312,11 +367,18 @@ Requires: pciutils-libs Requires: nspr >= %{nspr_build_version} Requires: nss >= %{nss_build_version} %endif +%if %{?system_libevent} +BuildRequires: pkgconfig(libevent) +%endif BuildRequires: python3-devel BuildRequires: python3-setuptools +BuildRequires: python3.11-devel %if !0%{?flatpak} Requires: u2f-hidraw-policy %endif +%if %{?use_xdg_file_portal} +Requires: xdg-desktop-portal +%endif BuildRequires: desktop-file-utils %if !0%{?flatpak} @@ -338,7 +400,7 @@ BuildRequires: libasan-static %endif BuildRequires: perl-interpreter BuildRequires: fdk-aac-free-devel -%if 0%{?test_on_wayland} +%if 0%{?launch_wayland_compositor} BuildRequires: mutter BuildRequires: gsettings-desktop-schemas BuildRequires: gnome-settings-daemon @@ -363,10 +425,7 @@ BuildRequires: liberation-mono-fonts BuildRequires: liberation-sans-fonts BuildRequires: liberation-serif-fonts # ---------------------------------- -# Missing on f32 -%if 0%{?fedora} > 33 BuildRequires: google-carlito-fonts -%endif BuildRequires: google-droid-sans-fonts BuildRequires: google-noto-fonts-common BuildRequires: google-noto-cjk-fonts-common @@ -385,10 +444,7 @@ BuildRequires: lohit-tamil-fonts BuildRequires: lohit-telugu-fonts # ---------------------------------- BuildRequires: paktype-naskh-basic-fonts -# faild to build in Koji / f32 -%if 0%{?fedora} > 33 BuildRequires: pt-sans-fonts -%endif BuildRequires: smc-meera-fonts BuildRequires: stix-fonts BuildRequires: abattis-cantarell-fonts @@ -397,14 +453,70 @@ BuildRequires: xorg-x11-fonts-misc %endif BuildRequires: make BuildRequires: pciutils-libs +BuildRequires: mesa-libgbm-devel +BuildRequires: libproxy-devel +# Required for --enable-replace-malloc +%if %{enable_replace_malloc} +BuildRequires: libstdc++-static +%endif +%if %{with wasi_sdk} +BuildRequires: clang cmake ninja-build +%endif +Recommends: speech-dispatcher +Recommends: speech-dispatcher-utils + +%if %{with build_with_clang} +BuildRequires: compiler-rt +%endif Obsoletes: mozilla <= 37:1.7.13 Provides: webclient +# Don't ship firefox-x11 and firefox-wayland on Fedora 40. +# Wayland backend is considered as mature enough now. +# We need to use v-r in Obsoletes because new versions of this +# package keep being built in older releases, and we want to +# obsolete all of them when the user updates to F40+. +%if 0%{?fedora} >= 40 +Obsoletes: firefox-wayland < %{version}-%{release} +Obsoletes: firefox-x11 < %{version}-%{release} +%endif + %description Mozilla Firefox is an open-source web browser, designed for standards compliance, performance and portability. +%if %{with langpacks_subpkg} +%package langpacks +Summary: Firefox langpacks +Requires: %{name} = %{version}-%{release} +%description langpacks +The firefox-langpacks package contains all the localization +and translations langpack add-ons. +%files langpacks -f %{name}.lang +%dir %{langpackdir} +%endif + +%if %{enable_mozilla_crashreporter} +%global moz_debug_prefix %{_prefix}/lib/debug +%global moz_debug_dir %{moz_debug_prefix}%{mozappdir} +%global uname_m %(uname -m) +%global symbols_file_name %{name}-%{version}.en-US.%{_os}-%{uname_m}.crashreporter-symbols.zip +%global symbols_file_path %{moz_debug_dir}/%{symbols_file_name} +%global _find_debuginfo_opts %{limit_build -m 32768} -p %{symbols_file_path} -o debugcrashreporter.list +%global crashreporter_pkg_name mozilla-crashreporter-%{name}-debuginfo +%package -n %{crashreporter_pkg_name} +Summary: Debugging symbols used by Mozilla's crash reporter servers +%description -n %{crashreporter_pkg_name} +This package provides debug information for Firefox, for use by +Mozilla's crash reporter servers. If you are trying to locally +debug %{name}, you want to install %{name}-debuginfo instead. +%files -n %{crashreporter_pkg_name} -f debugcrashreporter.list +%else +%global _find_debuginfo_opts %{limit_build -m 32768} +%endif + +%if 0%{?fedora} < 40 %package x11 Summary: Firefox X11 launcher. Requires: %{name} @@ -424,6 +536,7 @@ to run Firefox explicitly on Wayland. %files wayland %{_bindir}/firefox-wayland %{_datadir}/applications/firefox-wayland.desktop +%endif %if 0%{?run_firefox_tests} %global testsuite_pkg_name %{name}-testresults @@ -441,69 +554,64 @@ This package contains results of tests executed during build. %prep %setup -q -n %{tarballdir} +%if %{with wasi_sdk} +%setup -q -T -D -a 50 +%endif # Build patches, can't change backup suffix from default because during build # there is a compare of config and js/config directories and .orig suffix is # ignored during this compare. -%ifarch s390 -%patch25 -p1 -b .rhbz-1219542-s390 +%patch -P40 -p1 -b .aarch64-skia +%patch -P44 -p1 -b .build-arm-libopus +%patch -P53 -p1 -b .firefox-gcc-build +%patch -P71 -p1 -b .0001-GLIBCXX-fix-for-GCC-12 +%patch -P78 -p1 -b .firefox-i686 +%patch -P79 -p1 -b .firefox-gcc-13-build +%patch -P81 -p1 -b .firefox-gcc-15.0-s390 +%if 0%{?fedora} >= 44 +%patch -P82 -p1 -b .build-c11-threads-avail +%patch -P83 -p1 -b .build-seccomp %endif -%patch40 -p1 -b .aarch64-skia -%if 0%{?disable_elfhack} -%patch41 -p1 -b .disable-elfhack -%endif -%patch3 -p1 -b .arm -%patch44 -p1 -b .build-arm-libopus -%patch47 -p1 -b .fedora-shebang -%patch49 -p1 -b .build-arm-libaom -%patch53 -p1 -b .firefox-gcc-build -%patch54 -p1 -b .1669639 -%patch71 -p1 -b .0001-GLIBCXX-fix-for-GCC-12 -%patch73 -p1 -b .D147266 -%patch74 -p1 -b .D147267 -# Test patches -#%patch100 -p1 -b .firefox-tests-xpcshell -#%patch101 -p1 -b .firefox-tests-reftest -%patch102 -p1 -b .firefox-tests-xpcshell-freeze +# We need to create the wasi.patch with the correct path to the wasm libclang_rt. +%if %{with wasi_sdk} +cat %{SOURCE49} | sed -e "s|LIBCLANG_RT_PLACEHOLDER|`pwd`/wasi-sdk-25/build/sysroot/install/wasi-resource-dir/lib/wasi/libclang_rt.builtins-wasm32.a|" > %{_sourcedir}/wasi.patch +%patch -P80 -p1 -b .wasi +%endif # Fedora patches -%patch215 -p1 -b .addons -%patch219 -p1 -b .rhbz-1173156 -%patch224 -p1 -b .1170092 +%patch -P215 -p1 -b .addons +%patch -P219 -p1 -b .rhbz-1173156 #ARM run-time patch %ifarch aarch64 -%patch226 -p1 -b .1354671 +%patch -P226 -p1 -b .1354671 %endif -%patch228 -p1 -b .disable-openh264-download -%patch229 -p1 -b .firefox-nss-addon-hack +%patch -P228 -p1 -b .disable-openh264-download +%patch -P229 -p1 -b .firefox-nss-addon-hack +%patch -P231 -p1 -b .fedora-customization -%patch402 -p1 -b .1196777 -%patch407 -p1 -b .1667096 -%patch408 -p1 -b .1663844 -%patch415 -p1 -b .1670333 -%patch418 -p1 -b .mozilla-1767946-profilemanagersize +%patch -P400 -p1 -b .1196777 +%patch -P401 -p1 -b .1667096 # PGO patches %if %{build_with_pgo} -%if !%{build_with_clang} -%patch600 -p1 -b .pgo -%patch602 -p1 -b .1516803 +%if !%{with build_with_clang} +%patch -P600 -p1 -b .pgo +%patch -P602 -p1 -b .1516803 %endif %endif +%patch -P603 -p1 -b .inline -%patch1000 -p1 -b .libwebrtc-screen-cast-sync - -%{__rm} -f .mozconfig -%{__cp} %{SOURCE10} .mozconfig +rm -f .mozconfig +cp %{SOURCE10} .mozconfig echo "ac_add_options --enable-default-toolkit=cairo-gtk3-wayland" >> .mozconfig %if %{official_branding} echo "ac_add_options --enable-official-branding" >> .mozconfig %endif -%{__cp} %{SOURCE24} mozilla-api-key -%{__cp} %{SOURCE27} google-api-key -%{__cp} %{SOURCE35} google-loc-api-key +cp %{SOURCE24} mozilla-api-key +cp %{SOURCE27} google-api-key +cp %{SOURCE35} google-loc-api-key echo "ac_add_options --prefix=\"%{_prefix}\"" >> .mozconfig echo "ac_add_options --libdir=\"%{_libdir}\"" >> .mozconfig @@ -516,13 +624,20 @@ echo "ac_add_options --without-system-nspr" >> .mozconfig echo "ac_add_options --without-system-nss" >> .mozconfig %endif +%if %{?system_libevent} +echo "ac_add_options --with-system-libevent" >> .mozconfig +%endif + %if %{?system_ffi} echo "ac_add_options --enable-system-ffi" >> .mozconfig %endif -%ifarch %{arm} +%ifarch aarch64 echo "ac_add_options --disable-elf-hack" >> .mozconfig %endif +%ifarch ppc64le +echo "ac_add_options --disable-webrtc" >> .mozconfig +%endif %if %{?debug_build} echo "ac_add_options --enable-debug" >> .mozconfig @@ -545,6 +660,10 @@ echo "ac_add_options --disable-debug" >> .mozconfig echo "ac_add_options --disable-jemalloc" >> .mozconfig %endif +%if !%{enable_mozilla_crashreporter} +echo "ac_add_options --disable-crashreporter" >> .mozconfig +%endif + %if 0%{?build_tests} echo "ac_add_options --enable-tests" >> .mozconfig %else @@ -557,13 +676,47 @@ echo "ac_add_options --without-system-jpeg" >> .mozconfig echo "ac_add_options --with-system-jpeg" >> .mozconfig %endif +%if %{?system_pixman} +echo "ac_add_options --enable-system-pixman" >> .mozconfig +%endif + +%if %{?system_av1} +#echo "ac_add_options --with-system-av1" >> .mozconfig +%else +#echo "ac_add_options --without-system-av1" >> .mozconfig +%endif + %if %{?system_libvpx} echo "ac_add_options --with-system-libvpx" >> .mozconfig %else echo "ac_add_options --without-system-libvpx" >> .mozconfig %endif -%ifarch s390 s390x +%if %{?system_webp} +echo "ac_add_options --with-system-webp" >> .mozconfig +%else +echo "ac_add_options --without-system-webp" >> .mozconfig +%endif + +%if %{?system_drm} +echo "ac_add_options --with-system-libdrm" >> .mozconfig +%else +echo "ac_add_options --without-system-libdrm" >> .mozconfig +%endif + +%if %{?system_gbm} +echo "ac_add_options --with-system-gbm" >> .mozconfig +%else +echo "ac_add_options --without-system-gbm" >> .mozconfig +%endif + +%if %{?system_pipewire} +echo "ac_add_options --with-system-pipewire" >> .mozconfig +%else +echo "ac_add_options --without-system-pipewire" >> .mozconfig +%endif + +%ifarch s390x echo "ac_add_options --disable-jit" >> .mozconfig %endif @@ -572,16 +725,21 @@ echo "ac_add_options --enable-address-sanitizer" >> .mozconfig echo "ac_add_options --disable-jemalloc" >> .mozconfig %endif -%if !%{enable_mozilla_crashreporter} -echo "ac_add_options --disable-crashreporter" >> .mozconfig -%endif - # api keys full path echo "ac_add_options --with-mozilla-api-keyfile=`pwd`/mozilla-api-key" >> .mozconfig # It seems that the api key we have is for the safe browsing only echo "ac_add_options --with-google-location-service-api-keyfile=`pwd`/google-loc-api-key" >> .mozconfig echo "ac_add_options --with-google-safebrowsing-api-keyfile=`pwd`/google-api-key" >> .mozconfig +# https://bugzilla.redhat.com/show_bug.cgi?id=2239046 +# with clang 17 upstream's detection fails, so let's just tell it +# where to look +echo "ac_add_options --with-libclang-path=`llvm-config --libdir`" >> .mozconfig + +%if %{enable_replace_malloc} +echo "ac_add_options --enable-replace-malloc" >> .mozconfig +%endif + echo 'export NODEJS="%{_buildrootdir}/bin/node-stdout-nonblocking-wrapper"' >> .mozconfig # Remove executable bit to make brp-mangle-shebangs happy. @@ -594,12 +752,44 @@ chmod a-x third_party/rust/ash/src/extensions/nv/*.rs %build # Disable LTO to work around rhbz#1883904 +# Is that already fixed? %define _lto_cflags %{nil} +#WASI SDK +%if %{with wasi_sdk} +pushd wasi-sdk-25 + +mkdir -p my_rust_vendor +cd my_rust_vendor +tar xf %{SOURCE4} +mkdir -p .cargo +cat > .cargo/config < .cargo/config < .cargo/config < 30 +MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | sed -e 's/-Werror=format-security//') +# More Fedora specific build flags MOZ_OPT_FLAGS="$MOZ_OPT_FLAGS -fpermissive" -%endif -%if %{?hardened_build} -MOZ_OPT_FLAGS="$MOZ_OPT_FLAGS -fPIC -Wl,-z,relro -Wl,-z,now" -%endif %if %{?debug_build} -MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | %{__sed} -e 's/-O2//') +MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | sed -e 's/-O2//') %endif -%ifarch s390 -MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | %{__sed} -e 's/-g/-g1/') # If MOZ_DEBUG_FLAGS is empty, firefox's build will default it to "-g" which # overrides the -g1 from line above and breaks building on s390/arm # (OOM when linking, rhbz#1238225) +%ifarch %{ix86} ppc64le +MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | sed -e 's/-g/-g0/') +%else +# this reduces backtrace quality substantially, but seems to be needed +# to prevent various OOM conditions during build +# https://bugzilla.redhat.com/show_bug.cgi?id=2241690 +MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | sed -e 's/-g/-g1/') +%endif export MOZ_DEBUG_FLAGS=" " -%endif -%ifarch %{arm} %{ix86} -MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | %{__sed} -e 's/-g/-g0/') -export MOZ_DEBUG_FLAGS=" " -%endif -%if !%{build_with_clang} -%ifarch s390 ppc aarch64 %{ix86} -MOZ_LINK_FLAGS="-Wl,--no-keep-memory -Wl,--reduce-memory-overheads" -%endif -%ifarch %{arm} -MOZ_LINK_FLAGS="-Wl,--no-keep-memory -Wl,--strip-debug" -echo "ac_add_options --enable-linker=gold" >> .mozconfig +MOZ_LINK_FLAGS="%{build_ldflags}" +%if !%{with build_with_clang} +%ifarch aarch64 %{ix86} ppc64le x86_64 +MOZ_LINK_FLAGS="$MOZ_LINK_FLAGS -Wl,--no-keep-memory" %endif %endif -%if 0%{?flatpak} -# Make sure the linker can find libraries in /app/lib64 as we don't use -# __global_ldflags that normally sets this. -MOZ_LINK_FLAGS="$MOZ_LINK_FLAGS -L%{_libdir}" -%endif -%ifarch %{arm} %{ix86} %{s390x} +%ifarch %{ix86} s390x ppc64le export RUSTFLAGS="-Cdebuginfo=0" %endif %if %{build_with_asan} @@ -682,7 +879,7 @@ echo "export CFLAGS=\"$MOZ_OPT_FLAGS\"" >> .mozconfig echo "export CXXFLAGS=\"$MOZ_OPT_FLAGS\"" >> .mozconfig echo "export LDFLAGS=\"$MOZ_LINK_FLAGS\"" >> .mozconfig -%if %{build_with_clang} +%if %{with build_with_clang} echo "export LLVM_PROFDATA=\"llvm-profdata\"" >> .mozconfig echo "export AR=\"llvm-ar\"" >> .mozconfig echo "export NM=\"llvm-nm\"" >> .mozconfig @@ -696,102 +893,111 @@ echo "export NM=\"gcc-nm\"" >> .mozconfig echo "export RANLIB=\"gcc-ranlib\"" >> .mozconfig %endif %if 0%{?build_with_pgo} -echo "ac_add_options MOZ_PGO=1" >> .mozconfig # PGO build doesn't work with ccache export CCACHE_DISABLE=1 +export GCOV_PREFIX=`pwd -P`/objdir +export GCOV_PREFIX_STRIP=$(( $(echo `pwd -P`|tr -c -d '/' |wc -c )+2 )) +env | grep GCOV +echo "ac_add_options --enable-lto" >> .mozconfig +echo "ac_add_options MOZ_PGO=1" >> .mozconfig %endif -MOZ_SMP_FLAGS=-j1 -# On x86_64 architectures, Mozilla can build up to 4 jobs at once in parallel, -# however builds tend to fail on other arches when building in parallel. -%ifarch %{ix86} s390x %{arm} aarch64 -[ -z "$RPM_BUILD_NCPUS" ] && \ - RPM_BUILD_NCPUS="`/usr/bin/getconf _NPROCESSORS_ONLN`" -[ "$RPM_BUILD_NCPUS" -ge 2 ] && MOZ_SMP_FLAGS=-j2 -%endif -%ifarch x86_64 ppc ppc64 ppc64le -[ -z "$RPM_BUILD_NCPUS" ] && \ - RPM_BUILD_NCPUS="`/usr/bin/getconf _NPROCESSORS_ONLN`" -[ "$RPM_BUILD_NCPUS" -ge 2 ] && MOZ_SMP_FLAGS=-j2 -[ "$RPM_BUILD_NCPUS" -ge 4 ] && MOZ_SMP_FLAGS=-j4 -[ "$RPM_BUILD_NCPUS" -ge 8 ] && MOZ_SMP_FLAGS=-j8 -[ "$RPM_BUILD_NCPUS" -ge 16 ] && MOZ_SMP_FLAGS=-j16 -[ "$RPM_BUILD_NCPUS" -ge 24 ] && MOZ_SMP_FLAGS=-j24 -[ "$RPM_BUILD_NCPUS" -ge 32 ] && MOZ_SMP_FLAGS=-j32 -[ "$RPM_BUILD_NCPUS" -ge 64 ] && MOZ_SMP_FLAGS=-j64 +%if %{with wasi_sdk} +echo "ac_add_options --with-wasi-sysroot=`pwd`/wasi-sdk-25/build/sysroot/install/share/wasi-sysroot" >> .mozconfig +%else +echo "ac_add_options --without-sysroot" >> .mozconfig +echo "ac_add_options --without-wasm-sandboxed-libraries" >> .mozconfig %endif -echo "mk_add_options MOZ_MAKE_FLAGS=\"$MOZ_SMP_FLAGS\"" >> .mozconfig +# Require 4 GB of RAM per CPU core +%constrain_build -m 4096 +echo "mk_add_options MOZ_MAKE_FLAGS=\"-j%{_smp_build_ncpus}\"" >> .mozconfig + echo "mk_add_options MOZ_SERVICES_SYNC=1" >> .mozconfig echo "export STRIP=/bin/true" >> .mozconfig -#export MACH_USE_SYSTEM_PYTHON=1 - -%if %{launch_wayland_compositor} -cp %{SOURCE45} . -. ./run-wayland-compositor -%endif %if %{build_with_pgo} -%if %{test_on_wayland} -env | grep "WAYLAND" -MOZ_ENABLE_WAYLAND=1 ./mach build -v 2>&1 | cat - || exit 1 -%else -xvfb-run ./mach build -v 2>&1 | cat - || exit 1 -%endif -%else -./mach build -v 2>&1 | cat - || exit 1 -%endif - -#--------------------------------------------------------------------- -%install -# run Firefox test suite -export MACH_USE_SYSTEM_PYTHON=1 -%if %{launch_wayland_compositor} cp %{SOURCE45} . . ./run-wayland-compositor %endif -%if 0%{?run_firefox_tests} mkdir -p objdir/_virtualenvs/init_py3 -%{__cat} > objdir/_virtualenvs/init_py3/pip.conf << EOF +cat > objdir/_virtualenvs/init_py3/pip.conf << EOF [global] find-links=`pwd`/mochitest-python no-index=true EOF tar xf %{SOURCE37} + +#Use python 3.11 for mach +sed -i -e 's|#!/usr/bin/env python3|#!/usr/bin/env python3.11|' mach + +./mach build -v 2>&1 | cat - || exit 1 + +%if %{build_with_pgo} +kill $MUTTER_PID +%endif + +#--------------------------------------------------------------------- +%install +# run Firefox test suite +# Do we need it? +# export MACH_NATIVE_PACKAGE_SOURCE=system +%if %{run_firefox_tests} +cp %{SOURCE45} . +. ./run-wayland-compositor + cp %{SOURCE40} %{SOURCE41} %{SOURCE42} %{SOURCE38} %{SOURCE39} %{SOURCE43} %{SOURCE44} . mkdir -p test_results -%if %{test_on_wayland} ./run-tests-wayland || true -%else -./run-tests-x11 || true -%endif ./print_results > test_summary.txt 2>&1 || true ./print_failures || true + +kill $MUTTER_PID %endif # set up our default bookmarks %if !0%{?flatpak} -%{__cp} -p %{default_bookmarks_file} objdir/dist/bin/browser/chrome/browser/content/browser/default-bookmarks.html +cp -p %{default_bookmarks_file} objdir/dist/bin/browser/chrome/browser/content/browser/default-bookmarks.html %endif # Make sure locale works for langpacks -%{__cat} > objdir/dist/bin/browser/defaults/preferences/firefox-l10n.js << EOF +cat > objdir/dist/bin/browser/defaults/preferences/firefox-l10n.js << EOF pref("general.useragent.locale", "chrome://global/locale/intl.properties"); EOF DESTDIR=%{buildroot} make -C objdir install -%{__mkdir_p} %{buildroot}{%{_libdir},%{_bindir},%{_datadir}/applications} +mkdir -p %{buildroot}{%{_libdir},%{_bindir},%{_datadir}/applications} -desktop-file-install --dir %{buildroot}%{_datadir}/applications %{SOURCE20} +%if %{gnome_shell_search_provider} +# Install Gnome search provider files +mkdir -p %{buildroot}%{_datadir}/gnome-shell/search-providers +cp %{SOURCE34} %{buildroot}%{_datadir}/gnome-shell/search-providers +mkdir -p %{buildroot}%{_datadir}/dbus-1/services +cp %{SOURCE46} %{buildroot}%{_datadir}/dbus-1/services +%endif + +%if 0%{?fedora} >= 40 +desktop-file-install --dir %{buildroot}%{_datadir}/applications %{SOURCE47} +%else +# We can't use desktop-file-install as it refuses to install firefox.desktop file. +cp %{SOURCE20} %{buildroot}%{_datadir}/applications +%endif + +%if 0%{?fedora} < 40 desktop-file-install --dir %{buildroot}%{_datadir}/applications %{SOURCE31} desktop-file-install --dir %{buildroot}%{_datadir}/applications %{SOURCE29} +%endif # set up the firefox start script -%{__rm} -rf %{buildroot}%{_bindir}/firefox -%{__sed} -e 's,/__PREFIX__,%{_prefix},g' %{SOURCE21} > %{buildroot}%{_bindir}/firefox -%{__chmod} 755 %{buildroot}%{_bindir}/firefox +rm -rf %{buildroot}%{_bindir}/firefox +%if 0%{?fedora} < 40 +sed -e 's,/__PREFIX__,%{_prefix},g' -e 's,__APP_NAME__,firefox,g' %{SOURCE21} > %{buildroot}%{_bindir}/firefox +%else +sed -e 's,/__PREFIX__,%{_prefix},g' -e 's,__APP_NAME__,org.mozilla.firefox,g' %{SOURCE21} > %{buildroot}%{_bindir}/firefox +%endif +chmod 755 %{buildroot}%{_bindir}/firefox %if 0%{?flatpak} sed -i -e 's|%FLATPAK_ENV_VARS%|export TMPDIR="$XDG_CACHE_HOME/tmp"|' %{buildroot}%{_bindir}/firefox @@ -799,36 +1005,39 @@ sed -i -e 's|%FLATPAK_ENV_VARS%|export TMPDIR="$XDG_CACHE_HOME/tmp"|' %{buildroo sed -i -e 's|%FLATPAK_ENV_VARS%||' %{buildroot}%{_bindir}/firefox %endif -%{__sed} -e 's,/__PREFIX__,%{_prefix},g' %{SOURCE30} > %{buildroot}%{_bindir}/firefox-x11 -%{__chmod} 755 %{buildroot}%{_bindir}/firefox-x11 -%{__sed} -e 's,/__PREFIX__,%{_prefix},g' %{SOURCE28} > %{buildroot}%{_bindir}/firefox-wayland -%{__chmod} 755 %{buildroot}%{_bindir}/firefox-wayland +%if 0%{?fedora} < 40 +sed -e 's,/__PREFIX__,%{_prefix},g' %{SOURCE30} > %{buildroot}%{_bindir}/firefox-x11 +chmod 755 %{buildroot}%{_bindir}/firefox-x11 +sed -e 's,/__PREFIX__,%{_prefix},g' %{SOURCE28} > %{buildroot}%{_bindir}/firefox-wayland +chmod 755 %{buildroot}%{_bindir}/firefox-wayland +%endif -%{__install} -p -D -m 644 %{SOURCE23} %{buildroot}%{_mandir}/man1/firefox.1 +install -p -D -m 644 %{SOURCE23} %{buildroot}%{_mandir}/man1/firefox.1 -%{__rm} -f %{buildroot}/%{mozappdir}/firefox-config -%{__rm} -f %{buildroot}/%{mozappdir}/update-settings.ini +rm -f %{buildroot}/%{mozappdir}/firefox-config +rm -f %{buildroot}/%{mozappdir}/update-settings.ini +rm -f %{buildroot}/%{mozappdir}/firefox-bin for s in 16 22 24 32 48 256; do - %{__mkdir_p} %{buildroot}%{_datadir}/icons/hicolor/${s}x${s}/apps - %{__cp} -p browser/branding/official/default${s}.png \ - %{buildroot}%{_datadir}/icons/hicolor/${s}x${s}/apps/firefox.png + mkdir -p %{buildroot}%{_datadir}/icons/hicolor/${s}x${s}/apps + cp -p browser/branding/official/default${s}.png \ + %{buildroot}%{_datadir}/icons/hicolor/${s}x${s}/apps/firefox.png done # Install hight contrast icon -%{__mkdir_p} %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps -%{__cp} -p %{SOURCE25} \ - %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +mkdir -p %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps +cp -p %{SOURCE25} \ + %{buildroot}%{_datadir}/icons/hicolor/symbolic/apps echo > %{name}.lang %if %{with langpacks} # Extract langpacks, make any mods needed, repack the langpack, and install it. -%{__mkdir_p} %{buildroot}%{langpackdir} -%{__tar} xf %{SOURCE1} +mkdir -p %{buildroot}%{langpackdir} +tar xf %{SOURCE1} for langpack in `ls firefox-langpacks/*.xpi`; do language=`basename $langpack .xpi` extensionID=langpack-$language@firefox.mozilla.org - %{__mkdir_p} $extensionID + mkdir -p $extensionID unzip -qq $langpack -d $extensionID find $extensionID -type f | xargs chmod 644 @@ -836,7 +1045,7 @@ for langpack in `ls firefox-langpacks/*.xpi`; do zip -qq -r9mX ../${extensionID}.xpi * cd - - %{__install} -m 644 ${extensionID}.xpi %{buildroot}%{langpackdir} + install -m 644 ${extensionID}.xpi %{buildroot}%{langpackdir} language=`echo $language | sed -e 's/-/_/g'` %if 0%{?flatpak} echo "%{langpackdir}/${extensionID}.xpi" >> %{name}.lang @@ -844,7 +1053,7 @@ for langpack in `ls firefox-langpacks/*.xpi`; do echo "%%lang($language) %{langpackdir}/${extensionID}.xpi" >> %{name}.lang %endif done -%{__rm} -rf firefox-langpacks +rm -rf firefox-langpacks # Install langpack workaround (see #707100, #821169) function create_default_langpack() { @@ -873,62 +1082,67 @@ create_default_langpack "sv-SE" "sv" create_default_langpack "zh-TW" "zh" %endif -%{__mkdir_p} %{buildroot}/%{mozappdir}/browser/defaults/preferences +mkdir -p %{buildroot}/%{mozappdir}/browser/defaults/preferences # System config dir -%{__mkdir_p} %{buildroot}/%{_sysconfdir}/%{name}/pref +mkdir -p %{buildroot}/%{_sysconfdir}/%{name}/pref # System extensions -%{__mkdir_p} %{buildroot}%{_datadir}/mozilla/extensions/%{firefox_app_id} -%{__mkdir_p} %{buildroot}%{_libdir}/mozilla/extensions/%{firefox_app_id} +mkdir -p %{buildroot}%{_datadir}/mozilla/extensions/%{firefox_app_id} +mkdir -p %{buildroot}%{_libdir}/mozilla/extensions/%{firefox_app_id} # Copy over the LICENSE -%{__install} -p -c -m 644 LICENSE %{buildroot}/%{mozappdir} +install -p -c -m 644 LICENSE %{buildroot}/%{mozappdir} # Use the system hunspell dictionaries -%{__rm} -rf %{buildroot}%{mozappdir}/dictionaries -%if 0%{?fedora} > 35 +rm -rf %{buildroot}%{mozappdir}/dictionaries ln -s %{_datadir}/hunspell %{buildroot}%{mozappdir}/dictionaries -%else -ln -s %{_datadir}/myspell %{buildroot}%{mozappdir}/dictionaries + +# Enable crash reporter for Firefox application +%if %{enable_mozilla_crashreporter} +./mach buildsymbols +sed -i -e "s/\[Crash Reporter\]/[Crash Reporter]\nEnabled=1/" %{buildroot}/%{mozappdir}/application.ini +# Add debuginfo for crash-stats.mozilla.com +mkdir -p %{buildroot}/%{moz_debug_dir} +cp objdir/dist/%{symbols_file_name} %{buildroot}/%{moz_debug_dir} %endif %if 0%{?run_firefox_tests} -%{__mkdir_p} %{buildroot}/%{version}-%{release}/test_results -%{__cp} test_results/* %{buildroot}/%{version}-%{release}/test_results -%{__cp} test_summary.txt %{buildroot}/%{version}-%{release}/ -%{__cp} failures-* %{buildroot}/%{version}-%{release}/ || true +mkdir -p %{buildroot}/%{version}-%{release}/test_results +cp test_results/* %{buildroot}/%{version}-%{release}/test_results +cp test_summary.txt %{buildroot}/%{version}-%{release}/ +cp failures-* %{buildroot}/%{version}-%{release}/ || true %endif # Default -%{__cp} %{SOURCE12} %{buildroot}%{mozappdir}/browser/defaults/preferences - -# Since Fedora 36 the location of dictionaries has changed to /usr/share/hunspell. -# For backward spec compatibility we set the old path in previous versions. -# TODO remove when Fedora 35 becomes obsolete -%if 0%{?fedora} <= 35 -sed -i -e 's|/usr/share/hunspell|/usr/share/myspell|g' %{buildroot}%{mozappdir}/browser/defaults/preferences/firefox-redhat-default-prefs.js +cp %{SOURCE12} %{buildroot}%{mozappdir}/browser/defaults/preferences +%if %{?use_xdg_file_portal} +echo 'pref("widget.use-xdg-desktop-portal.file-picker", 1);' >> %{buildroot}%{mozappdir}/browser/defaults/preferences/firefox-redhat-default-prefs.js %endif -# Copy over run-mozilla.sh -%{__cp} build/unix/run-mozilla.sh %{buildroot}%{mozappdir} +%if %{?use_pipewire_camera} +echo 'pref("media.webrtc.camera.allow-pipewire", true);' >> %{buildroot}%{mozappdir}/browser/defaults/preferences/firefox-redhat-default-prefs.js +%endif # Add distribution.ini -%{__mkdir_p} %{buildroot}%{mozappdir}/distribution -%{__cp} %{SOURCE26} %{buildroot}%{mozappdir}/distribution +mkdir -p %{buildroot}%{mozappdir}/distribution +sed -e "s/__NAME__/%(source /etc/os-release; echo ${NAME})/" \ + -e "s/__ID__/%(source /etc/os-release; echo ${ID})/" \ + -e "s/rhel/redhat/" \ + -e "s/Fedora.*/Fedora/" \ + %{SOURCE26} > %{buildroot}%{mozappdir}/distribution/distribution.ini # Install appdata file mkdir -p %{buildroot}%{_datadir}/metainfo -%{__sed} -e "s/__VERSION__/%{version}/" \ - -e "s/__DATE__/$(date '+%F')/" \ - %{SOURCE33} > %{buildroot}%{_datadir}/metainfo/firefox.appdata.xml - -# Install Gnome search provider files -mkdir -p %{buildroot}%{_datadir}/gnome-shell/search-providers -%{__cp} %{SOURCE34} %{buildroot}%{_datadir}/gnome-shell/search-providers - -# Remove gtk2 support as flash plugin is no longer supported -rm -rf %{buildroot}%{mozappdir}/gtk2/ +%if 0%{?fedora} >= 40 +sed -e "s/__VERSION__/%{version}/" \ + -e "s/__DATE__/$(date '+%F')/" \ + %{SOURCE48} > %{buildroot}%{_datadir}/metainfo/org.mozilla.firefox.appdata.xml +%else +sed -e "s/__VERSION__/%{version}/" \ + -e "s/__DATE__/$(date '+%F')/" \ + %{SOURCE33} > %{buildroot}%{_datadir}/metainfo/firefox.appdata.xml +%endif # Remove copied libraries to speed up build rm -f %{buildroot}%{mozappdirdev}/sdk/lib/libmozjs.so @@ -972,51 +1186,46 @@ appstream-util validate-relax --nonet %{buildroot}%{_datadir}/metainfo/*.appdata %preun # is it a final removal? if [ $1 -eq 0 ]; then - %{__rm} -rf %{mozappdir}/components - %{__rm} -rf %{mozappdir}/extensions - %{__rm} -rf %{mozappdir}/plugins - %{__rm} -rf %{langpackdir} + rm -rf %{mozappdir}/components + rm -rf %{mozappdir}/extensions + rm -rf %{mozappdir}/plugins + rm -rf %{langpackdir} fi -%post -update-desktop-database &> /dev/null || : -touch --no-create %{_datadir}/icons/hicolor &>/dev/null || : - -%postun -update-desktop-database &> /dev/null || : -if [ $1 -eq 0 ] ; then - touch --no-create %{_datadir}/icons/hicolor &>/dev/null - gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : -fi - -%posttrans -gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : - +%if %{with langpacks_subpkg} +%files +%else %files -f %{name}.lang +%endif %{_bindir}/firefox %{mozappdir}/firefox -%{mozappdir}/firefox-bin +%{mozappdir}/glxtest %doc %{_mandir}/man1/* %dir %{_sysconfdir}/%{name} %dir %{_sysconfdir}/%{name}/* %dir %{_datadir}/mozilla/extensions/* %dir %{_libdir}/mozilla/extensions/* -%{_datadir}/applications/%{name}.desktop -%{_datadir}/metainfo/*.appdata.xml +%if 0%{?fedora} >= 40 +%{_datadir}/applications/org.mozilla.firefox.desktop +%else +%{_datadir}/applications/firefox.desktop +%endif +%if %{gnome_shell_search_provider} +%{_datadir}/dbus-1/services/* %{_datadir}/gnome-shell/search-providers/*.ini +%endif +%{_datadir}/metainfo/*.appdata.xml %dir %{mozappdir} %license %{mozappdir}/LICENSE -%{mozappdir}/browser/chrome -%{mozappdir}/browser/defaults/preferences/firefox-redhat-default-prefs.js -%{mozappdir}/browser/features/*.xpi -%{mozappdir}/distribution/distribution.ini +%{mozappdir}/browser +%{mozappdir}/distribution # That's Windows only %ghost %{mozappdir}/browser/features/aushelper@mozilla.org.xpi +%if %{without langpacks_subpkg} %if %{with langpacks} %dir %{langpackdir} %endif -%{mozappdir}/browser/omni.ja -%{mozappdir}/run-mozilla.sh +%endif %{mozappdir}/application.ini %{mozappdir}/pingsender %exclude %{mozappdir}/removed-files @@ -1033,10 +1242,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_datadir}/icons/hicolor/symbolic/apps/firefox-symbolic.svg %if %{enable_mozilla_crashreporter} %{mozappdir}/crashreporter -%{mozappdir}/crashreporter.ini -%{mozappdir}/minidump-analyzer -%{mozappdir}/Throbber-small.gif -%{mozappdir}/browser/crashreporter-override.ini +%{mozappdir}/crashhelper %endif %{mozappdir}/*.so %{mozappdir}/defaults/pref/channel-prefs.js @@ -1044,9 +1250,12 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{mozappdir}/dictionaries %{mozappdir}/omni.ja %{mozappdir}/platform.ini -%{mozappdir}/plugin-container %{mozappdir}/gmp-clearkey -%{mozappdir}/fonts/TwemojiMozilla.ttf +%{mozappdir}/fonts +%ifarch aarch64 riscv64 +%{mozappdir}/v4l2test +%endif +%{mozappdir}/vaapitest %if !%{?system_nss} %exclude %{mozappdir}/libnssckbi.so %endif @@ -1057,6 +1266,786 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Tue Jan 06 2026 Martin Stransky - 147.0-1 +- Updated to 147.0 + +* Fri Dec 19 2025 Martin Stransky - 146.0.1-1 +- Updated to 146.0.1 + +* Wed Dec 17 2025 Martin Stransky - 146.0-6 +- Added upstream patch IWYU (libwebrtc IWYU fixes for PipeWire) +- Claude AI assisted editing (failed to do whole work, but it was close!) + +* Wed Dec 17 2025 Martin Stransky - 146.0-5 +- Removed firefox-bin from man pages + +* Thu Dec 11 2025 Martin Stransky - 146.0-4 +- Removed firefox-bin + +* Thu Dec 11 2025 Martin Stransky - 146.0-3 +- Added aarch64 crash fix +- Fixed rawhide gcc build (kudos to jhorak who hacked it! He's just awesome.) + +* Mon Dec 08 2025 Martin Stransky - 146.0-2 +- Updated to 146.0 build 2 + +* Wed Dec 03 2025 Martin Stransky - 146.0-1 +- Updated to 146.0 + +* Wed Nov 19 2025 Martin Stransky - 145.0.1-1 +- Updated to 145.0.1 + +* Tue Nov 11 2025 Martin Stransky - 145.0-2 +- Updated to 145.0 B2 + +* Wed Nov 05 2025 Martin Stransky - 145.0-1 +- Updated to 145.0 + +* Thu Oct 30 2025 Martin Stransky - 144.0.2-1 +- Updated to 144.0.2 + +* Thu Oct 16 2025 Martin Stransky - 144.0-3 +- Add fix for mzbz#1990430 + +* Mon Oct 13 2025 Martin Stransky - 144.0-2 +- Updated to 144.0 (b2) + +* Thu Oct 09 2025 Martin Stransky - 144.0-1 +- Updated to 144.0 + +* Mon Oct 06 2025 Martin Stransky - 143.0.4-1 +- Updated to 143.0.4 + +* Tue Sep 30 2025 Martin Stransky - 143.0.3-1 +- Updated to 143.0.3 + +* Fri Sep 26 2025 Martin Stransky - 143.0.1-3 +- Added fix for mzbz#1990162 + +* Thu Sep 25 2025 Martin Stransky - 143.0.1-2 +- Added fix for mzbz#1984368 + +* Fri Sep 19 2025 Martin Stransky - 143.0.1-1 +- Updated to 143.0.1 + +* Wed Sep 10 2025 Martin Stransky - 143.0-1 +- Updated to 143.0 + +* Wed Aug 27 2025 Martin Stransky - 142.0.1-1 +- Updated to 142.0.1 + +* Mon Aug 25 2025 Tom Stellard - 142.0-3 +- Fix build with llvm-21 + +* Sat Aug 23 2025 Dominik Mierzejewski - 142.0-2 +- Drop unused yasm build dependency, part of: + https://fedoraproject.org/wiki/Changes/DeprecateYASM + +* Tue Aug 12 2025 Martin Stransky - 142.0-1 +- Updated to 142.0 + +* Mon Aug 11 2025 Martin Stransky - 141.0.3-1 +- Updated to 141.0.3 + +* Wed Aug 6 2025 Martin Stransky - 141.0.2-1 +- Updated to 141.0.2 + +* Wed Jul 23 2025 Fedora Release Engineering - 141.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + +* Fri Jul 18 2025 Martin Stransky - 141.0-2 +- Respin 141.0 build 2 + +* Thu Jul 17 2025 Martin Stransky - 141.0-1 +- Update to latest upstream (141.0) + +* Wed Jul 09 2025 Martin Stransky - 140.0.4-1 +- Update to latest upstream (140.0.4) + +* Fri Jun 27 2025 Martin Stransky - 140.0.1-1 +- Update to latest upstream (140.0.1) + +* Tue Jun 17 2025 Martin Stransky - 140.0-1 +- Update to latest upstream (140.0) + +* Wed Jun 11 2025 Martin Stransky - 139.0.4-2 +- Use headless Mutter to run PGO builds + +* Wed Jun 11 2025 Martin Stransky - 139.0.4-1 +- Updated to latest upstream (139.0.4) + +* Fri Jun 6 2025 Martin Stransky - 139.0-3 +- Updated desktop file translation (rhbz#2362155) + +* Fri May 30 2025 Jan Grulich - 139.0-2 +- Use system libraries for drm/gbm/pipewire + +* Tue May 27 2025 Martin Stransky - 139.0-1 +- Updated to 139.0 + +* Mon May 19 2025 Martin Stransky - 138.0.4-1 +- Updated to 138.0.4 + +* Wed May 14 2025 Martin Stransky - 138.0.3-2 +- Fixed rhbz#2283790 + +* Mon May 12 2025 Martin Stransky - 138.0.3-1 +- Updated to 138.0.3 + +* Thu May 1 2025 Martin Stransky - 138.0.1-1 +- Updated to 138.0.1 + +* Sat Apr 26 2025 Bojan Smojver - 138.0-1 +- Add fix for mzbz#1957628 +- Remove browser/features/*.xpi files, no longer shipped + +* Tue Apr 22 2025 Martin Stransky - 138.0-1 +- Updated to 138.0 + +* Tue Apr 22 2025 Martin Stransky - 137.0.2-3 +- Added fix for rhbz#2358565 + +* Wed Apr 16 2025 Martin Stransky - 137.0.2-2 +- Added fix for mzbz#1951249 + +* Wed Apr 16 2025 Martin Stransky - 137.0.2-1 +- Update 137.0.2 + +* Mon Apr 14 2025 Martin Stransky - 137.0.1-1 +- Update 137.0.1 + +* Mon Mar 31 2025 Martin Stransky - 137.0-2 +- Update 137.0 build 2 + +* Wed Mar 26 2025 Martin Stransky - 137.0-1 +- Update to latest upstream (137.0) + +* Tue Mar 25 2025 Martin Stransky - 136.0.3-1 +- Revert rhbz#2353895 as it looks broken +- Update to latest upstream (136.0.3) + +* Mon Mar 24 2025 Martin Stransky - 136.0.2-2 +- Stop overriding user settings on every update (rhbz#2353895) +- Remove browser.display.use_system_colors override (rhbz#2353953) + +* Wed Mar 19 2025 Martin Stransky - 136.0.2-1 +- Updated to 136.0.2 + +* Wed Mar 12 2025 Martin Stransky - 136.0.1-1 +- Updated to 136.0.1 + +* Fri Feb 28 2025 Martin Stransky - 136.0-2 +- Updated to 136.0 Build 3 + +* Tue Feb 25 2025 Martin Stransky - 136.0-1 +- Updated to 136.0 + +* Wed Feb 19 2025 Martin Stransky - 135.0.1-1 +- Updated to 135.0.1 + +* Tue Feb 04 2025 Martin Stransky - 135.0-1 +- Updated to 135.0 + +* Tue Jan 28 2025 Martin Stransky - 134.0.2-2 +- Call restorecon for widevine only (rhbz#2342243) + +* Wed Jan 22 2025 Martin Stransky - 134.0.2-1 +- Updated to 134.0.2 + +* Wed Jan 15 2025 Martin Stransky - 134.0.1-1 +- Updated to 134.0.1 + +* Thu Jan 02 2025 Martin Stransky - 134.0-1 +- Updated to 134.0 + +* Mon Dec 16 2024 Martin Stransky - 133.0.3-2 +- Remove MOZ_DBUS_APP_NAME from launch script as it breaks Thunderbird (rhbz#2320090) + +* Wed Dec 11 2024 Martin Stransky - 133.0.3-1 +- Updated to 133.0.3 + +* Sat Nov 30 2024 Martin Stransky - 133.0-2 +- Add fix for mzbz#1934217 + +* Fri Nov 22 2024 Martin Stransky - 133.0-1 +- Updated to latest upstream (133.0) + +* Mon Nov 18 2024 Martin Stransky - 132.0.2-2 +- Added memory saving flags to x86_64 + +* Fri Nov 15 2024 Martin Stransky - 132.0.2-1 +- Updated to 132.0.2 +- Try to reduce build mem usage on ppc64le + +* Thu Nov 07 2024 Jan Grulich - 132.0.1-2 +- PipeWire camera: use better unique device name for camera devices + +* Tue Nov 05 2024 Martin Stransky - 132.0.1-1 +- Updated to 132.0.1 + +* Fri Oct 25 2024 Martin Stransky - 132.0-2 +- Enabled PGO + +* Wed Oct 23 2024 Martin Stransky - 132.0-1 +- Updated to 132.0 + +* Mon Oct 21 2024 Martin Stransky - 131.0.3-3 +- Backported hi-res mouse scrolling and + hold touchpad gesture support for Fedora 41 + +* Tue Oct 15 2024 Martin Stransky - 131.0.3-1 +- Updated to 131.0.3 + +* Wed Oct 09 2024 Martin Stransky - 131.0.2-1 +- Updated to 131.0.2 + +* Mon Sep 30 2024 Martin Stransky - 131.0-2 +- Fix regression from mzbz#1634961 - enable Gnome Shell search in opened tabs +- Temporary disabled PGO due to build issues. + +* Wed Sep 25 2024 Martin Stransky - 131.0-1 +- Added fix for mzbz#1634961 - enable Gnome Shell search in opened tabs +- Updated to 131.0 + +* Mon Sep 23 2024 Jan Grulich - 130.0.1-3 +- Fix PipeWire camera support enablement for F41+ +- Additional WebRTC backports for PipeWire camera support + +* Fri Sep 20 2024 Songsong Zhang - 130.0.1-2 +- Add v4l2test file for RISC-V + +* Wed Sep 18 2024 Martin Stransky - 130.0.1-1 +- Updated to 130.0.1 + +* Sun Sep 08 2024 Jan Grulich - 130.0-5 +- PipeWire camera support: backport set of upstream patches + +* Fri Sep 6 2024 Martin Stransky - 130.0-4 +- Added fix for mzbz#1916038 + +* Thu Sep 5 2024 Martin Stransky - 130.0-3 +- Downgrade libyuv to fix AVIF image rendering + +* Fri Aug 30 2024 Martin Stransky - 130.0-2 +- Updated to 130.0 build 2 + +* Wed Aug 28 2024 Martin Stransky - 130.0-1 +- Update to 130.0 + +* Wed Aug 28 2024 Miroslav Suchý - 129.0.2-2 +- convert license to SPDX + +* Tue Aug 20 2024 Martin Stransky - 129.0.2-1 +- Update to 129.0.2 + +* Mon Aug 19 2024 Jan Grulich - 129.0-4 +- WebRTC backport: Filter out camera devices with no capabilities + +* Thu Aug 15 2024 Michael Catanzaro - 129.0-3 +- Add conditional hard dependency on mozilla-openh264, always required if openh264 is installed + +* Tue Aug 13 2024 Jan Grulich - 129.0-2 +- Enable PipeWire camera support for F41+ + +* Tue Jul 30 2024 Martin Stransky - 129.0-1 +- Update to 129.0 + +* Mon Jul 29 2024 Martin Stransky - 128.0.3-1 +- Update to 128.0.3 + +* Wed Jul 17 2024 Fedora Release Engineering - 128.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + +* Fri Jul 12 2024 Martin Stransky - 128.0-2 +- Added fix for mzbz#1907511 + +* Tue Jul 2 2024 Martin Stransky - 128.0-1 +- Update to 128.0 + +* Tue Jul 2 2024 Martin Stransky - 127.0.2-2 +- Allow to override MOZ_DBUS_APP_NAME + +* Tue Jun 25 2024 Martin Stransky - 127.0.2-1 +- Update to 127.0.2 + +* Fri Jun 14 2024 Jan Grulich - 127.0-2 +- Fix duplicated camera entries with PipeWire + +* Mon Jun 10 2024 Jan Horak - 127.0-1 +- Update to 127.0 + +* Tue May 21 2024 Jan Horak - 126.0-8 +- Enabled crashreporter again + +* Mon May 20 2024 Martin Stransky - 126.0-7 +- Gnome search service tweak + +* Wed May 15 2024 Martin Stransky - 126.0-6 +- Added fix for mzbz#1896846 + +* Tue May 14 2024 Martin Stransky - 126.0-5 +- Updated upstream patches + +* Mon May 13 2024 Martin Stransky - 126.0-4 +- Rebuild + +* Mon May 13 2024 Martin Stransky - 126.0-3 +- More upstream patches for Gnome search provider. + +* Fri May 10 2024 Martin Stransky - 126.0-2 +- Fix Gnome search provider for Fedora 40+ + +* Fri May 10 2024 Jan Grulich - 126.0-1 +- Backport WebRTC fix for screen cast glitches in KDE + +* Thu May 9 2024 Martin Stransky - 126.0-1 +- Updated to 126.0 + +* Tue May 7 2024 Martin Stransky - 125.0.3-2 +- Added ffmpeg-free to recommends (rhbz#2023833). + +* Mon Apr 29 2024 Martin Stransky - 125.0.3-1 +- Updated to 125.0.3 + +* Tue Apr 9 2024 Martin Stransky - 125.0-1 +- Updated to 125.0 + +* Thu Apr 4 2024 Martin Stransky - 124.0.2-2 +- Updated to 124.0.2 + +* Thu Mar 28 2024 Jan Horak - 124.0.1-4 +- Enable rlbox sandboxing + +* Mon Mar 25 2024 Martin Stransky - 124.0-2 +- Reverted IM patch + +* Wed Mar 13 2024 Martin Stransky - 124.0-1 +- Updated to 124.0 + +* Thu Mar 07 2024 Martin Stransky - 123.0.1-1 +- Updated to 123.0.1 + +* Fri Feb 23 2024 Martin Stransky - 123.0-2 +- Fixed PGO builds and enabled it again. + +* Wed Feb 21 2024 Daniel Rusek - 123.0-2 +- Add matching AppStream metadata for org.mozilla.firefox.desktop + +* Mon Feb 19 2024 Martin Stransky - 123.0-1 +- Update to 123.0 +- disabled system AV1 due to build issues. + +* Tue Feb 13 2024 Martin Stransky - 122.0.1-1 +- Update to 122.0.1 + +* Mon Feb 12 2024 Jan Grulich - 122.0-7 +- Backport upstream fixes to PipeWire camera support + +* Mon Feb 12 2024 Martin Stransky - 122.0-6 +- Temporary removed proxy cache (rhbz#2262959) + +* Wed Jan 31 2024 Martin Stransky - 122.0-5 +- Disabled system libvpx due to WebRTC/camera issues (mzbz#1875201) + +* Tue Jan 30 2024 Martin Stransky - 122.0-4 +- Build with --enable-replace-malloc (rhbz#2260766) + +* Tue Jan 30 2024 Martin Stransky - 122.0-3 +- Added version to obsolete firefox-wayland/x11 + +* Mon Jan 29 2024 Martin Stransky - 122.0-2 +- Obsolete firefox-wayland and firefox-x11 on Fedora 40+ + +* Fri Jan 19 2024 Martin Stransky - 122.0-1 +- Update to 122.0 + +* Fri Jan 19 2024 Fedora Release Engineering - 121.0.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 12 2024 Fabio Valentini - 121.0.1-2 +- Rebuild for dav1d 1.3.0 + +* Fri Jan 12 2024 Martin Stransky - 121.0.1-1 +- Update to 121.0.1 +- Fixed Firefox icon on Rawhide + +* Tue Jan 02 2024 Martin Stransky - 121.0-4 +- Really enable proxy cache + +* Fri Dec 22 2023 Martin Stransky - 121.0-3 +- Disabled DBus activations + +* Tue Dec 19 2023 Martin Stransky - 121.0-2 +- Added Wayland proxy cache (mzbz#1743144) + +* Mon Dec 18 2023 Martin Stransky - 121.0-2 +- Enable Gnome Shell Search provider for Fedora 40+ +- Don't ship firefox-x11 and firefox-wayland on Fedora 40+ + +* Mon Dec 18 2023 Martin Stransky - 121.0-1 +- Updated to 121.0 + +* Fri Dec 01 2023 Martin Stransky - 120.0.1-1 +- Updated to 120.0.1 + +* Mon Nov 27 2023 Martin Stransky - 120.0-3 +- Add fix for rhbz#2251202 + +* Mon Nov 20 2023 Martin Stransky - 120.0-2 +- Updated to 120.0 Build 2 + +* Tue Nov 14 2023 Martin Stransky - 120.0-1 +- Updated to 120.0 + +* Fri Nov 10 2023 Martin Stransky - 119.0.1-2 +- Updated to 119.0.1 + +* Tue Nov 07 2023 Martin Stransky - 119.0-5 +- Added fix for rhbz#2247665 + +* Mon Nov 06 2023 Martin Stransky - 119.0-4 +- Added fix for mzbz#1762816 + +* Mon Oct 30 2023 Jan Horak - 119.0-3 +- Enable mozilla crash reporter + +* Fri Oct 27 2023 Martin Stransky - 119.0-2 +- Added fix for mzbz#1861615 + +* Tue Oct 24 2023 Martin Stransky - 119.0-1 +- Updated to 119.0 + +* Tue Oct 10 2023 Martin Stransky - 118.0.2-1 +- Updated to 118.0.2 + +* Fri Oct 06 2023 Alessandro Astone - 118.0.1-7 +- Don't include -x11 and -wayland desktop files in the main package (rhbz#2242523) + +* Fri Oct 6 2023 Martin Stransky - 118.0.1-6 +- Removed DBusActivatable flag from desktop file as it crashes KDE (rhbz#2242454). + +* Thu Oct 05 2023 Kalev Lember - 118.0.1-5 +- Fix flatpak build + +* Mon Oct 2 2023 Martin Stransky - 118.0.1-4 +- Updated man page + +* Mon Oct 2 2023 Martin Stransky - 118.0.1-3 +- Avoid to launch Firefox by gnome-shell search + +* Fri Sep 29 2023 Martin Stransky - 118.0.1-2 +- Use firefox.desktop again + +* Fri Sep 29 2023 Martin Stransky - 118.0.1-1 +- Updated to 118.0.1 + +* Wed Sep 27 2023 Neal Gompa - 118.0.1-1 +- Use system libraries for AV1, VP8, VP9, and WebP + +* Wed Sep 27 2023 Martin Stransky - 118.0-2 +- Fixed Gnome search provider + +* Mon Sep 25 2023 Martin Stransky - 118.0-1 +- Updated to 118.0 + +* Thu Sep 14 2023 Adam Williamson - 117.0.1-2 +- Pass --with-clang-path to fix build with clang 17 (rhbz#2239047) + +* Wed Sep 13 2023 Martin Stransky - 117.0.1-1 +- Updated to 117.0.1 + +* Wed Aug 30 2023 Martin Stransky - 117.0-2 +- Added fix for rhbz#2235654 + +* Mon Aug 28 2023 Martin Stransky - 117.0-1 +- Updated to 117.0 + +* Thu Aug 17 2023 Martin Stransky - 116.0.3-1 +- Updated to 116.0.3 + +* Wed Aug 16 2023 Martin Stransky - 116.0.2-2 +- Added Fedora customization patch + +* Mon Aug 7 2023 Martin Stransky - 116.0.2-1 +- Updated to 116.0.2 + +* Fri Aug 4 2023 Martin Stransky - 116.0.1-1 +- Updated to 116.0.1 + +* Wed Aug 2 2023 Martin Stransky - 116.0-3 +- Added Canvas/WebGL VA-API playback patch (D167159 / mzbz#1769747) + +* Mon Jul 31 2023 Martin Stransky - 116.0-2 +- Updated to 116.0 Build 2 + +* Thu Jul 27 2023 Martin Stransky - 116.0-1 +- Updated to 116.0 + +* Mon Jul 24 2023 Martin Stransky - 115.0.2-4 +- Don't set MOZ_GMP_PATH as it's configured by /etc/profile.d/gmpopenh264.sh + from mozilla-openh264 package. + +* Wed Jul 19 2023 Martin Stransky - 115.0.2-3 +- Fix the previous fix (rhbz#2221317) + +* Tue Jul 18 2023 Martin Stransky - 115.0.2-2 +- Don't overwrite MOZ_GMP_PATH (rhbz#2221317) + +* Mon Jul 17 2023 Martin Stransky - 115.0.2-1 +- Update to 115.0.2 + +* Tue Jul 11 2023 Dan Horák - 115.0-3 +- re-enable ppc64le (rhbz#2212748) + +* Thu Jun 29 2023 Martin Stransky - 115.0-2 +- Update to 115.0 +- Disabled LTO due to rhbz#2218885 + +* Thu Jun 29 2023 Martin Stransky - 114.0.2-3 +- Enable Elf-hack for PGO builds. + +* Thu Jun 22 2023 Martin Stransky - 114.0.2-2 +- Enable PGO/LTO again. + +* Tue Jun 20 2023 Martin Stransky - 114.0.2-1 +- Update to 114.0.2 + +* Mon Jun 05 2023 Martin Stransky - 114.0-1 +- Updated to 114.0 +- Disable webrtc on ppc64le +- Disabled ppc64le due t build issues (rhbz#2212748). + +* Wed May 24 2023 Martin Stransky - 113.0.1-4 +- Added patches from 113.0.2 +- Added Rust fix for Rawhide (mzbz#1831242). + +* Fri May 19 2023 Martin Stransky - 113.0.1-3 +- Disabled libproxy support due to regressions (rhbz#2207469) + +* Tue May 16 2023 Jan Grulich - 113.0.1-2 +- Backport libwebrtc commit 7b0d7f48fb + Fix fcntl call when duplicating a file descriptor + +* Mon May 15 2023 Martin Stransky - 113.0.1-1 +- Updated to 113.0.1 + +* Tue May 9 2023 Martin Stransky - 113.0-1 +- Updated to 113.0 + +* Thu Apr 27 2023 Martin Stransky - 112.0.2-1 +- Updated to 112.0.2 + +* Tue Apr 18 2023 Martin Stransky - 112.0.1-1 +- Updated to 112.0.1 +- Added fix for rhbz#2187000 +- Enabled system pixman (by G.Hojda) + +* Tue Apr 11 2023 Martin Stransky - 112.0-3 +- Added wayland window fix mzbz#1827429 + +* Thu Apr 6 2023 Martin Stransky - 112.0-2 +- Updated to 112.0 build 2 +- don't crash on wayland logging (mzbz#1826583/rhbz#2184842). + +* Wed Apr 5 2023 Martin Stransky - 112.0-1 +- Updated to 112.0 + +* Wed Apr 5 2023 Martin Stransky - 111.0.1-2 +- Don't override MOZ_USE_XINPUT2 in startup script (hrbz#2184297) by GalaxyMaster + +* Wed Mar 22 2023 Martin Stransky - 111.0.1-1 +- Updated to 111.0.1 + +* Tue Mar 21 2023 Jan Grulich - 111.0-3 +- libwebrtc: backport upstream fix/improvement for DmaBuf screen sharing + +* Tue Mar 21 2023 Martin Stransky - 111.0-2 +- Added libproxy support (rhbz#2177806) +- Added build fixes on arm + +* Mon Mar 20 2023 Martin Stransky - 111.0-1 +- Updated to 111.0 +- Disabled arm on F36 + +* Tue Feb 14 2023 Martin Stransky - 110.0-3 +- Updated to 110.0 build 3 + +* Mon Feb 13 2023 Martin Stransky - 110.0-2 +- Added fix for orca + +* Thu Feb 9 2023 Martin Stransky - 110.0-1 +- Updated to 110.0 + +* Tue Feb 7 2023 Martin Stransky - 109.0.1-2 +- Rawhide build fix + +* Wed Feb 1 2023 Martin Stransky - 109.0.1-1 +- Updated to 109.0.1 +- Added fix for rhbz#2147344 / mzbz#1813500. + +* Thu Jan 19 2023 Martin Stransky - 109.0-4 +- Removed mozbz#1809162 + +* Thu Jan 19 2023 Fedora Release Engineering - 109.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Tue Jan 17 2023 Martin Stransky - 109.0-2 +- Added VA-API fixes mozbz#1809162, mozbz#1801576 + +* Mon Jan 16 2023 Martin Stransky - 109.0-1 +- Update to 109.0 + +* Thu Jan 12 2023 Jan Horak - 108.0.2-1 +- Update to 108.0.2 + +* Mon Jan 09 2023 Kalev Lember - 108.0.1-4 +- Drop conditionals for F35 + +* Wed Dec 21 2022 Martin Stransky - 108.0.1-3 +- Added second arch build fix + +* Wed Dec 21 2022 Martin Stransky - 108.0.1-2 +- Added mozbz#1795851 [wayland] Crash buffer size (170x113) + is not divisible by scale (2) + +* Mon Dec 19 2022 Martin Stransky - 108.0.1-1 +- Update to 108.0.1 + +* Wed Dec 14 2022 Martin Stransky - 108.0-2 +- Update to 108.0 Build 2 +- Added fix for rhbz#2149821 + +* Tue Dec 6 2022 Martin Stransky - 108.0-1 +- Update to 108.0 + +* Tue Dec 6 2022 Martin Stransky - 107.0.1-1 +- Update to 107.0.1 + +* Thu Nov 24 2022 Martin Stransky - 107.0-4 +- Added fix for mozbz#1779186 - fix VA-API playback artifacts + +* Mon Nov 21 2022 Martin Stransky - 107.0-3 +- Disabled crashreporter + +* Mon Nov 21 2022 Jan Horak - 107.0-2 +- Enabled mozilla crashreporter again + +* Mon Nov 14 2022 Martin Stransky - 107.0-1 +- Update to 107.0 + +* Fri Nov 04 2022 Martin Stransky - 106.0.4-1 +- Update to 106.0.4 + +* Mon Oct 31 2022 Martin Stransky - 106.0.3-1 +- Update to 106.0.3 + +* Sun Oct 23 2022 Martin Stransky - 106.0.1-1 +- Update to 106.0.1 +- Require xdg-desktop-portal when file dialog portal is used. +- Disabled file dialog portals on F37+ + +* Thu Oct 20 2022 Jan Grulich - 106.0-2 +- Enable upstream WebRTC code for screensharing on Wayland + +* Fri Oct 14 2022 Martin Stransky - 106.0-1 +- Updated to 106.0 +- Disabled PGO build due to rhbz#2136401 + +* Fri Oct 14 2022 Martin Stransky - 105.0.2-2 +- Fixed crashes on multi-monitor systems (mzbz#1793922) + +* Wed Oct 5 2022 Martin Stransky - 105.0.2-1 +- Updated to 105.0.2 + +* Fri Sep 30 2022 Martin Stransky - 105.0.1-2 +- Added fix for mozilla#1791856 / rhbz#2130087 + +* Thu Sep 22 2022 Martin Stransky - 105.0.1-1 +- Updated to 105.0.1 +- Excluded i686 due to https://bugzilla.mozilla.org/show_bug.cgi?id=1792159, + https://bugzilla.redhat.com/show_bug.cgi?id=2129720 + +* Tue Sep 20 2022 Martin Stransky - 105.0-1 +- Updated to 105.0 + +* Tue Sep 6 2022 Martin Stransky - 104.0.2-1 +- Updated to 104.0.2 + +* Tue Aug 30 2022 Martin Stransky - 104.0.1-1 +- Updated to 104.0.1 + +* Tue Aug 23 2022 Kalev Lember - 104.0-5 +- Use constrain_build macro to simplify parallel make handling +- Drop obsolete build conditionals +- Drop unused patches +- Use build_ldflags +- Drop hardened_build option +- Re-enable s390x builds + +* Tue Aug 23 2022 Jan Horak - 104.0-4 +- Rebuild due to ppc64le fixes + +* Mon Aug 22 2022 Eike Rathke - 104.0-3 +- Update to 104.0 respin + +* Wed Aug 17 2022 Martin Stransky - 104.0-2 +- Added build fixes + +* Tue Aug 16 2022 Martin Stransky - 104.0-1 +- Updated to 104.0 + +* Fri Aug 12 2022 Martin Stransky - 103.0.2-1 +- Updated to 103.0.2 + +* Thu Aug 4 2022 Martin Stransky - 103.0.1-2 +- Added arm build fixes by Gabriel Hojda +- Enable VA-API (rhbz#2115253) + +* Tue Aug 2 2022 Martin Stransky - 103.0.1-1 +- Update to 103.0.1 + +* Tue Jul 26 2022 Martin Stransky - 103.0-1 +- Update to 103.0 +- Disabled ppc64le due to webrtc build failures (rhbz#2113850) + +* Thu Jul 21 2022 Fedora Release Engineering - 102.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Wed Jul 13 2022 Martin Stransky - 102.0-3 +- Update preference logging. +- Added ARM fixes by Gabriel Hojda. + +* Mon Jul 11 2022 Jan Grulich - 102.0-2 +- Backport upstream fixes to WebRTC for screensharing on Wayland + +* Tue Jun 28 2022 Martin Stransky - 102.0-1 +- Updated to 102.0 +- Applied patch from https://src.fedoraproject.org/rpms/firefox/pull-request/43 + +* Mon Jun 27 2022 Martin Stransky - 101.0.1-7 +- Rebuild + +* Fri Jun 17 2022 Martin Stransky - 101.0.1-6 +- Added fix for mozbz#1774271 - Intel/dmabuf export issues. + +* Wed Jun 15 2022 Martin Stransky - 101.0.1-5 +- Added fix for mozbz#1758948 (AV1 VA-API playback shuttering) + +* Tue Jun 14 2022 Martin Stransky - 101.0.1-3 +- Added fixes for mozbz#1773377 and mozbz#1774075 + +* Mon Jun 13 2022 Martin Stransky - 101.0.1-2 +- Fix WebGL mem leaks (mzbz#1773968) + +* Thu Jun 9 2022 Martin Stransky - 101.0.1-1 +- Updated to 101.0.1 +- More VA-API sandbox fixes (mzbz#1769182) +- Fixed OpenH264 decode (rhbz#2094319) + +* Tue Jun 7 2022 Martin Stransky - 101.0-2 +- Enabled VA-API by default (+ added VA-API fixes from upstream) +- Fixed WebGL performance on NVIDIA drivers (mzbz#1735929) + * Mon May 30 2022 Martin Stransky - 101.0-1 - Updated to 101.0 diff --git a/fix-cargo-checksum b/fix-cargo-checksum new file mode 100755 index 0000000..bae2b2d --- /dev/null +++ b/fix-cargo-checksum @@ -0,0 +1,21 @@ +#!/bin/bash +if [ -z $1 ]; then + echo "Fixes .cargo-checksum.json by removing deleted files and recompute sha256sum" + echo "Usage: $0 .cargo-checksum.json" + exit +fi + +FILE=$1 +#set -x +cp $FILE $1.backup +for i in $(cat .cargo-checksum.json|jq -r '.files| keys[]'); do +if [ ! -f $i ]; then + #echo $i non exist + sed -ie "s|\"$i\":\"[^\"]*\",||" $FILE +else + SHA=`sha256sum $i | cut -d " " -f1` + sed -ie "s|\"$i\":\"[^\"]*\"|\"$i\":\"$SHA\"|" $FILE +fi + +#echo $i +done diff --git a/gen_cbindgen-vendor.sh b/gen_cbindgen-vendor.sh index 395613f..5711901 100755 --- a/gen_cbindgen-vendor.sh +++ b/gen_cbindgen-vendor.sh @@ -12,7 +12,7 @@ to be used with 'cargo vendor' commmand. """ [dependencies] -cbindgen = "0.19.0" +cbindgen = "0.29.1" [[bin]] name = "dummy" diff --git a/gen_dump_syms-vendor.sh b/gen_dump_syms-vendor.sh new file mode 100755 index 0000000..3854ad8 --- /dev/null +++ b/gen_dump_syms-vendor.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -x + +# Dummy Cargo.toml file with cbindgen dependency +cat > Cargo.toml < -Date: Mon, 21 Feb 2022 15:34:52 +0100 -Subject: WebRTC - screen cast sync - - -diff --git a/dom/media/webrtc/third_party_build/moz.build b/dom/media/webrtc/third_party_build/moz.build -index e4c7ba7..a42f913 100644 ---- a/dom/media/webrtc/third_party_build/moz.build -+++ b/dom/media/webrtc/third_party_build/moz.build -@@ -63,6 +63,8 @@ webrtc_non_unified_sources = [ - - if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": - DIRS += ["../../../../third_party/pipewire/libpipewire"] -+ DIRS += ["../../../../third_party/drm/libdrm"] -+ DIRS += ["../../../../third_party/gbm/libgbm"] - - GN_DIRS += ["../../../../third_party/libwebrtc"] - -diff --git a/third_party/drm/README b/third_party/drm/README -new file mode 100644 -index 0000000..f68ed10 ---- /dev/null -+++ b/third_party/drm/README -@@ -0,0 +1,4 @@ -+Libdrm is a drm library wrapper needed to build and run Firefox with -+Pipewire support on Linux (https://gitlab.freedesktop.org/mesa/drm). -+ -+libdrm directory stores headers of libdrm needed for build only. -diff --git a/third_party/drm/drm/drm.h b/third_party/drm/drm/drm.h -new file mode 100644 -index 0000000..5e54c3a ---- /dev/null -+++ b/third_party/drm/drm/drm.h -@@ -0,0 +1,1193 @@ -+/* -+ * Header for the Direct Rendering Manager -+ * -+ * Author: Rickard E. (Rik) Faith -+ * -+ * Acknowledgments: -+ * Dec 1999, Richard Henderson , move to generic cmpxchg. -+ */ -+ -+/* -+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. -+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. -+ * All rights reserved. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef _DRM_H_ -+#define _DRM_H_ -+ -+#if defined(__linux__) -+ -+#include -+#include -+typedef unsigned int drm_handle_t; -+ -+#else /* One of the BSDs */ -+ -+#include -+#include -+#include -+typedef int8_t __s8; -+typedef uint8_t __u8; -+typedef int16_t __s16; -+typedef uint16_t __u16; -+typedef int32_t __s32; -+typedef uint32_t __u32; -+typedef int64_t __s64; -+typedef uint64_t __u64; -+typedef size_t __kernel_size_t; -+typedef unsigned long drm_handle_t; -+ -+#endif -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */ -+#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */ -+#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */ -+#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */ -+ -+#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ -+#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ -+#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD) -+#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT) -+#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) -+ -+typedef unsigned int drm_context_t; -+typedef unsigned int drm_drawable_t; -+typedef unsigned int drm_magic_t; -+ -+/* -+ * Cliprect. -+ * -+ * \warning: If you change this structure, make sure you change -+ * XF86DRIClipRectRec in the server as well -+ * -+ * \note KW: Actually it's illegal to change either for -+ * backwards-compatibility reasons. -+ */ -+struct drm_clip_rect { -+ unsigned short x1; -+ unsigned short y1; -+ unsigned short x2; -+ unsigned short y2; -+}; -+ -+/* -+ * Drawable information. -+ */ -+struct drm_drawable_info { -+ unsigned int num_rects; -+ struct drm_clip_rect *rects; -+}; -+ -+/* -+ * Texture region, -+ */ -+struct drm_tex_region { -+ unsigned char next; -+ unsigned char prev; -+ unsigned char in_use; -+ unsigned char padding; -+ unsigned int age; -+}; -+ -+/* -+ * Hardware lock. -+ * -+ * The lock structure is a simple cache-line aligned integer. To avoid -+ * processor bus contention on a multiprocessor system, there should not be any -+ * other data stored in the same cache line. -+ */ -+struct drm_hw_lock { -+ __volatile__ unsigned int lock; /**< lock variable */ -+ char padding[60]; /**< Pad to cache line */ -+}; -+ -+/* -+ * DRM_IOCTL_VERSION ioctl argument type. -+ * -+ * \sa drmGetVersion(). -+ */ -+struct drm_version { -+ int version_major; /**< Major version */ -+ int version_minor; /**< Minor version */ -+ int version_patchlevel; /**< Patch level */ -+ __kernel_size_t name_len; /**< Length of name buffer */ -+ char *name; /**< Name of driver */ -+ __kernel_size_t date_len; /**< Length of date buffer */ -+ char *date; /**< User-space buffer to hold date */ -+ __kernel_size_t desc_len; /**< Length of desc buffer */ -+ char *desc; /**< User-space buffer to hold desc */ -+}; -+ -+/* -+ * DRM_IOCTL_GET_UNIQUE ioctl argument type. -+ * -+ * \sa drmGetBusid() and drmSetBusId(). -+ */ -+struct drm_unique { -+ __kernel_size_t unique_len; /**< Length of unique */ -+ char *unique; /**< Unique name for driver instantiation */ -+}; -+ -+struct drm_list { -+ int count; /**< Length of user-space structures */ -+ struct drm_version *version; -+}; -+ -+struct drm_block { -+ int unused; -+}; -+ -+/* -+ * DRM_IOCTL_CONTROL ioctl argument type. -+ * -+ * \sa drmCtlInstHandler() and drmCtlUninstHandler(). -+ */ -+struct drm_control { -+ enum { -+ DRM_ADD_COMMAND, -+ DRM_RM_COMMAND, -+ DRM_INST_HANDLER, -+ DRM_UNINST_HANDLER -+ } func; -+ int irq; -+}; -+ -+/* -+ * Type of memory to map. -+ */ -+enum drm_map_type { -+ _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */ -+ _DRM_REGISTERS = 1, /**< no caching, no core dump */ -+ _DRM_SHM = 2, /**< shared, cached */ -+ _DRM_AGP = 3, /**< AGP/GART */ -+ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ -+ _DRM_CONSISTENT = 5 /**< Consistent memory for PCI DMA */ -+}; -+ -+/* -+ * Memory mapping flags. -+ */ -+enum drm_map_flags { -+ _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */ -+ _DRM_READ_ONLY = 0x02, -+ _DRM_LOCKED = 0x04, /**< shared, cached, locked */ -+ _DRM_KERNEL = 0x08, /**< kernel requires access */ -+ _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ -+ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ -+ _DRM_REMOVABLE = 0x40, /**< Removable mapping */ -+ _DRM_DRIVER = 0x80 /**< Managed by driver */ -+}; -+ -+struct drm_ctx_priv_map { -+ unsigned int ctx_id; /**< Context requesting private mapping */ -+ void *handle; /**< Handle of map */ -+}; -+ -+/* -+ * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls -+ * argument type. -+ * -+ * \sa drmAddMap(). -+ */ -+struct drm_map { -+ unsigned long offset; /**< Requested physical address (0 for SAREA)*/ -+ unsigned long size; /**< Requested physical size (bytes) */ -+ enum drm_map_type type; /**< Type of memory to map */ -+ enum drm_map_flags flags; /**< Flags */ -+ void *handle; /**< User-space: "Handle" to pass to mmap() */ -+ /**< Kernel-space: kernel-virtual address */ -+ int mtrr; /**< MTRR slot used */ -+ /* Private data */ -+}; -+ -+/* -+ * DRM_IOCTL_GET_CLIENT ioctl argument type. -+ */ -+struct drm_client { -+ int idx; /**< Which client desired? */ -+ int auth; /**< Is client authenticated? */ -+ unsigned long pid; /**< Process ID */ -+ unsigned long uid; /**< User ID */ -+ unsigned long magic; /**< Magic */ -+ unsigned long iocs; /**< Ioctl count */ -+}; -+ -+enum drm_stat_type { -+ _DRM_STAT_LOCK, -+ _DRM_STAT_OPENS, -+ _DRM_STAT_CLOSES, -+ _DRM_STAT_IOCTLS, -+ _DRM_STAT_LOCKS, -+ _DRM_STAT_UNLOCKS, -+ _DRM_STAT_VALUE, /**< Generic value */ -+ _DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */ -+ _DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */ -+ -+ _DRM_STAT_IRQ, /**< IRQ */ -+ _DRM_STAT_PRIMARY, /**< Primary DMA bytes */ -+ _DRM_STAT_SECONDARY, /**< Secondary DMA bytes */ -+ _DRM_STAT_DMA, /**< DMA */ -+ _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */ -+ _DRM_STAT_MISSED /**< Missed DMA opportunity */ -+ /* Add to the *END* of the list */ -+}; -+ -+/* -+ * DRM_IOCTL_GET_STATS ioctl argument type. -+ */ -+struct drm_stats { -+ unsigned long count; -+ struct { -+ unsigned long value; -+ enum drm_stat_type type; -+ } data[15]; -+}; -+ -+/* -+ * Hardware locking flags. -+ */ -+enum drm_lock_flags { -+ _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ -+ _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ -+ _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ -+ _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ -+ /* These *HALT* flags aren't supported yet -+ -- they will be used to support the -+ full-screen DGA-like mode. */ -+ _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ -+ _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ -+}; -+ -+/* -+ * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type. -+ * -+ * \sa drmGetLock() and drmUnlock(). -+ */ -+struct drm_lock { -+ int context; -+ enum drm_lock_flags flags; -+}; -+ -+/* -+ * DMA flags -+ * -+ * \warning -+ * These values \e must match xf86drm.h. -+ * -+ * \sa drm_dma. -+ */ -+enum drm_dma_flags { -+ /* Flags for DMA buffer dispatch */ -+ _DRM_DMA_BLOCK = 0x01, /**< -+ * Block until buffer dispatched. -+ * -+ * \note The buffer may not yet have -+ * been processed by the hardware -- -+ * getting a hardware lock with the -+ * hardware quiescent will ensure -+ * that the buffer has been -+ * processed. -+ */ -+ _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ -+ _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ -+ -+ /* Flags for DMA buffer request */ -+ _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ -+ _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ -+ _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ -+}; -+ -+/* -+ * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type. -+ * -+ * \sa drmAddBufs(). -+ */ -+struct drm_buf_desc { -+ int count; /**< Number of buffers of this size */ -+ int size; /**< Size in bytes */ -+ int low_mark; /**< Low water mark */ -+ int high_mark; /**< High water mark */ -+ enum { -+ _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */ -+ _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */ -+ _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */ -+ _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */ -+ _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */ -+ } flags; -+ unsigned long agp_start; /**< -+ * Start address of where the AGP buffers are -+ * in the AGP aperture -+ */ -+}; -+ -+/* -+ * DRM_IOCTL_INFO_BUFS ioctl argument type. -+ */ -+struct drm_buf_info { -+ int count; /**< Entries in list */ -+ struct drm_buf_desc *list; -+}; -+ -+/* -+ * DRM_IOCTL_FREE_BUFS ioctl argument type. -+ */ -+struct drm_buf_free { -+ int count; -+ int *list; -+}; -+ -+/* -+ * Buffer information -+ * -+ * \sa drm_buf_map. -+ */ -+struct drm_buf_pub { -+ int idx; /**< Index into the master buffer list */ -+ int total; /**< Buffer size */ -+ int used; /**< Amount of buffer in use (for DMA) */ -+ void *address; /**< Address of buffer */ -+}; -+ -+/* -+ * DRM_IOCTL_MAP_BUFS ioctl argument type. -+ */ -+struct drm_buf_map { -+ int count; /**< Length of the buffer list */ -+#ifdef __cplusplus -+ void *virt; -+#else -+ void *virtual; /**< Mmap'd area in user-virtual */ -+#endif -+ struct drm_buf_pub *list; /**< Buffer information */ -+}; -+ -+/* -+ * DRM_IOCTL_DMA ioctl argument type. -+ * -+ * Indices here refer to the offset into the buffer list in drm_buf_get. -+ * -+ * \sa drmDMA(). -+ */ -+struct drm_dma { -+ int context; /**< Context handle */ -+ int send_count; /**< Number of buffers to send */ -+ int *send_indices; /**< List of handles to buffers */ -+ int *send_sizes; /**< Lengths of data to send */ -+ enum drm_dma_flags flags; /**< Flags */ -+ int request_count; /**< Number of buffers requested */ -+ int request_size; /**< Desired size for buffers */ -+ int *request_indices; /**< Buffer information */ -+ int *request_sizes; -+ int granted_count; /**< Number of buffers granted */ -+}; -+ -+enum drm_ctx_flags { -+ _DRM_CONTEXT_PRESERVED = 0x01, -+ _DRM_CONTEXT_2DONLY = 0x02 -+}; -+ -+/* -+ * DRM_IOCTL_ADD_CTX ioctl argument type. -+ * -+ * \sa drmCreateContext() and drmDestroyContext(). -+ */ -+struct drm_ctx { -+ drm_context_t handle; -+ enum drm_ctx_flags flags; -+}; -+ -+/* -+ * DRM_IOCTL_RES_CTX ioctl argument type. -+ */ -+struct drm_ctx_res { -+ int count; -+ struct drm_ctx *contexts; -+}; -+ -+/* -+ * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type. -+ */ -+struct drm_draw { -+ drm_drawable_t handle; -+}; -+ -+/* -+ * DRM_IOCTL_UPDATE_DRAW ioctl argument type. -+ */ -+typedef enum { -+ DRM_DRAWABLE_CLIPRECTS -+} drm_drawable_info_type_t; -+ -+struct drm_update_draw { -+ drm_drawable_t handle; -+ unsigned int type; -+ unsigned int num; -+ unsigned long long data; -+}; -+ -+/* -+ * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type. -+ */ -+struct drm_auth { -+ drm_magic_t magic; -+}; -+ -+/* -+ * DRM_IOCTL_IRQ_BUSID ioctl argument type. -+ * -+ * \sa drmGetInterruptFromBusID(). -+ */ -+struct drm_irq_busid { -+ int irq; /**< IRQ number */ -+ int busnum; /**< bus number */ -+ int devnum; /**< device number */ -+ int funcnum; /**< function number */ -+}; -+ -+enum drm_vblank_seq_type { -+ _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ -+ _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ -+ /* bits 1-6 are reserved for high crtcs */ -+ _DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e, -+ _DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ -+ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ -+ _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ -+ _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ -+ _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking, unsupported */ -+}; -+#define _DRM_VBLANK_HIGH_CRTC_SHIFT 1 -+ -+#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE) -+#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_EVENT | _DRM_VBLANK_SIGNAL | \ -+ _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS) -+ -+struct drm_wait_vblank_request { -+ enum drm_vblank_seq_type type; -+ unsigned int sequence; -+ unsigned long signal; -+}; -+ -+struct drm_wait_vblank_reply { -+ enum drm_vblank_seq_type type; -+ unsigned int sequence; -+ long tval_sec; -+ long tval_usec; -+}; -+ -+/* -+ * DRM_IOCTL_WAIT_VBLANK ioctl argument type. -+ * -+ * \sa drmWaitVBlank(). -+ */ -+union drm_wait_vblank { -+ struct drm_wait_vblank_request request; -+ struct drm_wait_vblank_reply reply; -+}; -+ -+#define _DRM_PRE_MODESET 1 -+#define _DRM_POST_MODESET 2 -+ -+/* -+ * DRM_IOCTL_MODESET_CTL ioctl argument type -+ * -+ * \sa drmModesetCtl(). -+ */ -+struct drm_modeset_ctl { -+ __u32 crtc; -+ __u32 cmd; -+}; -+ -+/* -+ * DRM_IOCTL_AGP_ENABLE ioctl argument type. -+ * -+ * \sa drmAgpEnable(). -+ */ -+struct drm_agp_mode { -+ unsigned long mode; /**< AGP mode */ -+}; -+ -+/* -+ * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type. -+ * -+ * \sa drmAgpAlloc() and drmAgpFree(). -+ */ -+struct drm_agp_buffer { -+ unsigned long size; /**< In bytes -- will round to page boundary */ -+ unsigned long handle; /**< Used for binding / unbinding */ -+ unsigned long type; /**< Type of memory to allocate */ -+ unsigned long physical; /**< Physical used by i810 */ -+}; -+ -+/* -+ * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type. -+ * -+ * \sa drmAgpBind() and drmAgpUnbind(). -+ */ -+struct drm_agp_binding { -+ unsigned long handle; /**< From drm_agp_buffer */ -+ unsigned long offset; /**< In bytes -- will round to page boundary */ -+}; -+ -+/* -+ * DRM_IOCTL_AGP_INFO ioctl argument type. -+ * -+ * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(), -+ * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(), -+ * drmAgpVendorId() and drmAgpDeviceId(). -+ */ -+struct drm_agp_info { -+ int agp_version_major; -+ int agp_version_minor; -+ unsigned long mode; -+ unsigned long aperture_base; /* physical address */ -+ unsigned long aperture_size; /* bytes */ -+ unsigned long memory_allowed; /* bytes */ -+ unsigned long memory_used; -+ -+ /* PCI information */ -+ unsigned short id_vendor; -+ unsigned short id_device; -+}; -+ -+/* -+ * DRM_IOCTL_SG_ALLOC ioctl argument type. -+ */ -+struct drm_scatter_gather { -+ unsigned long size; /**< In bytes -- will round to page boundary */ -+ unsigned long handle; /**< Used for mapping / unmapping */ -+}; -+ -+/* -+ * DRM_IOCTL_SET_VERSION ioctl argument type. -+ */ -+struct drm_set_version { -+ int drm_di_major; -+ int drm_di_minor; -+ int drm_dd_major; -+ int drm_dd_minor; -+}; -+ -+/* DRM_IOCTL_GEM_CLOSE ioctl argument type */ -+struct drm_gem_close { -+ /** Handle of the object to be closed. */ -+ __u32 handle; -+ __u32 pad; -+}; -+ -+/* DRM_IOCTL_GEM_FLINK ioctl argument type */ -+struct drm_gem_flink { -+ /** Handle for the object being named */ -+ __u32 handle; -+ -+ /** Returned global name */ -+ __u32 name; -+}; -+ -+/* DRM_IOCTL_GEM_OPEN ioctl argument type */ -+struct drm_gem_open { -+ /** Name of object being opened */ -+ __u32 name; -+ -+ /** Returned handle for the object */ -+ __u32 handle; -+ -+ /** Returned size of the object */ -+ __u64 size; -+}; -+ -+/** -+ * DRM_CAP_DUMB_BUFFER -+ * -+ * If set to 1, the driver supports creating dumb buffers via the -+ * &DRM_IOCTL_MODE_CREATE_DUMB ioctl. -+ */ -+#define DRM_CAP_DUMB_BUFFER 0x1 -+/** -+ * DRM_CAP_VBLANK_HIGH_CRTC -+ * -+ * If set to 1, the kernel supports specifying a :ref:`CRTC index` -+ * in the high bits of &drm_wait_vblank_request.type. -+ * -+ * Starting kernel version 2.6.39, this capability is always set to 1. -+ */ -+#define DRM_CAP_VBLANK_HIGH_CRTC 0x2 -+/** -+ * DRM_CAP_DUMB_PREFERRED_DEPTH -+ * -+ * The preferred bit depth for dumb buffers. -+ * -+ * The bit depth is the number of bits used to indicate the color of a single -+ * pixel excluding any padding. This is different from the number of bits per -+ * pixel. For instance, XRGB8888 has a bit depth of 24 but has 32 bits per -+ * pixel. -+ * -+ * Note that this preference only applies to dumb buffers, it's irrelevant for -+ * other types of buffers. -+ */ -+#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3 -+/** -+ * DRM_CAP_DUMB_PREFER_SHADOW -+ * -+ * If set to 1, the driver prefers userspace to render to a shadow buffer -+ * instead of directly rendering to a dumb buffer. For best speed, userspace -+ * should do streaming ordered memory copies into the dumb buffer and never -+ * read from it. -+ * -+ * Note that this preference only applies to dumb buffers, it's irrelevant for -+ * other types of buffers. -+ */ -+#define DRM_CAP_DUMB_PREFER_SHADOW 0x4 -+/** -+ * DRM_CAP_PRIME -+ * -+ * Bitfield of supported PRIME sharing capabilities. See &DRM_PRIME_CAP_IMPORT -+ * and &DRM_PRIME_CAP_EXPORT. -+ * -+ * PRIME buffers are exposed as dma-buf file descriptors. See -+ * Documentation/gpu/drm-mm.rst, section "PRIME Buffer Sharing". -+ */ -+#define DRM_CAP_PRIME 0x5 -+/** -+ * DRM_PRIME_CAP_IMPORT -+ * -+ * If this bit is set in &DRM_CAP_PRIME, the driver supports importing PRIME -+ * buffers via the &DRM_IOCTL_PRIME_FD_TO_HANDLE ioctl. -+ */ -+#define DRM_PRIME_CAP_IMPORT 0x1 -+/** -+ * DRM_PRIME_CAP_EXPORT -+ * -+ * If this bit is set in &DRM_CAP_PRIME, the driver supports exporting PRIME -+ * buffers via the &DRM_IOCTL_PRIME_HANDLE_TO_FD ioctl. -+ */ -+#define DRM_PRIME_CAP_EXPORT 0x2 -+/** -+ * DRM_CAP_TIMESTAMP_MONOTONIC -+ * -+ * If set to 0, the kernel will report timestamps with ``CLOCK_REALTIME`` in -+ * struct drm_event_vblank. If set to 1, the kernel will report timestamps with -+ * ``CLOCK_MONOTONIC``. See ``clock_gettime(2)`` for the definition of these -+ * clocks. -+ * -+ * Starting from kernel version 2.6.39, the default value for this capability -+ * is 1. Starting kernel version 4.15, this capability is always set to 1. -+ */ -+#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6 -+/** -+ * DRM_CAP_ASYNC_PAGE_FLIP -+ * -+ * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC. -+ */ -+#define DRM_CAP_ASYNC_PAGE_FLIP 0x7 -+/** -+ * DRM_CAP_CURSOR_WIDTH -+ * -+ * The ``CURSOR_WIDTH`` and ``CURSOR_HEIGHT`` capabilities return a valid -+ * width x height combination for the hardware cursor. The intention is that a -+ * hardware agnostic userspace can query a cursor plane size to use. -+ * -+ * Note that the cross-driver contract is to merely return a valid size; -+ * drivers are free to attach another meaning on top, eg. i915 returns the -+ * maximum plane size. -+ */ -+#define DRM_CAP_CURSOR_WIDTH 0x8 -+/** -+ * DRM_CAP_CURSOR_HEIGHT -+ * -+ * See &DRM_CAP_CURSOR_WIDTH. -+ */ -+#define DRM_CAP_CURSOR_HEIGHT 0x9 -+/** -+ * DRM_CAP_ADDFB2_MODIFIERS -+ * -+ * If set to 1, the driver supports supplying modifiers in the -+ * &DRM_IOCTL_MODE_ADDFB2 ioctl. -+ */ -+#define DRM_CAP_ADDFB2_MODIFIERS 0x10 -+/** -+ * DRM_CAP_PAGE_FLIP_TARGET -+ * -+ * If set to 1, the driver supports the &DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE and -+ * &DRM_MODE_PAGE_FLIP_TARGET_RELATIVE flags in -+ * &drm_mode_crtc_page_flip_target.flags for the &DRM_IOCTL_MODE_PAGE_FLIP -+ * ioctl. -+ */ -+#define DRM_CAP_PAGE_FLIP_TARGET 0x11 -+/** -+ * DRM_CAP_CRTC_IN_VBLANK_EVENT -+ * -+ * If set to 1, the kernel supports reporting the CRTC ID in -+ * &drm_event_vblank.crtc_id for the &DRM_EVENT_VBLANK and -+ * &DRM_EVENT_FLIP_COMPLETE events. -+ * -+ * Starting kernel version 4.12, this capability is always set to 1. -+ */ -+#define DRM_CAP_CRTC_IN_VBLANK_EVENT 0x12 -+/** -+ * DRM_CAP_SYNCOBJ -+ * -+ * If set to 1, the driver supports sync objects. See -+ * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects". -+ */ -+#define DRM_CAP_SYNCOBJ 0x13 -+/** -+ * DRM_CAP_SYNCOBJ_TIMELINE -+ * -+ * If set to 1, the driver supports timeline operations on sync objects. See -+ * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects". -+ */ -+#define DRM_CAP_SYNCOBJ_TIMELINE 0x14 -+ -+/* DRM_IOCTL_GET_CAP ioctl argument type */ -+struct drm_get_cap { -+ __u64 capability; -+ __u64 value; -+}; -+ -+/** -+ * DRM_CLIENT_CAP_STEREO_3D -+ * -+ * If set to 1, the DRM core will expose the stereo 3D capabilities of the -+ * monitor by advertising the supported 3D layouts in the flags of struct -+ * drm_mode_modeinfo. See ``DRM_MODE_FLAG_3D_*``. -+ * -+ * This capability is always supported for all drivers starting from kernel -+ * version 3.13. -+ */ -+#define DRM_CLIENT_CAP_STEREO_3D 1 -+ -+/** -+ * DRM_CLIENT_CAP_UNIVERSAL_PLANES -+ * -+ * If set to 1, the DRM core will expose all planes (overlay, primary, and -+ * cursor) to userspace. -+ * -+ * This capability has been introduced in kernel version 3.15. Starting from -+ * kernel version 3.17, this capability is always supported for all drivers. -+ */ -+#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2 -+ -+/** -+ * DRM_CLIENT_CAP_ATOMIC -+ * -+ * If set to 1, the DRM core will expose atomic properties to userspace. This -+ * implicitly enables &DRM_CLIENT_CAP_UNIVERSAL_PLANES and -+ * &DRM_CLIENT_CAP_ASPECT_RATIO. -+ * -+ * If the driver doesn't support atomic mode-setting, enabling this capability -+ * will fail with -EOPNOTSUPP. -+ * -+ * This capability has been introduced in kernel version 4.0. Starting from -+ * kernel version 4.2, this capability is always supported for atomic-capable -+ * drivers. -+ */ -+#define DRM_CLIENT_CAP_ATOMIC 3 -+ -+/** -+ * DRM_CLIENT_CAP_ASPECT_RATIO -+ * -+ * If set to 1, the DRM core will provide aspect ratio information in modes. -+ * See ``DRM_MODE_FLAG_PIC_AR_*``. -+ * -+ * This capability is always supported for all drivers starting from kernel -+ * version 4.18. -+ */ -+#define DRM_CLIENT_CAP_ASPECT_RATIO 4 -+ -+/** -+ * DRM_CLIENT_CAP_WRITEBACK_CONNECTORS -+ * -+ * If set to 1, the DRM core will expose special connectors to be used for -+ * writing back to memory the scene setup in the commit. The client must enable -+ * &DRM_CLIENT_CAP_ATOMIC first. -+ * -+ * This capability is always supported for atomic-capable drivers starting from -+ * kernel version 4.19. -+ */ -+#define DRM_CLIENT_CAP_WRITEBACK_CONNECTORS 5 -+ -+/* DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ -+struct drm_set_client_cap { -+ __u64 capability; -+ __u64 value; -+}; -+ -+#define DRM_RDWR O_RDWR -+#define DRM_CLOEXEC O_CLOEXEC -+struct drm_prime_handle { -+ __u32 handle; -+ -+ /** Flags.. only applicable for handle->fd */ -+ __u32 flags; -+ -+ /** Returned dmabuf file descriptor */ -+ __s32 fd; -+}; -+ -+struct drm_syncobj_create { -+ __u32 handle; -+#define DRM_SYNCOBJ_CREATE_SIGNALED (1 << 0) -+ __u32 flags; -+}; -+ -+struct drm_syncobj_destroy { -+ __u32 handle; -+ __u32 pad; -+}; -+ -+#define DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE (1 << 0) -+#define DRM_SYNCOBJ_HANDLE_TO_FD_FLAGS_EXPORT_SYNC_FILE (1 << 0) -+struct drm_syncobj_handle { -+ __u32 handle; -+ __u32 flags; -+ -+ __s32 fd; -+ __u32 pad; -+}; -+ -+struct drm_syncobj_transfer { -+ __u32 src_handle; -+ __u32 dst_handle; -+ __u64 src_point; -+ __u64 dst_point; -+ __u32 flags; -+ __u32 pad; -+}; -+ -+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_ALL (1 << 0) -+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT (1 << 1) -+#define DRM_SYNCOBJ_WAIT_FLAGS_WAIT_AVAILABLE (1 << 2) /* wait for time point to become available */ -+struct drm_syncobj_wait { -+ __u64 handles; -+ /* absolute timeout */ -+ __s64 timeout_nsec; -+ __u32 count_handles; -+ __u32 flags; -+ __u32 first_signaled; /* only valid when not waiting all */ -+ __u32 pad; -+}; -+ -+struct drm_syncobj_timeline_wait { -+ __u64 handles; -+ /* wait on specific timeline point for every handles*/ -+ __u64 points; -+ /* absolute timeout */ -+ __s64 timeout_nsec; -+ __u32 count_handles; -+ __u32 flags; -+ __u32 first_signaled; /* only valid when not waiting all */ -+ __u32 pad; -+}; -+ -+ -+struct drm_syncobj_array { -+ __u64 handles; -+ __u32 count_handles; -+ __u32 pad; -+}; -+ -+#define DRM_SYNCOBJ_QUERY_FLAGS_LAST_SUBMITTED (1 << 0) /* last available point on timeline syncobj */ -+struct drm_syncobj_timeline_array { -+ __u64 handles; -+ __u64 points; -+ __u32 count_handles; -+ __u32 flags; -+}; -+ -+ -+/* Query current scanout sequence number */ -+struct drm_crtc_get_sequence { -+ __u32 crtc_id; /* requested crtc_id */ -+ __u32 active; /* return: crtc output is active */ -+ __u64 sequence; /* return: most recent vblank sequence */ -+ __s64 sequence_ns; /* return: most recent time of first pixel out */ -+}; -+ -+/* Queue event to be delivered at specified sequence. Time stamp marks -+ * when the first pixel of the refresh cycle leaves the display engine -+ * for the display -+ */ -+#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001 /* sequence is relative to current */ -+#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002 /* Use next sequence if we've missed */ -+ -+struct drm_crtc_queue_sequence { -+ __u32 crtc_id; -+ __u32 flags; -+ __u64 sequence; /* on input, target sequence. on output, actual sequence */ -+ __u64 user_data; /* user data passed to event */ -+}; -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#include "drm_mode.h" -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+#define DRM_IOCTL_BASE 'd' -+#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -+#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) -+#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type) -+#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type) -+ -+#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version) -+#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique) -+#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth) -+#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid) -+#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map) -+#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client) -+#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats) -+#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version) -+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl) -+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close) -+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink) -+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open) -+#define DRM_IOCTL_GET_CAP DRM_IOWR(0x0c, struct drm_get_cap) -+#define DRM_IOCTL_SET_CLIENT_CAP DRM_IOW( 0x0d, struct drm_set_client_cap) -+ -+#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique) -+#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth) -+#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block) -+#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block) -+#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control) -+#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map) -+#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc) -+#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc) -+#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info) -+#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map) -+#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free) -+ -+#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map) -+ -+#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) -+#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) -+ -+#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) -+#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) -+ -+#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) -+#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) -+#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) -+#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx) -+#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx) -+#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx) -+#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res) -+#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw) -+#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw) -+#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma) -+#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock) -+#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock) -+#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock) -+ -+#define DRM_IOCTL_PRIME_HANDLE_TO_FD DRM_IOWR(0x2d, struct drm_prime_handle) -+#define DRM_IOCTL_PRIME_FD_TO_HANDLE DRM_IOWR(0x2e, struct drm_prime_handle) -+ -+#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) -+#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) -+#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode) -+#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info) -+#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer) -+#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer) -+#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding) -+#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding) -+ -+#define DRM_IOCTL_SG_ALLOC DRM_IOWR(0x38, struct drm_scatter_gather) -+#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather) -+ -+#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank) -+ -+#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence) -+#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence) -+ -+#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) -+ -+#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) -+#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) -+#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc) -+#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor) -+#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut) -+#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut) -+#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder) -+#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector) -+#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) /* deprecated (never worked) */ -+#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) /* deprecated (never worked) */ -+ -+#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property) -+#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property) -+#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob) -+#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) -+#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) -+/** -+ * DRM_IOCTL_MODE_RMFB - Remove a framebuffer. -+ * -+ * This removes a framebuffer previously added via ADDFB/ADDFB2. The IOCTL -+ * argument is a framebuffer object ID. -+ * -+ * Warning: removing a framebuffer currently in-use on an enabled plane will -+ * disable that plane. The CRTC the plane is linked to may also be disabled -+ * (depending on driver capabilities). -+ */ -+#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) -+#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) -+#define DRM_IOCTL_MODE_DIRTYFB DRM_IOWR(0xB1, struct drm_mode_fb_dirty_cmd) -+ -+#define DRM_IOCTL_MODE_CREATE_DUMB DRM_IOWR(0xB2, struct drm_mode_create_dumb) -+#define DRM_IOCTL_MODE_MAP_DUMB DRM_IOWR(0xB3, struct drm_mode_map_dumb) -+#define DRM_IOCTL_MODE_DESTROY_DUMB DRM_IOWR(0xB4, struct drm_mode_destroy_dumb) -+#define DRM_IOCTL_MODE_GETPLANERESOURCES DRM_IOWR(0xB5, struct drm_mode_get_plane_res) -+#define DRM_IOCTL_MODE_GETPLANE DRM_IOWR(0xB6, struct drm_mode_get_plane) -+#define DRM_IOCTL_MODE_SETPLANE DRM_IOWR(0xB7, struct drm_mode_set_plane) -+#define DRM_IOCTL_MODE_ADDFB2 DRM_IOWR(0xB8, struct drm_mode_fb_cmd2) -+#define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties) -+#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property) -+#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2) -+#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic) -+#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob) -+#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob) -+ -+#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create) -+#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy) -+#define DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD DRM_IOWR(0xC1, struct drm_syncobj_handle) -+#define DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE DRM_IOWR(0xC2, struct drm_syncobj_handle) -+#define DRM_IOCTL_SYNCOBJ_WAIT DRM_IOWR(0xC3, struct drm_syncobj_wait) -+#define DRM_IOCTL_SYNCOBJ_RESET DRM_IOWR(0xC4, struct drm_syncobj_array) -+#define DRM_IOCTL_SYNCOBJ_SIGNAL DRM_IOWR(0xC5, struct drm_syncobj_array) -+ -+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC6, struct drm_mode_create_lease) -+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC7, struct drm_mode_list_lessees) -+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC8, struct drm_mode_get_lease) -+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC9, struct drm_mode_revoke_lease) -+ -+#define DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT DRM_IOWR(0xCA, struct drm_syncobj_timeline_wait) -+#define DRM_IOCTL_SYNCOBJ_QUERY DRM_IOWR(0xCB, struct drm_syncobj_timeline_array) -+#define DRM_IOCTL_SYNCOBJ_TRANSFER DRM_IOWR(0xCC, struct drm_syncobj_transfer) -+#define DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL DRM_IOWR(0xCD, struct drm_syncobj_timeline_array) -+ -+#define DRM_IOCTL_MODE_GETFB2 DRM_IOWR(0xCE, struct drm_mode_fb_cmd2) -+ -+/* -+ * Device specific ioctls should only be in their respective headers -+ * The device specific ioctl range is from 0x40 to 0x9f. -+ * Generic IOCTLS restart at 0xA0. -+ * -+ * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and -+ * drmCommandReadWrite(). -+ */ -+#define DRM_COMMAND_BASE 0x40 -+#define DRM_COMMAND_END 0xA0 -+ -+/* -+ * Header for events written back to userspace on the drm fd. The -+ * type defines the type of event, the length specifies the total -+ * length of the event (including the header), and user_data is -+ * typically a 64 bit value passed with the ioctl that triggered the -+ * event. A read on the drm fd will always only return complete -+ * events, that is, if for example the read buffer is 100 bytes, and -+ * there are two 64 byte events pending, only one will be returned. -+ * -+ * Event types 0 - 0x7fffffff are generic drm events, 0x80000000 and -+ * up are chipset specific. -+ */ -+struct drm_event { -+ __u32 type; -+ __u32 length; -+}; -+ -+#define DRM_EVENT_VBLANK 0x01 -+#define DRM_EVENT_FLIP_COMPLETE 0x02 -+#define DRM_EVENT_CRTC_SEQUENCE 0x03 -+ -+struct drm_event_vblank { -+ struct drm_event base; -+ __u64 user_data; -+ __u32 tv_sec; -+ __u32 tv_usec; -+ __u32 sequence; -+ __u32 crtc_id; /* 0 on older kernels that do not support this */ -+}; -+ -+/* Event delivered at sequence. Time stamp marks when the first pixel -+ * of the refresh cycle leaves the display engine for the display -+ */ -+struct drm_event_crtc_sequence { -+ struct drm_event base; -+ __u64 user_data; -+ __s64 time_ns; -+ __u64 sequence; -+}; -+ -+/* typedef area */ -+typedef struct drm_clip_rect drm_clip_rect_t; -+typedef struct drm_drawable_info drm_drawable_info_t; -+typedef struct drm_tex_region drm_tex_region_t; -+typedef struct drm_hw_lock drm_hw_lock_t; -+typedef struct drm_version drm_version_t; -+typedef struct drm_unique drm_unique_t; -+typedef struct drm_list drm_list_t; -+typedef struct drm_block drm_block_t; -+typedef struct drm_control drm_control_t; -+typedef enum drm_map_type drm_map_type_t; -+typedef enum drm_map_flags drm_map_flags_t; -+typedef struct drm_ctx_priv_map drm_ctx_priv_map_t; -+typedef struct drm_map drm_map_t; -+typedef struct drm_client drm_client_t; -+typedef enum drm_stat_type drm_stat_type_t; -+typedef struct drm_stats drm_stats_t; -+typedef enum drm_lock_flags drm_lock_flags_t; -+typedef struct drm_lock drm_lock_t; -+typedef enum drm_dma_flags drm_dma_flags_t; -+typedef struct drm_buf_desc drm_buf_desc_t; -+typedef struct drm_buf_info drm_buf_info_t; -+typedef struct drm_buf_free drm_buf_free_t; -+typedef struct drm_buf_pub drm_buf_pub_t; -+typedef struct drm_buf_map drm_buf_map_t; -+typedef struct drm_dma drm_dma_t; -+typedef union drm_wait_vblank drm_wait_vblank_t; -+typedef struct drm_agp_mode drm_agp_mode_t; -+typedef enum drm_ctx_flags drm_ctx_flags_t; -+typedef struct drm_ctx drm_ctx_t; -+typedef struct drm_ctx_res drm_ctx_res_t; -+typedef struct drm_draw drm_draw_t; -+typedef struct drm_update_draw drm_update_draw_t; -+typedef struct drm_auth drm_auth_t; -+typedef struct drm_irq_busid drm_irq_busid_t; -+typedef enum drm_vblank_seq_type drm_vblank_seq_type_t; -+ -+typedef struct drm_agp_buffer drm_agp_buffer_t; -+typedef struct drm_agp_binding drm_agp_binding_t; -+typedef struct drm_agp_info drm_agp_info_t; -+typedef struct drm_scatter_gather drm_scatter_gather_t; -+typedef struct drm_set_version drm_set_version_t; -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif -diff --git a/third_party/drm/drm/drm_fourcc.h b/third_party/drm/drm/drm_fourcc.h -new file mode 100644 -index 0000000..4ececa8 ---- /dev/null -+++ b/third_party/drm/drm/drm_fourcc.h -@@ -0,0 +1,1377 @@ -+/* -+ * Copyright 2011 Intel Corporation -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef DRM_FOURCC_H -+#define DRM_FOURCC_H -+ -+#include "drm.h" -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+/** -+ * DOC: overview -+ * -+ * In the DRM subsystem, framebuffer pixel formats are described using the -+ * fourcc codes defined in `include/uapi/drm/drm_fourcc.h`. In addition to the -+ * fourcc code, a Format Modifier may optionally be provided, in order to -+ * further describe the buffer's format - for example tiling or compression. -+ * -+ * Format Modifiers -+ * ---------------- -+ * -+ * Format modifiers are used in conjunction with a fourcc code, forming a -+ * unique fourcc:modifier pair. This format:modifier pair must fully define the -+ * format and data layout of the buffer, and should be the only way to describe -+ * that particular buffer. -+ * -+ * Having multiple fourcc:modifier pairs which describe the same layout should -+ * be avoided, as such aliases run the risk of different drivers exposing -+ * different names for the same data format, forcing userspace to understand -+ * that they are aliases. -+ * -+ * Format modifiers may change any property of the buffer, including the number -+ * of planes and/or the required allocation size. Format modifiers are -+ * vendor-namespaced, and as such the relationship between a fourcc code and a -+ * modifier is specific to the modifer being used. For example, some modifiers -+ * may preserve meaning - such as number of planes - from the fourcc code, -+ * whereas others may not. -+ * -+ * Modifiers must uniquely encode buffer layout. In other words, a buffer must -+ * match only a single modifier. A modifier must not be a subset of layouts of -+ * another modifier. For instance, it's incorrect to encode pitch alignment in -+ * a modifier: a buffer may match a 64-pixel aligned modifier and a 32-pixel -+ * aligned modifier. That said, modifiers can have implicit minimal -+ * requirements. -+ * -+ * For modifiers where the combination of fourcc code and modifier can alias, -+ * a canonical pair needs to be defined and used by all drivers. Preferred -+ * combinations are also encouraged where all combinations might lead to -+ * confusion and unnecessarily reduced interoperability. An example for the -+ * latter is AFBC, where the ABGR layouts are preferred over ARGB layouts. -+ * -+ * There are two kinds of modifier users: -+ * -+ * - Kernel and user-space drivers: for drivers it's important that modifiers -+ * don't alias, otherwise two drivers might support the same format but use -+ * different aliases, preventing them from sharing buffers in an efficient -+ * format. -+ * - Higher-level programs interfacing with KMS/GBM/EGL/Vulkan/etc: these users -+ * see modifiers as opaque tokens they can check for equality and intersect. -+ * These users musn't need to know to reason about the modifier value -+ * (i.e. they are not expected to extract information out of the modifier). -+ * -+ * Vendors should document their modifier usage in as much detail as -+ * possible, to ensure maximum compatibility across devices, drivers and -+ * applications. -+ * -+ * The authoritative list of format modifier codes is found in -+ * `include/uapi/drm/drm_fourcc.h` -+ */ -+ -+#define fourcc_code(a, b, c, d) ((__u32)(a) | ((__u32)(b) << 8) | \ -+ ((__u32)(c) << 16) | ((__u32)(d) << 24)) -+ -+#define DRM_FORMAT_BIG_ENDIAN (1U<<31) /* format is big endian instead of little endian */ -+ -+/* Reserve 0 for the invalid format specifier */ -+#define DRM_FORMAT_INVALID 0 -+ -+/* color index */ -+#define DRM_FORMAT_C8 fourcc_code('C', '8', ' ', ' ') /* [7:0] C */ -+ -+/* 8 bpp Red */ -+#define DRM_FORMAT_R8 fourcc_code('R', '8', ' ', ' ') /* [7:0] R */ -+ -+/* 10 bpp Red */ -+#define DRM_FORMAT_R10 fourcc_code('R', '1', '0', ' ') /* [15:0] x:R 6:10 little endian */ -+ -+/* 12 bpp Red */ -+#define DRM_FORMAT_R12 fourcc_code('R', '1', '2', ' ') /* [15:0] x:R 4:12 little endian */ -+ -+/* 16 bpp Red */ -+#define DRM_FORMAT_R16 fourcc_code('R', '1', '6', ' ') /* [15:0] R little endian */ -+ -+/* 16 bpp RG */ -+#define DRM_FORMAT_RG88 fourcc_code('R', 'G', '8', '8') /* [15:0] R:G 8:8 little endian */ -+#define DRM_FORMAT_GR88 fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */ -+ -+/* 32 bpp RG */ -+#define DRM_FORMAT_RG1616 fourcc_code('R', 'G', '3', '2') /* [31:0] R:G 16:16 little endian */ -+#define DRM_FORMAT_GR1616 fourcc_code('G', 'R', '3', '2') /* [31:0] G:R 16:16 little endian */ -+ -+/* 8 bpp RGB */ -+#define DRM_FORMAT_RGB332 fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */ -+#define DRM_FORMAT_BGR233 fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */ -+ -+/* 16 bpp RGB */ -+#define DRM_FORMAT_XRGB4444 fourcc_code('X', 'R', '1', '2') /* [15:0] x:R:G:B 4:4:4:4 little endian */ -+#define DRM_FORMAT_XBGR4444 fourcc_code('X', 'B', '1', '2') /* [15:0] x:B:G:R 4:4:4:4 little endian */ -+#define DRM_FORMAT_RGBX4444 fourcc_code('R', 'X', '1', '2') /* [15:0] R:G:B:x 4:4:4:4 little endian */ -+#define DRM_FORMAT_BGRX4444 fourcc_code('B', 'X', '1', '2') /* [15:0] B:G:R:x 4:4:4:4 little endian */ -+ -+#define DRM_FORMAT_ARGB4444 fourcc_code('A', 'R', '1', '2') /* [15:0] A:R:G:B 4:4:4:4 little endian */ -+#define DRM_FORMAT_ABGR4444 fourcc_code('A', 'B', '1', '2') /* [15:0] A:B:G:R 4:4:4:4 little endian */ -+#define DRM_FORMAT_RGBA4444 fourcc_code('R', 'A', '1', '2') /* [15:0] R:G:B:A 4:4:4:4 little endian */ -+#define DRM_FORMAT_BGRA4444 fourcc_code('B', 'A', '1', '2') /* [15:0] B:G:R:A 4:4:4:4 little endian */ -+ -+#define DRM_FORMAT_XRGB1555 fourcc_code('X', 'R', '1', '5') /* [15:0] x:R:G:B 1:5:5:5 little endian */ -+#define DRM_FORMAT_XBGR1555 fourcc_code('X', 'B', '1', '5') /* [15:0] x:B:G:R 1:5:5:5 little endian */ -+#define DRM_FORMAT_RGBX5551 fourcc_code('R', 'X', '1', '5') /* [15:0] R:G:B:x 5:5:5:1 little endian */ -+#define DRM_FORMAT_BGRX5551 fourcc_code('B', 'X', '1', '5') /* [15:0] B:G:R:x 5:5:5:1 little endian */ -+ -+#define DRM_FORMAT_ARGB1555 fourcc_code('A', 'R', '1', '5') /* [15:0] A:R:G:B 1:5:5:5 little endian */ -+#define DRM_FORMAT_ABGR1555 fourcc_code('A', 'B', '1', '5') /* [15:0] A:B:G:R 1:5:5:5 little endian */ -+#define DRM_FORMAT_RGBA5551 fourcc_code('R', 'A', '1', '5') /* [15:0] R:G:B:A 5:5:5:1 little endian */ -+#define DRM_FORMAT_BGRA5551 fourcc_code('B', 'A', '1', '5') /* [15:0] B:G:R:A 5:5:5:1 little endian */ -+ -+#define DRM_FORMAT_RGB565 fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */ -+#define DRM_FORMAT_BGR565 fourcc_code('B', 'G', '1', '6') /* [15:0] B:G:R 5:6:5 little endian */ -+ -+/* 24 bpp RGB */ -+#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */ -+#define DRM_FORMAT_BGR888 fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */ -+ -+/* 32 bpp RGB */ -+#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ -+#define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4') /* [31:0] x:B:G:R 8:8:8:8 little endian */ -+#define DRM_FORMAT_RGBX8888 fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */ -+#define DRM_FORMAT_BGRX8888 fourcc_code('B', 'X', '2', '4') /* [31:0] B:G:R:x 8:8:8:8 little endian */ -+ -+#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4') /* [31:0] A:R:G:B 8:8:8:8 little endian */ -+#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */ -+#define DRM_FORMAT_RGBA8888 fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */ -+#define DRM_FORMAT_BGRA8888 fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */ -+ -+#define DRM_FORMAT_XRGB2101010 fourcc_code('X', 'R', '3', '0') /* [31:0] x:R:G:B 2:10:10:10 little endian */ -+#define DRM_FORMAT_XBGR2101010 fourcc_code('X', 'B', '3', '0') /* [31:0] x:B:G:R 2:10:10:10 little endian */ -+#define DRM_FORMAT_RGBX1010102 fourcc_code('R', 'X', '3', '0') /* [31:0] R:G:B:x 10:10:10:2 little endian */ -+#define DRM_FORMAT_BGRX1010102 fourcc_code('B', 'X', '3', '0') /* [31:0] B:G:R:x 10:10:10:2 little endian */ -+ -+#define DRM_FORMAT_ARGB2101010 fourcc_code('A', 'R', '3', '0') /* [31:0] A:R:G:B 2:10:10:10 little endian */ -+#define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0') /* [31:0] A:B:G:R 2:10:10:10 little endian */ -+#define DRM_FORMAT_RGBA1010102 fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */ -+#define DRM_FORMAT_BGRA1010102 fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */ -+ -+/* 64 bpp RGB */ -+#define DRM_FORMAT_XRGB16161616 fourcc_code('X', 'R', '4', '8') /* [63:0] x:R:G:B 16:16:16:16 little endian */ -+#define DRM_FORMAT_XBGR16161616 fourcc_code('X', 'B', '4', '8') /* [63:0] x:B:G:R 16:16:16:16 little endian */ -+ -+#define DRM_FORMAT_ARGB16161616 fourcc_code('A', 'R', '4', '8') /* [63:0] A:R:G:B 16:16:16:16 little endian */ -+#define DRM_FORMAT_ABGR16161616 fourcc_code('A', 'B', '4', '8') /* [63:0] A:B:G:R 16:16:16:16 little endian */ -+ -+/* -+ * Floating point 64bpp RGB -+ * IEEE 754-2008 binary16 half-precision float -+ * [15:0] sign:exponent:mantissa 1:5:10 -+ */ -+#define DRM_FORMAT_XRGB16161616F fourcc_code('X', 'R', '4', 'H') /* [63:0] x:R:G:B 16:16:16:16 little endian */ -+#define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H') /* [63:0] x:B:G:R 16:16:16:16 little endian */ -+ -+#define DRM_FORMAT_ARGB16161616F fourcc_code('A', 'R', '4', 'H') /* [63:0] A:R:G:B 16:16:16:16 little endian */ -+#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */ -+ -+/* -+ * RGBA format with 10-bit components packed in 64-bit per pixel, with 6 bits -+ * of unused padding per component: -+ */ -+#define DRM_FORMAT_AXBXGXRX106106106106 fourcc_code('A', 'B', '1', '0') /* [63:0] A:x:B:x:G:x:R:x 10:6:10:6:10:6:10:6 little endian */ -+ -+/* packed YCbCr */ -+#define DRM_FORMAT_YUYV fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ -+#define DRM_FORMAT_YVYU fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ -+#define DRM_FORMAT_UYVY fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ -+#define DRM_FORMAT_VYUY fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */ -+ -+#define DRM_FORMAT_AYUV fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */ -+#define DRM_FORMAT_XYUV8888 fourcc_code('X', 'Y', 'U', 'V') /* [31:0] X:Y:Cb:Cr 8:8:8:8 little endian */ -+#define DRM_FORMAT_VUY888 fourcc_code('V', 'U', '2', '4') /* [23:0] Cr:Cb:Y 8:8:8 little endian */ -+#define DRM_FORMAT_VUY101010 fourcc_code('V', 'U', '3', '0') /* Y followed by U then V, 10:10:10. Non-linear modifier only */ -+ -+/* -+ * packed Y2xx indicate for each component, xx valid data occupy msb -+ * 16-xx padding occupy lsb -+ */ -+#define DRM_FORMAT_Y210 fourcc_code('Y', '2', '1', '0') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels */ -+#define DRM_FORMAT_Y212 fourcc_code('Y', '2', '1', '2') /* [63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels */ -+#define DRM_FORMAT_Y216 fourcc_code('Y', '2', '1', '6') /* [63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels */ -+ -+/* -+ * packed Y4xx indicate for each component, xx valid data occupy msb -+ * 16-xx padding occupy lsb except Y410 -+ */ -+#define DRM_FORMAT_Y410 fourcc_code('Y', '4', '1', '0') /* [31:0] A:Cr:Y:Cb 2:10:10:10 little endian */ -+#define DRM_FORMAT_Y412 fourcc_code('Y', '4', '1', '2') /* [63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian */ -+#define DRM_FORMAT_Y416 fourcc_code('Y', '4', '1', '6') /* [63:0] A:Cr:Y:Cb 16:16:16:16 little endian */ -+ -+#define DRM_FORMAT_XVYU2101010 fourcc_code('X', 'V', '3', '0') /* [31:0] X:Cr:Y:Cb 2:10:10:10 little endian */ -+#define DRM_FORMAT_XVYU12_16161616 fourcc_code('X', 'V', '3', '6') /* [63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian */ -+#define DRM_FORMAT_XVYU16161616 fourcc_code('X', 'V', '4', '8') /* [63:0] X:Cr:Y:Cb 16:16:16:16 little endian */ -+ -+/* -+ * packed YCbCr420 2x2 tiled formats -+ * first 64 bits will contain Y,Cb,Cr components for a 2x2 tile -+ */ -+/* [63:0] A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */ -+#define DRM_FORMAT_Y0L0 fourcc_code('Y', '0', 'L', '0') -+/* [63:0] X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian */ -+#define DRM_FORMAT_X0L0 fourcc_code('X', '0', 'L', '0') -+ -+/* [63:0] A3:A2:Y3:Cr0:Y2:A1:A0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian */ -+#define DRM_FORMAT_Y0L2 fourcc_code('Y', '0', 'L', '2') -+/* [63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian */ -+#define DRM_FORMAT_X0L2 fourcc_code('X', '0', 'L', '2') -+ -+/* -+ * 1-plane YUV 4:2:0 -+ * In these formats, the component ordering is specified (Y, followed by U -+ * then V), but the exact Linear layout is undefined. -+ * These formats can only be used with a non-Linear modifier. -+ */ -+#define DRM_FORMAT_YUV420_8BIT fourcc_code('Y', 'U', '0', '8') -+#define DRM_FORMAT_YUV420_10BIT fourcc_code('Y', 'U', '1', '0') -+ -+/* -+ * 2 plane RGB + A -+ * index 0 = RGB plane, same format as the corresponding non _A8 format has -+ * index 1 = A plane, [7:0] A -+ */ -+#define DRM_FORMAT_XRGB8888_A8 fourcc_code('X', 'R', 'A', '8') -+#define DRM_FORMAT_XBGR8888_A8 fourcc_code('X', 'B', 'A', '8') -+#define DRM_FORMAT_RGBX8888_A8 fourcc_code('R', 'X', 'A', '8') -+#define DRM_FORMAT_BGRX8888_A8 fourcc_code('B', 'X', 'A', '8') -+#define DRM_FORMAT_RGB888_A8 fourcc_code('R', '8', 'A', '8') -+#define DRM_FORMAT_BGR888_A8 fourcc_code('B', '8', 'A', '8') -+#define DRM_FORMAT_RGB565_A8 fourcc_code('R', '5', 'A', '8') -+#define DRM_FORMAT_BGR565_A8 fourcc_code('B', '5', 'A', '8') -+ -+/* -+ * 2 plane YCbCr -+ * index 0 = Y plane, [7:0] Y -+ * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian -+ * or -+ * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian -+ */ -+#define DRM_FORMAT_NV12 fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */ -+#define DRM_FORMAT_NV21 fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */ -+#define DRM_FORMAT_NV16 fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */ -+#define DRM_FORMAT_NV61 fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ -+#define DRM_FORMAT_NV24 fourcc_code('N', 'V', '2', '4') /* non-subsampled Cr:Cb plane */ -+#define DRM_FORMAT_NV42 fourcc_code('N', 'V', '4', '2') /* non-subsampled Cb:Cr plane */ -+/* -+ * 2 plane YCbCr -+ * index 0 = Y plane, [39:0] Y3:Y2:Y1:Y0 little endian -+ * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian -+ */ -+#define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ -+ -+/* -+ * 2 plane YCbCr MSB aligned -+ * index 0 = Y plane, [15:0] Y:x [10:6] little endian -+ * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [10:6:10:6] little endian -+ */ -+#define DRM_FORMAT_P210 fourcc_code('P', '2', '1', '0') /* 2x1 subsampled Cr:Cb plane, 10 bit per channel */ -+ -+/* -+ * 2 plane YCbCr MSB aligned -+ * index 0 = Y plane, [15:0] Y:x [10:6] little endian -+ * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [10:6:10:6] little endian -+ */ -+#define DRM_FORMAT_P010 fourcc_code('P', '0', '1', '0') /* 2x2 subsampled Cr:Cb plane 10 bits per channel */ -+ -+/* -+ * 2 plane YCbCr MSB aligned -+ * index 0 = Y plane, [15:0] Y:x [12:4] little endian -+ * index 1 = Cr:Cb plane, [31:0] Cr:x:Cb:x [12:4:12:4] little endian -+ */ -+#define DRM_FORMAT_P012 fourcc_code('P', '0', '1', '2') /* 2x2 subsampled Cr:Cb plane 12 bits per channel */ -+ -+/* -+ * 2 plane YCbCr MSB aligned -+ * index 0 = Y plane, [15:0] Y little endian -+ * index 1 = Cr:Cb plane, [31:0] Cr:Cb [16:16] little endian -+ */ -+#define DRM_FORMAT_P016 fourcc_code('P', '0', '1', '6') /* 2x2 subsampled Cr:Cb plane 16 bits per channel */ -+ -+/* 3 plane non-subsampled (444) YCbCr -+ * 16 bits per component, but only 10 bits are used and 6 bits are padded -+ * index 0: Y plane, [15:0] Y:x [10:6] little endian -+ * index 1: Cb plane, [15:0] Cb:x [10:6] little endian -+ * index 2: Cr plane, [15:0] Cr:x [10:6] little endian -+ */ -+#define DRM_FORMAT_Q410 fourcc_code('Q', '4', '1', '0') -+ -+/* 3 plane non-subsampled (444) YCrCb -+ * 16 bits per component, but only 10 bits are used and 6 bits are padded -+ * index 0: Y plane, [15:0] Y:x [10:6] little endian -+ * index 1: Cr plane, [15:0] Cr:x [10:6] little endian -+ * index 2: Cb plane, [15:0] Cb:x [10:6] little endian -+ */ -+#define DRM_FORMAT_Q401 fourcc_code('Q', '4', '0', '1') -+ -+/* -+ * 3 plane YCbCr -+ * index 0: Y plane, [7:0] Y -+ * index 1: Cb plane, [7:0] Cb -+ * index 2: Cr plane, [7:0] Cr -+ * or -+ * index 1: Cr plane, [7:0] Cr -+ * index 2: Cb plane, [7:0] Cb -+ */ -+#define DRM_FORMAT_YUV410 fourcc_code('Y', 'U', 'V', '9') /* 4x4 subsampled Cb (1) and Cr (2) planes */ -+#define DRM_FORMAT_YVU410 fourcc_code('Y', 'V', 'U', '9') /* 4x4 subsampled Cr (1) and Cb (2) planes */ -+#define DRM_FORMAT_YUV411 fourcc_code('Y', 'U', '1', '1') /* 4x1 subsampled Cb (1) and Cr (2) planes */ -+#define DRM_FORMAT_YVU411 fourcc_code('Y', 'V', '1', '1') /* 4x1 subsampled Cr (1) and Cb (2) planes */ -+#define DRM_FORMAT_YUV420 fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */ -+#define DRM_FORMAT_YVU420 fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */ -+#define DRM_FORMAT_YUV422 fourcc_code('Y', 'U', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes */ -+#define DRM_FORMAT_YVU422 fourcc_code('Y', 'V', '1', '6') /* 2x1 subsampled Cr (1) and Cb (2) planes */ -+#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ -+#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ -+ -+ -+/* -+ * Format Modifiers: -+ * -+ * Format modifiers describe, typically, a re-ordering or modification -+ * of the data in a plane of an FB. This can be used to express tiled/ -+ * swizzled formats, or compression, or a combination of the two. -+ * -+ * The upper 8 bits of the format modifier are a vendor-id as assigned -+ * below. The lower 56 bits are assigned as vendor sees fit. -+ */ -+ -+/* Vendor Ids: */ -+#define DRM_FORMAT_MOD_VENDOR_NONE 0 -+#define DRM_FORMAT_MOD_VENDOR_INTEL 0x01 -+#define DRM_FORMAT_MOD_VENDOR_AMD 0x02 -+#define DRM_FORMAT_MOD_VENDOR_NVIDIA 0x03 -+#define DRM_FORMAT_MOD_VENDOR_SAMSUNG 0x04 -+#define DRM_FORMAT_MOD_VENDOR_QCOM 0x05 -+#define DRM_FORMAT_MOD_VENDOR_VIVANTE 0x06 -+#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 -+#define DRM_FORMAT_MOD_VENDOR_ARM 0x08 -+#define DRM_FORMAT_MOD_VENDOR_ALLWINNER 0x09 -+#define DRM_FORMAT_MOD_VENDOR_AMLOGIC 0x0a -+ -+/* add more to the end as needed */ -+ -+#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) -+ -+#define fourcc_mod_get_vendor(modifier) \ -+ (((modifier) >> 56) & 0xff) -+ -+#define fourcc_mod_is_vendor(modifier, vendor) \ -+ (fourcc_mod_get_vendor(modifier) == DRM_FORMAT_MOD_VENDOR_## vendor) -+ -+#define fourcc_mod_code(vendor, val) \ -+ ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | ((val) & 0x00ffffffffffffffULL)) -+ -+/* -+ * Format Modifier tokens: -+ * -+ * When adding a new token please document the layout with a code comment, -+ * similar to the fourcc codes above. drm_fourcc.h is considered the -+ * authoritative source for all of these. -+ * -+ * Generic modifier names: -+ * -+ * DRM_FORMAT_MOD_GENERIC_* definitions are used to provide vendor-neutral names -+ * for layouts which are common across multiple vendors. To preserve -+ * compatibility, in cases where a vendor-specific definition already exists and -+ * a generic name for it is desired, the common name is a purely symbolic alias -+ * and must use the same numerical value as the original definition. -+ * -+ * Note that generic names should only be used for modifiers which describe -+ * generic layouts (such as pixel re-ordering), which may have -+ * independently-developed support across multiple vendors. -+ * -+ * In future cases where a generic layout is identified before merging with a -+ * vendor-specific modifier, a new 'GENERIC' vendor or modifier using vendor -+ * 'NONE' could be considered. This should only be for obvious, exceptional -+ * cases to avoid polluting the 'GENERIC' namespace with modifiers which only -+ * apply to a single vendor. -+ * -+ * Generic names should not be used for cases where multiple hardware vendors -+ * have implementations of the same standardised compression scheme (such as -+ * AFBC). In those cases, all implementations should use the same format -+ * modifier(s), reflecting the vendor of the standard. -+ */ -+ -+#define DRM_FORMAT_MOD_GENERIC_16_16_TILE DRM_FORMAT_MOD_SAMSUNG_16_16_TILE -+ -+/* -+ * Invalid Modifier -+ * -+ * This modifier can be used as a sentinel to terminate the format modifiers -+ * list, or to initialize a variable with an invalid modifier. It might also be -+ * used to report an error back to userspace for certain APIs. -+ */ -+#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED) -+ -+/* -+ * Linear Layout -+ * -+ * Just plain linear layout. Note that this is different from no specifying any -+ * modifier (e.g. not setting DRM_MODE_FB_MODIFIERS in the DRM_ADDFB2 ioctl), -+ * which tells the driver to also take driver-internal information into account -+ * and so might actually result in a tiled framebuffer. -+ */ -+#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0) -+ -+/* -+ * Deprecated: use DRM_FORMAT_MOD_LINEAR instead -+ * -+ * The "none" format modifier doesn't actually mean that the modifier is -+ * implicit, instead it means that the layout is linear. Whether modifiers are -+ * used is out-of-band information carried in an API-specific way (e.g. in a -+ * flag for drm_mode_fb_cmd2). -+ */ -+#define DRM_FORMAT_MOD_NONE 0 -+ -+/* Intel framebuffer modifiers */ -+ -+/* -+ * Intel X-tiling layout -+ * -+ * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) -+ * in row-major layout. Within the tile bytes are laid out row-major, with -+ * a platform-dependent stride. On top of that the memory can apply -+ * platform-depending swizzling of some higher address bits into bit6. -+ * -+ * Note that this layout is only accurate on intel gen 8+ or valleyview chipsets. -+ * On earlier platforms the is highly platforms specific and not useful for -+ * cross-driver sharing. It exists since on a given platform it does uniquely -+ * identify the layout in a simple way for i915-specific userspace, which -+ * facilitated conversion of userspace to modifiers. Additionally the exact -+ * format on some really old platforms is not known. -+ */ -+#define I915_FORMAT_MOD_X_TILED fourcc_mod_code(INTEL, 1) -+ -+/* -+ * Intel Y-tiling layout -+ * -+ * This is a tiled layout using 4Kb tiles (except on gen2 where the tiles 2Kb) -+ * in row-major layout. Within the tile bytes are laid out in OWORD (16 bytes) -+ * chunks column-major, with a platform-dependent height. On top of that the -+ * memory can apply platform-depending swizzling of some higher address bits -+ * into bit6. -+ * -+ * Note that this layout is only accurate on intel gen 8+ or valleyview chipsets. -+ * On earlier platforms the is highly platforms specific and not useful for -+ * cross-driver sharing. It exists since on a given platform it does uniquely -+ * identify the layout in a simple way for i915-specific userspace, which -+ * facilitated conversion of userspace to modifiers. Additionally the exact -+ * format on some really old platforms is not known. -+ */ -+#define I915_FORMAT_MOD_Y_TILED fourcc_mod_code(INTEL, 2) -+ -+/* -+ * Intel Yf-tiling layout -+ * -+ * This is a tiled layout using 4Kb tiles in row-major layout. -+ * Within the tile pixels are laid out in 16 256 byte units / sub-tiles which -+ * are arranged in four groups (two wide, two high) with column-major layout. -+ * Each group therefore consits out of four 256 byte units, which are also laid -+ * out as 2x2 column-major. -+ * 256 byte units are made out of four 64 byte blocks of pixels, producing -+ * either a square block or a 2:1 unit. -+ * 64 byte blocks of pixels contain four pixel rows of 16 bytes, where the width -+ * in pixel depends on the pixel depth. -+ */ -+#define I915_FORMAT_MOD_Yf_TILED fourcc_mod_code(INTEL, 3) -+ -+/* -+ * Intel color control surface (CCS) for render compression -+ * -+ * The framebuffer format must be one of the 8:8:8:8 RGB formats. -+ * The main surface will be plane index 0 and must be Y/Yf-tiled, -+ * the CCS will be plane index 1. -+ * -+ * Each CCS tile matches a 1024x512 pixel area of the main surface. -+ * To match certain aspects of the 3D hardware the CCS is -+ * considered to be made up of normal 128Bx32 Y tiles, Thus -+ * the CCS pitch must be specified in multiples of 128 bytes. -+ * -+ * In reality the CCS tile appears to be a 64Bx64 Y tile, composed -+ * of QWORD (8 bytes) chunks instead of OWORD (16 bytes) chunks. -+ * But that fact is not relevant unless the memory is accessed -+ * directly. -+ */ -+#define I915_FORMAT_MOD_Y_TILED_CCS fourcc_mod_code(INTEL, 4) -+#define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5) -+ -+/* -+ * Intel color control surfaces (CCS) for Gen-12 render compression. -+ * -+ * The main surface is Y-tiled and at plane index 0, the CCS is linear and -+ * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in -+ * main surface. In other words, 4 bits in CCS map to a main surface cache -+ * line pair. The main surface pitch is required to be a multiple of four -+ * Y-tile widths. -+ */ -+#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS fourcc_mod_code(INTEL, 6) -+ -+/* -+ * Intel color control surfaces (CCS) for Gen-12 media compression -+ * -+ * The main surface is Y-tiled and at plane index 0, the CCS is linear and -+ * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in -+ * main surface. In other words, 4 bits in CCS map to a main surface cache -+ * line pair. The main surface pitch is required to be a multiple of four -+ * Y-tile widths. For semi-planar formats like NV12, CCS planes follow the -+ * Y and UV planes i.e., planes 0 and 1 are used for Y and UV surfaces, -+ * planes 2 and 3 for the respective CCS. -+ */ -+#define I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS fourcc_mod_code(INTEL, 7) -+ -+/* -+ * Intel Color Control Surface with Clear Color (CCS) for Gen-12 render -+ * compression. -+ * -+ * The main surface is Y-tiled and is at plane index 0 whereas CCS is linear -+ * and at index 1. The clear color is stored at index 2, and the pitch should -+ * be ignored. The clear color structure is 256 bits. The first 128 bits -+ * represents Raw Clear Color Red, Green, Blue and Alpha color each represented -+ * by 32 bits. The raw clear color is consumed by the 3d engine and generates -+ * the converted clear color of size 64 bits. The first 32 bits store the Lower -+ * Converted Clear Color value and the next 32 bits store the Higher Converted -+ * Clear Color value when applicable. The Converted Clear Color values are -+ * consumed by the DE. The last 64 bits are used to store Color Discard Enable -+ * and Depth Clear Value Valid which are ignored by the DE. A CCS cache line -+ * corresponds to an area of 4x1 tiles in the main surface. The main surface -+ * pitch is required to be a multiple of 4 tile widths. -+ */ -+#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC fourcc_mod_code(INTEL, 8) -+ -+/* -+ * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks -+ * -+ * Macroblocks are laid in a Z-shape, and each pixel data is following the -+ * standard NV12 style. -+ * As for NV12, an image is the result of two frame buffers: one for Y, -+ * one for the interleaved Cb/Cr components (1/2 the height of the Y buffer). -+ * Alignment requirements are (for each buffer): -+ * - multiple of 128 pixels for the width -+ * - multiple of 32 pixels for the height -+ * -+ * For more information: see https://linuxtv.org/downloads/v4l-dvb-apis/re32.html -+ */ -+#define DRM_FORMAT_MOD_SAMSUNG_64_32_TILE fourcc_mod_code(SAMSUNG, 1) -+ -+/* -+ * Tiled, 16 (pixels) x 16 (lines) - sized macroblocks -+ * -+ * This is a simple tiled layout using tiles of 16x16 pixels in a row-major -+ * layout. For YCbCr formats Cb/Cr components are taken in such a way that -+ * they correspond to their 16x16 luma block. -+ */ -+#define DRM_FORMAT_MOD_SAMSUNG_16_16_TILE fourcc_mod_code(SAMSUNG, 2) -+ -+/* -+ * Qualcomm Compressed Format -+ * -+ * Refers to a compressed variant of the base format that is compressed. -+ * Implementation may be platform and base-format specific. -+ * -+ * Each macrotile consists of m x n (mostly 4 x 4) tiles. -+ * Pixel data pitch/stride is aligned with macrotile width. -+ * Pixel data height is aligned with macrotile height. -+ * Entire pixel data buffer is aligned with 4k(bytes). -+ */ -+#define DRM_FORMAT_MOD_QCOM_COMPRESSED fourcc_mod_code(QCOM, 1) -+ -+/* Vivante framebuffer modifiers */ -+ -+/* -+ * Vivante 4x4 tiling layout -+ * -+ * This is a simple tiled layout using tiles of 4x4 pixels in a row-major -+ * layout. -+ */ -+#define DRM_FORMAT_MOD_VIVANTE_TILED fourcc_mod_code(VIVANTE, 1) -+ -+/* -+ * Vivante 64x64 super-tiling layout -+ * -+ * This is a tiled layout using 64x64 pixel super-tiles, where each super-tile -+ * contains 8x4 groups of 2x4 tiles of 4x4 pixels (like above) each, all in row- -+ * major layout. -+ * -+ * For more information: see -+ * https://github.com/etnaviv/etna_viv/blob/master/doc/hardware.md#texture-tiling -+ */ -+#define DRM_FORMAT_MOD_VIVANTE_SUPER_TILED fourcc_mod_code(VIVANTE, 2) -+ -+/* -+ * Vivante 4x4 tiling layout for dual-pipe -+ * -+ * Same as the 4x4 tiling layout, except every second 4x4 pixel tile starts at a -+ * different base address. Offsets from the base addresses are therefore halved -+ * compared to the non-split tiled layout. -+ */ -+#define DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED fourcc_mod_code(VIVANTE, 3) -+ -+/* -+ * Vivante 64x64 super-tiling layout for dual-pipe -+ * -+ * Same as the 64x64 super-tiling layout, except every second 4x4 pixel tile -+ * starts at a different base address. Offsets from the base addresses are -+ * therefore halved compared to the non-split super-tiled layout. -+ */ -+#define DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED fourcc_mod_code(VIVANTE, 4) -+ -+/* NVIDIA frame buffer modifiers */ -+ -+/* -+ * Tegra Tiled Layout, used by Tegra 2, 3 and 4. -+ * -+ * Pixels are arranged in simple tiles of 16 x 16 bytes. -+ */ -+#define DRM_FORMAT_MOD_NVIDIA_TEGRA_TILED fourcc_mod_code(NVIDIA, 1) -+ -+/* -+ * Generalized Block Linear layout, used by desktop GPUs starting with NV50/G80, -+ * and Tegra GPUs starting with Tegra K1. -+ * -+ * Pixels are arranged in Groups of Bytes (GOBs). GOB size and layout varies -+ * based on the architecture generation. GOBs themselves are then arranged in -+ * 3D blocks, with the block dimensions (in terms of GOBs) always being a power -+ * of two, and hence expressible as their log2 equivalent (E.g., "2" represents -+ * a block depth or height of "4"). -+ * -+ * Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format -+ * in full detail. -+ * -+ * Macro -+ * Bits Param Description -+ * ---- ----- ----------------------------------------------------------------- -+ * -+ * 3:0 h log2(height) of each block, in GOBs. Placed here for -+ * compatibility with the existing -+ * DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK()-based modifiers. -+ * -+ * 4:4 - Must be 1, to indicate block-linear layout. Necessary for -+ * compatibility with the existing -+ * DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK()-based modifiers. -+ * -+ * 8:5 - Reserved (To support 3D-surfaces with variable log2(depth) block -+ * size). Must be zero. -+ * -+ * Note there is no log2(width) parameter. Some portions of the -+ * hardware support a block width of two gobs, but it is impractical -+ * to use due to lack of support elsewhere, and has no known -+ * benefits. -+ * -+ * 11:9 - Reserved (To support 2D-array textures with variable array stride -+ * in blocks, specified via log2(tile width in blocks)). Must be -+ * zero. -+ * -+ * 19:12 k Page Kind. This value directly maps to a field in the page -+ * tables of all GPUs >= NV50. It affects the exact layout of bits -+ * in memory and can be derived from the tuple -+ * -+ * (format, GPU model, compression type, samples per pixel) -+ * -+ * Where compression type is defined below. If GPU model were -+ * implied by the format modifier, format, or memory buffer, page -+ * kind would not need to be included in the modifier itself, but -+ * since the modifier should define the layout of the associated -+ * memory buffer independent from any device or other context, it -+ * must be included here. -+ * -+ * 21:20 g GOB Height and Page Kind Generation. The height of a GOB changed -+ * starting with Fermi GPUs. Additionally, the mapping between page -+ * kind and bit layout has changed at various points. -+ * -+ * 0 = Gob Height 8, Fermi - Volta, Tegra K1+ Page Kind mapping -+ * 1 = Gob Height 4, G80 - GT2XX Page Kind mapping -+ * 2 = Gob Height 8, Turing+ Page Kind mapping -+ * 3 = Reserved for future use. -+ * -+ * 22:22 s Sector layout. On Tegra GPUs prior to Xavier, there is a further -+ * bit remapping step that occurs at an even lower level than the -+ * page kind and block linear swizzles. This causes the layout of -+ * surfaces mapped in those SOC's GPUs to be incompatible with the -+ * equivalent mapping on other GPUs in the same system. -+ * -+ * 0 = Tegra K1 - Tegra Parker/TX2 Layout. -+ * 1 = Desktop GPU and Tegra Xavier+ Layout -+ * -+ * 25:23 c Lossless Framebuffer Compression type. -+ * -+ * 0 = none -+ * 1 = ROP/3D, layout 1, exact compression format implied by Page -+ * Kind field -+ * 2 = ROP/3D, layout 2, exact compression format implied by Page -+ * Kind field -+ * 3 = CDE horizontal -+ * 4 = CDE vertical -+ * 5 = Reserved for future use -+ * 6 = Reserved for future use -+ * 7 = Reserved for future use -+ * -+ * 55:25 - Reserved for future use. Must be zero. -+ */ -+#define DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(c, s, g, k, h) \ -+ fourcc_mod_code(NVIDIA, (0x10 | \ -+ ((h) & 0xf) | \ -+ (((k) & 0xff) << 12) | \ -+ (((g) & 0x3) << 20) | \ -+ (((s) & 0x1) << 22) | \ -+ (((c) & 0x7) << 23))) -+ -+/* To grandfather in prior block linear format modifiers to the above layout, -+ * the page kind "0", which corresponds to "pitch/linear" and hence is unusable -+ * with block-linear layouts, is remapped within drivers to the value 0xfe, -+ * which corresponds to the "generic" kind used for simple single-sample -+ * uncompressed color formats on Fermi - Volta GPUs. -+ */ -+static __inline__ __u64 -+drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) -+{ -+ if (!(modifier & 0x10) || (modifier & (0xff << 12))) -+ return modifier; -+ else -+ return modifier | (0xfe << 12); -+} -+ -+/* -+ * 16Bx2 Block Linear layout, used by Tegra K1 and later -+ * -+ * Pixels are arranged in 64x8 Groups Of Bytes (GOBs). GOBs are then stacked -+ * vertically by a power of 2 (1 to 32 GOBs) to form a block. -+ * -+ * Within a GOB, data is ordered as 16B x 2 lines sectors laid in Z-shape. -+ * -+ * Parameter 'v' is the log2 encoding of the number of GOBs stacked vertically. -+ * Valid values are: -+ * -+ * 0 == ONE_GOB -+ * 1 == TWO_GOBS -+ * 2 == FOUR_GOBS -+ * 3 == EIGHT_GOBS -+ * 4 == SIXTEEN_GOBS -+ * 5 == THIRTYTWO_GOBS -+ * -+ * Chapter 20 "Pixel Memory Formats" of the Tegra X1 TRM describes this format -+ * in full detail. -+ */ -+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(v) \ -+ DRM_FORMAT_MOD_NVIDIA_BLOCK_LINEAR_2D(0, 0, 0, 0, (v)) -+ -+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_ONE_GOB \ -+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(0) -+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_TWO_GOB \ -+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(1) -+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_FOUR_GOB \ -+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(2) -+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_EIGHT_GOB \ -+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(3) -+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_SIXTEEN_GOB \ -+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(4) -+#define DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK_THIRTYTWO_GOB \ -+ DRM_FORMAT_MOD_NVIDIA_16BX2_BLOCK(5) -+ -+/* -+ * Some Broadcom modifiers take parameters, for example the number of -+ * vertical lines in the image. Reserve the lower 32 bits for modifier -+ * type, and the next 24 bits for parameters. Top 8 bits are the -+ * vendor code. -+ */ -+#define __fourcc_mod_broadcom_param_shift 8 -+#define __fourcc_mod_broadcom_param_bits 48 -+#define fourcc_mod_broadcom_code(val, params) \ -+ fourcc_mod_code(BROADCOM, ((((__u64)params) << __fourcc_mod_broadcom_param_shift) | val)) -+#define fourcc_mod_broadcom_param(m) \ -+ ((int)(((m) >> __fourcc_mod_broadcom_param_shift) & \ -+ ((1ULL << __fourcc_mod_broadcom_param_bits) - 1))) -+#define fourcc_mod_broadcom_mod(m) \ -+ ((m) & ~(((1ULL << __fourcc_mod_broadcom_param_bits) - 1) << \ -+ __fourcc_mod_broadcom_param_shift)) -+ -+/* -+ * Broadcom VC4 "T" format -+ * -+ * This is the primary layout that the V3D GPU can texture from (it -+ * can't do linear). The T format has: -+ * -+ * - 64b utiles of pixels in a raster-order grid according to cpp. It's 4x4 -+ * pixels at 32 bit depth. -+ * -+ * - 1k subtiles made of a 4x4 raster-order grid of 64b utiles (so usually -+ * 16x16 pixels). -+ * -+ * - 4k tiles made of a 2x2 grid of 1k subtiles (so usually 32x32 pixels). On -+ * even 4k tile rows, they're arranged as (BL, TL, TR, BR), and on odd rows -+ * they're (TR, BR, BL, TL), where bottom left is start of memory. -+ * -+ * - an image made of 4k tiles in rows either left-to-right (even rows of 4k -+ * tiles) or right-to-left (odd rows of 4k tiles). -+ */ -+#define DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED fourcc_mod_code(BROADCOM, 1) -+ -+/* -+ * Broadcom SAND format -+ * -+ * This is the native format that the H.264 codec block uses. For VC4 -+ * HVS, it is only valid for H.264 (NV12/21) and RGBA modes. -+ * -+ * The image can be considered to be split into columns, and the -+ * columns are placed consecutively into memory. The width of those -+ * columns can be either 32, 64, 128, or 256 pixels, but in practice -+ * only 128 pixel columns are used. -+ * -+ * The pitch between the start of each column is set to optimally -+ * switch between SDRAM banks. This is passed as the number of lines -+ * of column width in the modifier (we can't use the stride value due -+ * to various core checks that look at it , so you should set the -+ * stride to width*cpp). -+ * -+ * Note that the column height for this format modifier is the same -+ * for all of the planes, assuming that each column contains both Y -+ * and UV. Some SAND-using hardware stores UV in a separate tiled -+ * image from Y to reduce the column height, which is not supported -+ * with these modifiers. -+ */ -+ -+#define DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(v) \ -+ fourcc_mod_broadcom_code(2, v) -+#define DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT(v) \ -+ fourcc_mod_broadcom_code(3, v) -+#define DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(v) \ -+ fourcc_mod_broadcom_code(4, v) -+#define DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT(v) \ -+ fourcc_mod_broadcom_code(5, v) -+ -+#define DRM_FORMAT_MOD_BROADCOM_SAND32 \ -+ DRM_FORMAT_MOD_BROADCOM_SAND32_COL_HEIGHT(0) -+#define DRM_FORMAT_MOD_BROADCOM_SAND64 \ -+ DRM_FORMAT_MOD_BROADCOM_SAND64_COL_HEIGHT(0) -+#define DRM_FORMAT_MOD_BROADCOM_SAND128 \ -+ DRM_FORMAT_MOD_BROADCOM_SAND128_COL_HEIGHT(0) -+#define DRM_FORMAT_MOD_BROADCOM_SAND256 \ -+ DRM_FORMAT_MOD_BROADCOM_SAND256_COL_HEIGHT(0) -+ -+/* Broadcom UIF format -+ * -+ * This is the common format for the current Broadcom multimedia -+ * blocks, including V3D 3.x and newer, newer video codecs, and -+ * displays. -+ * -+ * The image consists of utiles (64b blocks), UIF blocks (2x2 utiles), -+ * and macroblocks (4x4 UIF blocks). Those 4x4 UIF block groups are -+ * stored in columns, with padding between the columns to ensure that -+ * moving from one column to the next doesn't hit the same SDRAM page -+ * bank. -+ * -+ * To calculate the padding, it is assumed that each hardware block -+ * and the software driving it knows the platform's SDRAM page size, -+ * number of banks, and XOR address, and that it's identical between -+ * all blocks using the format. This tiling modifier will use XOR as -+ * necessary to reduce the padding. If a hardware block can't do XOR, -+ * the assumption is that a no-XOR tiling modifier will be created. -+ */ -+#define DRM_FORMAT_MOD_BROADCOM_UIF fourcc_mod_code(BROADCOM, 6) -+ -+/* -+ * Arm Framebuffer Compression (AFBC) modifiers -+ * -+ * AFBC is a proprietary lossless image compression protocol and format. -+ * It provides fine-grained random access and minimizes the amount of data -+ * transferred between IP blocks. -+ * -+ * AFBC has several features which may be supported and/or used, which are -+ * represented using bits in the modifier. Not all combinations are valid, -+ * and different devices or use-cases may support different combinations. -+ * -+ * Further information on the use of AFBC modifiers can be found in -+ * Documentation/gpu/afbc.rst -+ */ -+ -+/* -+ * The top 4 bits (out of the 56 bits alloted for specifying vendor specific -+ * modifiers) denote the category for modifiers. Currently we have three -+ * categories of modifiers ie AFBC, MISC and AFRC. We can have a maximum of -+ * sixteen different categories. -+ */ -+#define DRM_FORMAT_MOD_ARM_CODE(__type, __val) \ -+ fourcc_mod_code(ARM, ((__u64)(__type) << 52) | ((__val) & 0x000fffffffffffffULL)) -+ -+#define DRM_FORMAT_MOD_ARM_TYPE_AFBC 0x00 -+#define DRM_FORMAT_MOD_ARM_TYPE_MISC 0x01 -+ -+#define DRM_FORMAT_MOD_ARM_AFBC(__afbc_mode) \ -+ DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_AFBC, __afbc_mode) -+ -+/* -+ * AFBC superblock size -+ * -+ * Indicates the superblock size(s) used for the AFBC buffer. The buffer -+ * size (in pixels) must be aligned to a multiple of the superblock size. -+ * Four lowest significant bits(LSBs) are reserved for block size. -+ * -+ * Where one superblock size is specified, it applies to all planes of the -+ * buffer (e.g. 16x16, 32x8). When multiple superblock sizes are specified, -+ * the first applies to the Luma plane and the second applies to the Chroma -+ * plane(s). e.g. (32x8_64x4 means 32x8 Luma, with 64x4 Chroma). -+ * Multiple superblock sizes are only valid for multi-plane YCbCr formats. -+ */ -+#define AFBC_FORMAT_MOD_BLOCK_SIZE_MASK 0xf -+#define AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 (1ULL) -+#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 (2ULL) -+#define AFBC_FORMAT_MOD_BLOCK_SIZE_64x4 (3ULL) -+#define AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4 (4ULL) -+ -+/* -+ * AFBC lossless colorspace transform -+ * -+ * Indicates that the buffer makes use of the AFBC lossless colorspace -+ * transform. -+ */ -+#define AFBC_FORMAT_MOD_YTR (1ULL << 4) -+ -+/* -+ * AFBC block-split -+ * -+ * Indicates that the payload of each superblock is split. The second -+ * half of the payload is positioned at a predefined offset from the start -+ * of the superblock payload. -+ */ -+#define AFBC_FORMAT_MOD_SPLIT (1ULL << 5) -+ -+/* -+ * AFBC sparse layout -+ * -+ * This flag indicates that the payload of each superblock must be stored at a -+ * predefined position relative to the other superblocks in the same AFBC -+ * buffer. This order is the same order used by the header buffer. In this mode -+ * each superblock is given the same amount of space as an uncompressed -+ * superblock of the particular format would require, rounding up to the next -+ * multiple of 128 bytes in size. -+ */ -+#define AFBC_FORMAT_MOD_SPARSE (1ULL << 6) -+ -+/* -+ * AFBC copy-block restrict -+ * -+ * Buffers with this flag must obey the copy-block restriction. The restriction -+ * is such that there are no copy-blocks referring across the border of 8x8 -+ * blocks. For the subsampled data the 8x8 limitation is also subsampled. -+ */ -+#define AFBC_FORMAT_MOD_CBR (1ULL << 7) -+ -+/* -+ * AFBC tiled layout -+ * -+ * The tiled layout groups superblocks in 8x8 or 4x4 tiles, where all -+ * superblocks inside a tile are stored together in memory. 8x8 tiles are used -+ * for pixel formats up to and including 32 bpp while 4x4 tiles are used for -+ * larger bpp formats. The order between the tiles is scan line. -+ * When the tiled layout is used, the buffer size (in pixels) must be aligned -+ * to the tile size. -+ */ -+#define AFBC_FORMAT_MOD_TILED (1ULL << 8) -+ -+/* -+ * AFBC solid color blocks -+ * -+ * Indicates that the buffer makes use of solid-color blocks, whereby bandwidth -+ * can be reduced if a whole superblock is a single color. -+ */ -+#define AFBC_FORMAT_MOD_SC (1ULL << 9) -+ -+/* -+ * AFBC double-buffer -+ * -+ * Indicates that the buffer is allocated in a layout safe for front-buffer -+ * rendering. -+ */ -+#define AFBC_FORMAT_MOD_DB (1ULL << 10) -+ -+/* -+ * AFBC buffer content hints -+ * -+ * Indicates that the buffer includes per-superblock content hints. -+ */ -+#define AFBC_FORMAT_MOD_BCH (1ULL << 11) -+ -+/* AFBC uncompressed storage mode -+ * -+ * Indicates that the buffer is using AFBC uncompressed storage mode. -+ * In this mode all superblock payloads in the buffer use the uncompressed -+ * storage mode, which is usually only used for data which cannot be compressed. -+ * The buffer layout is the same as for AFBC buffers without USM set, this only -+ * affects the storage mode of the individual superblocks. Note that even a -+ * buffer without USM set may use uncompressed storage mode for some or all -+ * superblocks, USM just guarantees it for all. -+ */ -+#define AFBC_FORMAT_MOD_USM (1ULL << 12) -+ -+/* -+ * Arm Fixed-Rate Compression (AFRC) modifiers -+ * -+ * AFRC is a proprietary fixed rate image compression protocol and format, -+ * designed to provide guaranteed bandwidth and memory footprint -+ * reductions in graphics and media use-cases. -+ * -+ * AFRC buffers consist of one or more planes, with the same components -+ * and meaning as an uncompressed buffer using the same pixel format. -+ * -+ * Within each plane, the pixel/luma/chroma values are grouped into -+ * "coding unit" blocks which are individually compressed to a -+ * fixed size (in bytes). All coding units within a given plane of a buffer -+ * store the same number of values, and have the same compressed size. -+ * -+ * The coding unit size is configurable, allowing different rates of compression. -+ * -+ * The start of each AFRC buffer plane must be aligned to an alignment granule which -+ * depends on the coding unit size. -+ * -+ * Coding Unit Size Plane Alignment -+ * ---------------- --------------- -+ * 16 bytes 1024 bytes -+ * 24 bytes 512 bytes -+ * 32 bytes 2048 bytes -+ * -+ * Coding units are grouped into paging tiles. AFRC buffer dimensions must be aligned -+ * to a multiple of the paging tile dimensions. -+ * The dimensions of each paging tile depend on whether the buffer is optimised for -+ * scanline (SCAN layout) or rotated (ROT layout) access. -+ * -+ * Layout Paging Tile Width Paging Tile Height -+ * ------ ----------------- ------------------ -+ * SCAN 16 coding units 4 coding units -+ * ROT 8 coding units 8 coding units -+ * -+ * The dimensions of each coding unit depend on the number of components -+ * in the compressed plane and whether the buffer is optimised for -+ * scanline (SCAN layout) or rotated (ROT layout) access. -+ * -+ * Number of Components in Plane Layout Coding Unit Width Coding Unit Height -+ * ----------------------------- --------- ----------------- ------------------ -+ * 1 SCAN 16 samples 4 samples -+ * Example: 16x4 luma samples in a 'Y' plane -+ * 16x4 chroma 'V' values, in the 'V' plane of a fully-planar YUV buffer -+ * ----------------------------- --------- ----------------- ------------------ -+ * 1 ROT 8 samples 8 samples -+ * Example: 8x8 luma samples in a 'Y' plane -+ * 8x8 chroma 'V' values, in the 'V' plane of a fully-planar YUV buffer -+ * ----------------------------- --------- ----------------- ------------------ -+ * 2 DONT CARE 8 samples 4 samples -+ * Example: 8x4 chroma pairs in the 'UV' plane of a semi-planar YUV buffer -+ * ----------------------------- --------- ----------------- ------------------ -+ * 3 DONT CARE 4 samples 4 samples -+ * Example: 4x4 pixels in an RGB buffer without alpha -+ * ----------------------------- --------- ----------------- ------------------ -+ * 4 DONT CARE 4 samples 4 samples -+ * Example: 4x4 pixels in an RGB buffer with alpha -+ */ -+ -+#define DRM_FORMAT_MOD_ARM_TYPE_AFRC 0x02 -+ -+#define DRM_FORMAT_MOD_ARM_AFRC(__afrc_mode) \ -+ DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_AFRC, __afrc_mode) -+ -+/* -+ * AFRC coding unit size modifier. -+ * -+ * Indicates the number of bytes used to store each compressed coding unit for -+ * one or more planes in an AFRC encoded buffer. The coding unit size for chrominance -+ * is the same for both Cb and Cr, which may be stored in separate planes. -+ * -+ * AFRC_FORMAT_MOD_CU_SIZE_P0 indicates the number of bytes used to store -+ * each compressed coding unit in the first plane of the buffer. For RGBA buffers -+ * this is the only plane, while for semi-planar and fully-planar YUV buffers, -+ * this corresponds to the luma plane. -+ * -+ * AFRC_FORMAT_MOD_CU_SIZE_P12 indicates the number of bytes used to store -+ * each compressed coding unit in the second and third planes in the buffer. -+ * For semi-planar and fully-planar YUV buffers, this corresponds to the chroma plane(s). -+ * -+ * For single-plane buffers, AFRC_FORMAT_MOD_CU_SIZE_P0 must be specified -+ * and AFRC_FORMAT_MOD_CU_SIZE_P12 must be zero. -+ * For semi-planar and fully-planar buffers, both AFRC_FORMAT_MOD_CU_SIZE_P0 and -+ * AFRC_FORMAT_MOD_CU_SIZE_P12 must be specified. -+ */ -+#define AFRC_FORMAT_MOD_CU_SIZE_MASK 0xf -+#define AFRC_FORMAT_MOD_CU_SIZE_16 (1ULL) -+#define AFRC_FORMAT_MOD_CU_SIZE_24 (2ULL) -+#define AFRC_FORMAT_MOD_CU_SIZE_32 (3ULL) -+ -+#define AFRC_FORMAT_MOD_CU_SIZE_P0(__afrc_cu_size) (__afrc_cu_size) -+#define AFRC_FORMAT_MOD_CU_SIZE_P12(__afrc_cu_size) ((__afrc_cu_size) << 4) -+ -+/* -+ * AFRC scanline memory layout. -+ * -+ * Indicates if the buffer uses the scanline-optimised layout -+ * for an AFRC encoded buffer, otherwise, it uses the rotation-optimised layout. -+ * The memory layout is the same for all planes. -+ */ -+#define AFRC_FORMAT_MOD_LAYOUT_SCAN (1ULL << 8) -+ -+/* -+ * Arm 16x16 Block U-Interleaved modifier -+ * -+ * This is used by Arm Mali Utgard and Midgard GPUs. It divides the image -+ * into 16x16 pixel blocks. Blocks are stored linearly in order, but pixels -+ * in the block are reordered. -+ */ -+#define DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED \ -+ DRM_FORMAT_MOD_ARM_CODE(DRM_FORMAT_MOD_ARM_TYPE_MISC, 1ULL) -+ -+/* -+ * Allwinner tiled modifier -+ * -+ * This tiling mode is implemented by the VPU found on all Allwinner platforms, -+ * codenamed sunxi. It is associated with a YUV format that uses either 2 or 3 -+ * planes. -+ * -+ * With this tiling, the luminance samples are disposed in tiles representing -+ * 32x32 pixels and the chrominance samples in tiles representing 32x64 pixels. -+ * The pixel order in each tile is linear and the tiles are disposed linearly, -+ * both in row-major order. -+ */ -+#define DRM_FORMAT_MOD_ALLWINNER_TILED fourcc_mod_code(ALLWINNER, 1) -+ -+/* -+ * Amlogic Video Framebuffer Compression modifiers -+ * -+ * Amlogic uses a proprietary lossless image compression protocol and format -+ * for their hardware video codec accelerators, either video decoders or -+ * video input encoders. -+ * -+ * It considerably reduces memory bandwidth while writing and reading -+ * frames in memory. -+ * -+ * The underlying storage is considered to be 3 components, 8bit or 10-bit -+ * per component YCbCr 420, single plane : -+ * - DRM_FORMAT_YUV420_8BIT -+ * - DRM_FORMAT_YUV420_10BIT -+ * -+ * The first 8 bits of the mode defines the layout, then the following 8 bits -+ * defines the options changing the layout. -+ * -+ * Not all combinations are valid, and different SoCs may support different -+ * combinations of layout and options. -+ */ -+#define __fourcc_mod_amlogic_layout_mask 0xff -+#define __fourcc_mod_amlogic_options_shift 8 -+#define __fourcc_mod_amlogic_options_mask 0xff -+ -+#define DRM_FORMAT_MOD_AMLOGIC_FBC(__layout, __options) \ -+ fourcc_mod_code(AMLOGIC, \ -+ ((__layout) & __fourcc_mod_amlogic_layout_mask) | \ -+ (((__options) & __fourcc_mod_amlogic_options_mask) \ -+ << __fourcc_mod_amlogic_options_shift)) -+ -+/* Amlogic FBC Layouts */ -+ -+/* -+ * Amlogic FBC Basic Layout -+ * -+ * The basic layout is composed of: -+ * - a body content organized in 64x32 superblocks with 4096 bytes per -+ * superblock in default mode. -+ * - a 32 bytes per 128x64 header block -+ * -+ * This layout is transferrable between Amlogic SoCs supporting this modifier. -+ */ -+#define AMLOGIC_FBC_LAYOUT_BASIC (1ULL) -+ -+/* -+ * Amlogic FBC Scatter Memory layout -+ * -+ * Indicates the header contains IOMMU references to the compressed -+ * frames content to optimize memory access and layout. -+ * -+ * In this mode, only the header memory address is needed, thus the -+ * content memory organization is tied to the current producer -+ * execution and cannot be saved/dumped neither transferrable between -+ * Amlogic SoCs supporting this modifier. -+ * -+ * Due to the nature of the layout, these buffers are not expected to -+ * be accessible by the user-space clients, but only accessible by the -+ * hardware producers and consumers. -+ * -+ * The user-space clients should expect a failure while trying to mmap -+ * the DMA-BUF handle returned by the producer. -+ */ -+#define AMLOGIC_FBC_LAYOUT_SCATTER (2ULL) -+ -+/* Amlogic FBC Layout Options Bit Mask */ -+ -+/* -+ * Amlogic FBC Memory Saving mode -+ * -+ * Indicates the storage is packed when pixel size is multiple of word -+ * boudaries, i.e. 8bit should be stored in this mode to save allocation -+ * memory. -+ * -+ * This mode reduces body layout to 3072 bytes per 64x32 superblock with -+ * the basic layout and 3200 bytes per 64x32 superblock combined with -+ * the scatter layout. -+ */ -+#define AMLOGIC_FBC_OPTION_MEM_SAVING (1ULL << 0) -+ -+/* -+ * AMD modifiers -+ * -+ * Memory layout: -+ * -+ * without DCC: -+ * - main surface -+ * -+ * with DCC & without DCC_RETILE: -+ * - main surface in plane 0 -+ * - DCC surface in plane 1 (RB-aligned, pipe-aligned if DCC_PIPE_ALIGN is set) -+ * -+ * with DCC & DCC_RETILE: -+ * - main surface in plane 0 -+ * - displayable DCC surface in plane 1 (not RB-aligned & not pipe-aligned) -+ * - pipe-aligned DCC surface in plane 2 (RB-aligned & pipe-aligned) -+ * -+ * For multi-plane formats the above surfaces get merged into one plane for -+ * each format plane, based on the required alignment only. -+ * -+ * Bits Parameter Notes -+ * ----- ------------------------ --------------------------------------------- -+ * -+ * 7:0 TILE_VERSION Values are AMD_FMT_MOD_TILE_VER_* -+ * 12:8 TILE Values are AMD_FMT_MOD_TILE__* -+ * 13 DCC -+ * 14 DCC_RETILE -+ * 15 DCC_PIPE_ALIGN -+ * 16 DCC_INDEPENDENT_64B -+ * 17 DCC_INDEPENDENT_128B -+ * 19:18 DCC_MAX_COMPRESSED_BLOCK Values are AMD_FMT_MOD_DCC_BLOCK_* -+ * 20 DCC_CONSTANT_ENCODE -+ * 23:21 PIPE_XOR_BITS Only for some chips -+ * 26:24 BANK_XOR_BITS Only for some chips -+ * 29:27 PACKERS Only for some chips -+ * 32:30 RB Only for some chips -+ * 35:33 PIPE Only for some chips -+ * 55:36 - Reserved for future use, must be zero -+ */ -+#define AMD_FMT_MOD fourcc_mod_code(AMD, 0) -+ -+#define IS_AMD_FMT_MOD(val) (((val) >> 56) == DRM_FORMAT_MOD_VENDOR_AMD) -+ -+/* Reserve 0 for GFX8 and older */ -+#define AMD_FMT_MOD_TILE_VER_GFX9 1 -+#define AMD_FMT_MOD_TILE_VER_GFX10 2 -+#define AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS 3 -+ -+/* -+ * 64K_S is the same for GFX9/GFX10/GFX10_RBPLUS and hence has GFX9 as canonical -+ * version. -+ */ -+#define AMD_FMT_MOD_TILE_GFX9_64K_S 9 -+ -+/* -+ * 64K_D for non-32 bpp is the same for GFX9/GFX10/GFX10_RBPLUS and hence has -+ * GFX9 as canonical version. -+ */ -+#define AMD_FMT_MOD_TILE_GFX9_64K_D 10 -+#define AMD_FMT_MOD_TILE_GFX9_64K_S_X 25 -+#define AMD_FMT_MOD_TILE_GFX9_64K_D_X 26 -+#define AMD_FMT_MOD_TILE_GFX9_64K_R_X 27 -+ -+#define AMD_FMT_MOD_DCC_BLOCK_64B 0 -+#define AMD_FMT_MOD_DCC_BLOCK_128B 1 -+#define AMD_FMT_MOD_DCC_BLOCK_256B 2 -+ -+#define AMD_FMT_MOD_TILE_VERSION_SHIFT 0 -+#define AMD_FMT_MOD_TILE_VERSION_MASK 0xFF -+#define AMD_FMT_MOD_TILE_SHIFT 8 -+#define AMD_FMT_MOD_TILE_MASK 0x1F -+ -+/* Whether DCC compression is enabled. */ -+#define AMD_FMT_MOD_DCC_SHIFT 13 -+#define AMD_FMT_MOD_DCC_MASK 0x1 -+ -+/* -+ * Whether to include two DCC surfaces, one which is rb & pipe aligned, and -+ * one which is not-aligned. -+ */ -+#define AMD_FMT_MOD_DCC_RETILE_SHIFT 14 -+#define AMD_FMT_MOD_DCC_RETILE_MASK 0x1 -+ -+/* Only set if DCC_RETILE = false */ -+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_SHIFT 15 -+#define AMD_FMT_MOD_DCC_PIPE_ALIGN_MASK 0x1 -+ -+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_SHIFT 16 -+#define AMD_FMT_MOD_DCC_INDEPENDENT_64B_MASK 0x1 -+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_SHIFT 17 -+#define AMD_FMT_MOD_DCC_INDEPENDENT_128B_MASK 0x1 -+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_SHIFT 18 -+#define AMD_FMT_MOD_DCC_MAX_COMPRESSED_BLOCK_MASK 0x3 -+ -+/* -+ * DCC supports embedding some clear colors directly in the DCC surface. -+ * However, on older GPUs the rendering HW ignores the embedded clear color -+ * and prefers the driver provided color. This necessitates doing a fastclear -+ * eliminate operation before a process transfers control. -+ * -+ * If this bit is set that means the fastclear eliminate is not needed for these -+ * embeddable colors. -+ */ -+#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_SHIFT 20 -+#define AMD_FMT_MOD_DCC_CONSTANT_ENCODE_MASK 0x1 -+ -+/* -+ * The below fields are for accounting for per GPU differences. These are only -+ * relevant for GFX9 and later and if the tile field is *_X/_T. -+ * -+ * PIPE_XOR_BITS = always needed -+ * BANK_XOR_BITS = only for TILE_VER_GFX9 -+ * PACKERS = only for TILE_VER_GFX10_RBPLUS -+ * RB = only for TILE_VER_GFX9 & DCC -+ * PIPE = only for TILE_VER_GFX9 & DCC & (DCC_RETILE | DCC_PIPE_ALIGN) -+ */ -+#define AMD_FMT_MOD_PIPE_XOR_BITS_SHIFT 21 -+#define AMD_FMT_MOD_PIPE_XOR_BITS_MASK 0x7 -+#define AMD_FMT_MOD_BANK_XOR_BITS_SHIFT 24 -+#define AMD_FMT_MOD_BANK_XOR_BITS_MASK 0x7 -+#define AMD_FMT_MOD_PACKERS_SHIFT 27 -+#define AMD_FMT_MOD_PACKERS_MASK 0x7 -+#define AMD_FMT_MOD_RB_SHIFT 30 -+#define AMD_FMT_MOD_RB_MASK 0x7 -+#define AMD_FMT_MOD_PIPE_SHIFT 33 -+#define AMD_FMT_MOD_PIPE_MASK 0x7 -+ -+#define AMD_FMT_MOD_SET(field, value) \ -+ ((uint64_t)(value) << AMD_FMT_MOD_##field##_SHIFT) -+#define AMD_FMT_MOD_GET(field, value) \ -+ (((value) >> AMD_FMT_MOD_##field##_SHIFT) & AMD_FMT_MOD_##field##_MASK) -+#define AMD_FMT_MOD_CLEAR(field) \ -+ (~((uint64_t)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT)) -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif /* DRM_FOURCC_H */ -diff --git a/third_party/drm/drm/drm_mode.h b/third_party/drm/drm/drm_mode.h -new file mode 100644 -index 0000000..e1e3516 ---- /dev/null -+++ b/third_party/drm/drm/drm_mode.h -@@ -0,0 +1,1217 @@ -+/* -+ * Copyright (c) 2007 Dave Airlie -+ * Copyright (c) 2007 Jakob Bornecrantz -+ * Copyright (c) 2008 Red Hat Inc. -+ * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA -+ * Copyright (c) 2007-2008 Intel Corporation -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be included in -+ * all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#ifndef _DRM_MODE_H -+#define _DRM_MODE_H -+ -+#include "drm.h" -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+/** -+ * DOC: overview -+ * -+ * DRM exposes many UAPI and structure definition to have a consistent -+ * and standardized interface with user. -+ * Userspace can refer to these structure definitions and UAPI formats -+ * to communicate to driver -+ */ -+ -+#define DRM_CONNECTOR_NAME_LEN 32 -+#define DRM_DISPLAY_MODE_LEN 32 -+#define DRM_PROP_NAME_LEN 32 -+ -+#define DRM_MODE_TYPE_BUILTIN (1<<0) /* deprecated */ -+#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) /* deprecated */ -+#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN) /* deprecated */ -+#define DRM_MODE_TYPE_PREFERRED (1<<3) -+#define DRM_MODE_TYPE_DEFAULT (1<<4) /* deprecated */ -+#define DRM_MODE_TYPE_USERDEF (1<<5) -+#define DRM_MODE_TYPE_DRIVER (1<<6) -+ -+#define DRM_MODE_TYPE_ALL (DRM_MODE_TYPE_PREFERRED | \ -+ DRM_MODE_TYPE_USERDEF | \ -+ DRM_MODE_TYPE_DRIVER) -+ -+/* Video mode flags */ -+/* bit compatible with the xrandr RR_ definitions (bits 0-13) -+ * -+ * ABI warning: Existing userspace really expects -+ * the mode flags to match the xrandr definitions. Any -+ * changes that don't match the xrandr definitions will -+ * likely need a new client cap or some other mechanism -+ * to avoid breaking existing userspace. This includes -+ * allocating new flags in the previously unused bits! -+ */ -+#define DRM_MODE_FLAG_PHSYNC (1<<0) -+#define DRM_MODE_FLAG_NHSYNC (1<<1) -+#define DRM_MODE_FLAG_PVSYNC (1<<2) -+#define DRM_MODE_FLAG_NVSYNC (1<<3) -+#define DRM_MODE_FLAG_INTERLACE (1<<4) -+#define DRM_MODE_FLAG_DBLSCAN (1<<5) -+#define DRM_MODE_FLAG_CSYNC (1<<6) -+#define DRM_MODE_FLAG_PCSYNC (1<<7) -+#define DRM_MODE_FLAG_NCSYNC (1<<8) -+#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ -+#define DRM_MODE_FLAG_BCAST (1<<10) /* deprecated */ -+#define DRM_MODE_FLAG_PIXMUX (1<<11) /* deprecated */ -+#define DRM_MODE_FLAG_DBLCLK (1<<12) -+#define DRM_MODE_FLAG_CLKDIV2 (1<<13) -+ /* -+ * When adding a new stereo mode don't forget to adjust DRM_MODE_FLAGS_3D_MAX -+ * (define not exposed to user space). -+ */ -+#define DRM_MODE_FLAG_3D_MASK (0x1f<<14) -+#define DRM_MODE_FLAG_3D_NONE (0<<14) -+#define DRM_MODE_FLAG_3D_FRAME_PACKING (1<<14) -+#define DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE (2<<14) -+#define DRM_MODE_FLAG_3D_LINE_ALTERNATIVE (3<<14) -+#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL (4<<14) -+#define DRM_MODE_FLAG_3D_L_DEPTH (5<<14) -+#define DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH (6<<14) -+#define DRM_MODE_FLAG_3D_TOP_AND_BOTTOM (7<<14) -+#define DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF (8<<14) -+ -+/* Picture aspect ratio options */ -+#define DRM_MODE_PICTURE_ASPECT_NONE 0 -+#define DRM_MODE_PICTURE_ASPECT_4_3 1 -+#define DRM_MODE_PICTURE_ASPECT_16_9 2 -+#define DRM_MODE_PICTURE_ASPECT_64_27 3 -+#define DRM_MODE_PICTURE_ASPECT_256_135 4 -+ -+/* Content type options */ -+#define DRM_MODE_CONTENT_TYPE_NO_DATA 0 -+#define DRM_MODE_CONTENT_TYPE_GRAPHICS 1 -+#define DRM_MODE_CONTENT_TYPE_PHOTO 2 -+#define DRM_MODE_CONTENT_TYPE_CINEMA 3 -+#define DRM_MODE_CONTENT_TYPE_GAME 4 -+ -+/* Aspect ratio flag bitmask (4 bits 22:19) */ -+#define DRM_MODE_FLAG_PIC_AR_MASK (0x0F<<19) -+#define DRM_MODE_FLAG_PIC_AR_NONE \ -+ (DRM_MODE_PICTURE_ASPECT_NONE<<19) -+#define DRM_MODE_FLAG_PIC_AR_4_3 \ -+ (DRM_MODE_PICTURE_ASPECT_4_3<<19) -+#define DRM_MODE_FLAG_PIC_AR_16_9 \ -+ (DRM_MODE_PICTURE_ASPECT_16_9<<19) -+#define DRM_MODE_FLAG_PIC_AR_64_27 \ -+ (DRM_MODE_PICTURE_ASPECT_64_27<<19) -+#define DRM_MODE_FLAG_PIC_AR_256_135 \ -+ (DRM_MODE_PICTURE_ASPECT_256_135<<19) -+ -+#define DRM_MODE_FLAG_ALL (DRM_MODE_FLAG_PHSYNC | \ -+ DRM_MODE_FLAG_NHSYNC | \ -+ DRM_MODE_FLAG_PVSYNC | \ -+ DRM_MODE_FLAG_NVSYNC | \ -+ DRM_MODE_FLAG_INTERLACE | \ -+ DRM_MODE_FLAG_DBLSCAN | \ -+ DRM_MODE_FLAG_CSYNC | \ -+ DRM_MODE_FLAG_PCSYNC | \ -+ DRM_MODE_FLAG_NCSYNC | \ -+ DRM_MODE_FLAG_HSKEW | \ -+ DRM_MODE_FLAG_DBLCLK | \ -+ DRM_MODE_FLAG_CLKDIV2 | \ -+ DRM_MODE_FLAG_3D_MASK) -+ -+/* DPMS flags */ -+/* bit compatible with the xorg definitions. */ -+#define DRM_MODE_DPMS_ON 0 -+#define DRM_MODE_DPMS_STANDBY 1 -+#define DRM_MODE_DPMS_SUSPEND 2 -+#define DRM_MODE_DPMS_OFF 3 -+ -+/* Scaling mode options */ -+#define DRM_MODE_SCALE_NONE 0 /* Unmodified timing (display or -+ software can still scale) */ -+#define DRM_MODE_SCALE_FULLSCREEN 1 /* Full screen, ignore aspect */ -+#define DRM_MODE_SCALE_CENTER 2 /* Centered, no scaling */ -+#define DRM_MODE_SCALE_ASPECT 3 /* Full screen, preserve aspect */ -+ -+/* Dithering mode options */ -+#define DRM_MODE_DITHERING_OFF 0 -+#define DRM_MODE_DITHERING_ON 1 -+#define DRM_MODE_DITHERING_AUTO 2 -+ -+/* Dirty info options */ -+#define DRM_MODE_DIRTY_OFF 0 -+#define DRM_MODE_DIRTY_ON 1 -+#define DRM_MODE_DIRTY_ANNOTATE 2 -+ -+/* Link Status options */ -+#define DRM_MODE_LINK_STATUS_GOOD 0 -+#define DRM_MODE_LINK_STATUS_BAD 1 -+ -+/* -+ * DRM_MODE_ROTATE_ -+ * -+ * Signals that a drm plane is been rotated degrees in counter -+ * clockwise direction. -+ * -+ * This define is provided as a convenience, looking up the property id -+ * using the name->prop id lookup is the preferred method. -+ */ -+#define DRM_MODE_ROTATE_0 (1<<0) -+#define DRM_MODE_ROTATE_90 (1<<1) -+#define DRM_MODE_ROTATE_180 (1<<2) -+#define DRM_MODE_ROTATE_270 (1<<3) -+ -+/* -+ * DRM_MODE_ROTATE_MASK -+ * -+ * Bitmask used to look for drm plane rotations. -+ */ -+#define DRM_MODE_ROTATE_MASK (\ -+ DRM_MODE_ROTATE_0 | \ -+ DRM_MODE_ROTATE_90 | \ -+ DRM_MODE_ROTATE_180 | \ -+ DRM_MODE_ROTATE_270) -+ -+/* -+ * DRM_MODE_REFLECT_ -+ * -+ * Signals that the contents of a drm plane is reflected along the axis, -+ * in the same way as mirroring. -+ * See kerneldoc chapter "Plane Composition Properties" for more details. -+ * -+ * This define is provided as a convenience, looking up the property id -+ * using the name->prop id lookup is the preferred method. -+ */ -+#define DRM_MODE_REFLECT_X (1<<4) -+#define DRM_MODE_REFLECT_Y (1<<5) -+ -+/* -+ * DRM_MODE_REFLECT_MASK -+ * -+ * Bitmask used to look for drm plane reflections. -+ */ -+#define DRM_MODE_REFLECT_MASK (\ -+ DRM_MODE_REFLECT_X | \ -+ DRM_MODE_REFLECT_Y) -+ -+/* Content Protection Flags */ -+#define DRM_MODE_CONTENT_PROTECTION_UNDESIRED 0 -+#define DRM_MODE_CONTENT_PROTECTION_DESIRED 1 -+#define DRM_MODE_CONTENT_PROTECTION_ENABLED 2 -+ -+/** -+ * struct drm_mode_modeinfo - Display mode information. -+ * @clock: pixel clock in kHz -+ * @hdisplay: horizontal display size -+ * @hsync_start: horizontal sync start -+ * @hsync_end: horizontal sync end -+ * @htotal: horizontal total size -+ * @hskew: horizontal skew -+ * @vdisplay: vertical display size -+ * @vsync_start: vertical sync start -+ * @vsync_end: vertical sync end -+ * @vtotal: vertical total size -+ * @vscan: vertical scan -+ * @vrefresh: approximate vertical refresh rate in Hz -+ * @flags: bitmask of misc. flags, see DRM_MODE_FLAG_* defines -+ * @type: bitmask of type flags, see DRM_MODE_TYPE_* defines -+ * @name: string describing the mode resolution -+ * -+ * This is the user-space API display mode information structure. For the -+ * kernel version see struct drm_display_mode. -+ */ -+struct drm_mode_modeinfo { -+ __u32 clock; -+ __u16 hdisplay; -+ __u16 hsync_start; -+ __u16 hsync_end; -+ __u16 htotal; -+ __u16 hskew; -+ __u16 vdisplay; -+ __u16 vsync_start; -+ __u16 vsync_end; -+ __u16 vtotal; -+ __u16 vscan; -+ -+ __u32 vrefresh; -+ -+ __u32 flags; -+ __u32 type; -+ char name[DRM_DISPLAY_MODE_LEN]; -+}; -+ -+struct drm_mode_card_res { -+ __u64 fb_id_ptr; -+ __u64 crtc_id_ptr; -+ __u64 connector_id_ptr; -+ __u64 encoder_id_ptr; -+ __u32 count_fbs; -+ __u32 count_crtcs; -+ __u32 count_connectors; -+ __u32 count_encoders; -+ __u32 min_width; -+ __u32 max_width; -+ __u32 min_height; -+ __u32 max_height; -+}; -+ -+struct drm_mode_crtc { -+ __u64 set_connectors_ptr; -+ __u32 count_connectors; -+ -+ __u32 crtc_id; /**< Id */ -+ __u32 fb_id; /**< Id of framebuffer */ -+ -+ __u32 x; /**< x Position on the framebuffer */ -+ __u32 y; /**< y Position on the framebuffer */ -+ -+ __u32 gamma_size; -+ __u32 mode_valid; -+ struct drm_mode_modeinfo mode; -+}; -+ -+#define DRM_MODE_PRESENT_TOP_FIELD (1<<0) -+#define DRM_MODE_PRESENT_BOTTOM_FIELD (1<<1) -+ -+/* Planes blend with or override other bits on the CRTC */ -+struct drm_mode_set_plane { -+ __u32 plane_id; -+ __u32 crtc_id; -+ __u32 fb_id; /* fb object contains surface format type */ -+ __u32 flags; /* see above flags */ -+ -+ /* Signed dest location allows it to be partially off screen */ -+ __s32 crtc_x; -+ __s32 crtc_y; -+ __u32 crtc_w; -+ __u32 crtc_h; -+ -+ /* Source values are 16.16 fixed point */ -+ __u32 src_x; -+ __u32 src_y; -+ __u32 src_h; -+ __u32 src_w; -+}; -+ -+/** -+ * struct drm_mode_get_plane - Get plane metadata. -+ * -+ * Userspace can perform a GETPLANE ioctl to retrieve information about a -+ * plane. -+ * -+ * To retrieve the number of formats supported, set @count_format_types to zero -+ * and call the ioctl. @count_format_types will be updated with the value. -+ * -+ * To retrieve these formats, allocate an array with the memory needed to store -+ * @count_format_types formats. Point @format_type_ptr to this array and call -+ * the ioctl again (with @count_format_types still set to the value returned in -+ * the first ioctl call). -+ */ -+struct drm_mode_get_plane { -+ /** -+ * @plane_id: Object ID of the plane whose information should be -+ * retrieved. Set by caller. -+ */ -+ __u32 plane_id; -+ -+ /** @crtc_id: Object ID of the current CRTC. */ -+ __u32 crtc_id; -+ /** @fb_id: Object ID of the current fb. */ -+ __u32 fb_id; -+ -+ /** -+ * @possible_crtcs: Bitmask of CRTC's compatible with the plane. CRTC's -+ * are created and they receive an index, which corresponds to their -+ * position in the bitmask. Bit N corresponds to -+ * :ref:`CRTC index` N. -+ */ -+ __u32 possible_crtcs; -+ /** @gamma_size: Never used. */ -+ __u32 gamma_size; -+ -+ /** @count_format_types: Number of formats. */ -+ __u32 count_format_types; -+ /** -+ * @format_type_ptr: Pointer to ``__u32`` array of formats that are -+ * supported by the plane. These formats do not require modifiers. -+ */ -+ __u64 format_type_ptr; -+}; -+ -+struct drm_mode_get_plane_res { -+ __u64 plane_id_ptr; -+ __u32 count_planes; -+}; -+ -+#define DRM_MODE_ENCODER_NONE 0 -+#define DRM_MODE_ENCODER_DAC 1 -+#define DRM_MODE_ENCODER_TMDS 2 -+#define DRM_MODE_ENCODER_LVDS 3 -+#define DRM_MODE_ENCODER_TVDAC 4 -+#define DRM_MODE_ENCODER_VIRTUAL 5 -+#define DRM_MODE_ENCODER_DSI 6 -+#define DRM_MODE_ENCODER_DPMST 7 -+#define DRM_MODE_ENCODER_DPI 8 -+ -+struct drm_mode_get_encoder { -+ __u32 encoder_id; -+ __u32 encoder_type; -+ -+ __u32 crtc_id; /**< Id of crtc */ -+ -+ __u32 possible_crtcs; -+ __u32 possible_clones; -+}; -+ -+/* This is for connectors with multiple signal types. */ -+/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */ -+enum drm_mode_subconnector { -+ DRM_MODE_SUBCONNECTOR_Automatic = 0, /* DVI-I, TV */ -+ DRM_MODE_SUBCONNECTOR_Unknown = 0, /* DVI-I, TV, DP */ -+ DRM_MODE_SUBCONNECTOR_VGA = 1, /* DP */ -+ DRM_MODE_SUBCONNECTOR_DVID = 3, /* DVI-I DP */ -+ DRM_MODE_SUBCONNECTOR_DVIA = 4, /* DVI-I */ -+ DRM_MODE_SUBCONNECTOR_Composite = 5, /* TV */ -+ DRM_MODE_SUBCONNECTOR_SVIDEO = 6, /* TV */ -+ DRM_MODE_SUBCONNECTOR_Component = 8, /* TV */ -+ DRM_MODE_SUBCONNECTOR_SCART = 9, /* TV */ -+ DRM_MODE_SUBCONNECTOR_DisplayPort = 10, /* DP */ -+ DRM_MODE_SUBCONNECTOR_HDMIA = 11, /* DP */ -+ DRM_MODE_SUBCONNECTOR_Native = 15, /* DP */ -+ DRM_MODE_SUBCONNECTOR_Wireless = 18, /* DP */ -+}; -+ -+#define DRM_MODE_CONNECTOR_Unknown 0 -+#define DRM_MODE_CONNECTOR_VGA 1 -+#define DRM_MODE_CONNECTOR_DVII 2 -+#define DRM_MODE_CONNECTOR_DVID 3 -+#define DRM_MODE_CONNECTOR_DVIA 4 -+#define DRM_MODE_CONNECTOR_Composite 5 -+#define DRM_MODE_CONNECTOR_SVIDEO 6 -+#define DRM_MODE_CONNECTOR_LVDS 7 -+#define DRM_MODE_CONNECTOR_Component 8 -+#define DRM_MODE_CONNECTOR_9PinDIN 9 -+#define DRM_MODE_CONNECTOR_DisplayPort 10 -+#define DRM_MODE_CONNECTOR_HDMIA 11 -+#define DRM_MODE_CONNECTOR_HDMIB 12 -+#define DRM_MODE_CONNECTOR_TV 13 -+#define DRM_MODE_CONNECTOR_eDP 14 -+#define DRM_MODE_CONNECTOR_VIRTUAL 15 -+#define DRM_MODE_CONNECTOR_DSI 16 -+#define DRM_MODE_CONNECTOR_DPI 17 -+#define DRM_MODE_CONNECTOR_WRITEBACK 18 -+#define DRM_MODE_CONNECTOR_SPI 19 -+#define DRM_MODE_CONNECTOR_USB 20 -+ -+/** -+ * struct drm_mode_get_connector - Get connector metadata. -+ * -+ * User-space can perform a GETCONNECTOR ioctl to retrieve information about a -+ * connector. User-space is expected to retrieve encoders, modes and properties -+ * by performing this ioctl at least twice: the first time to retrieve the -+ * number of elements, the second time to retrieve the elements themselves. -+ * -+ * To retrieve the number of elements, set @count_props and @count_encoders to -+ * zero, set @count_modes to 1, and set @modes_ptr to a temporary struct -+ * drm_mode_modeinfo element. -+ * -+ * To retrieve the elements, allocate arrays for @encoders_ptr, @modes_ptr, -+ * @props_ptr and @prop_values_ptr, then set @count_modes, @count_props and -+ * @count_encoders to their capacity. -+ * -+ * Performing the ioctl only twice may be racy: the number of elements may have -+ * changed with a hotplug event in-between the two ioctls. User-space is -+ * expected to retry the last ioctl until the number of elements stabilizes. -+ * The kernel won't fill any array which doesn't have the expected length. -+ * -+ * **Force-probing a connector** -+ * -+ * If the @count_modes field is set to zero and the DRM client is the current -+ * DRM master, the kernel will perform a forced probe on the connector to -+ * refresh the connector status, modes and EDID. A forced-probe can be slow, -+ * might cause flickering and the ioctl will block. -+ * -+ * User-space needs to force-probe connectors to ensure their metadata is -+ * up-to-date at startup and after receiving a hot-plug event. User-space -+ * may perform a forced-probe when the user explicitly requests it. User-space -+ * shouldn't perform a forced-probe in other situations. -+ */ -+struct drm_mode_get_connector { -+ /** @encoders_ptr: Pointer to ``__u32`` array of object IDs. */ -+ __u64 encoders_ptr; -+ /** @modes_ptr: Pointer to struct drm_mode_modeinfo array. */ -+ __u64 modes_ptr; -+ /** @props_ptr: Pointer to ``__u32`` array of property IDs. */ -+ __u64 props_ptr; -+ /** @prop_values_ptr: Pointer to ``__u64`` array of property values. */ -+ __u64 prop_values_ptr; -+ -+ /** @count_modes: Number of modes. */ -+ __u32 count_modes; -+ /** @count_props: Number of properties. */ -+ __u32 count_props; -+ /** @count_encoders: Number of encoders. */ -+ __u32 count_encoders; -+ -+ /** @encoder_id: Object ID of the current encoder. */ -+ __u32 encoder_id; -+ /** @connector_id: Object ID of the connector. */ -+ __u32 connector_id; -+ /** -+ * @connector_type: Type of the connector. -+ * -+ * See DRM_MODE_CONNECTOR_* defines. -+ */ -+ __u32 connector_type; -+ /** -+ * @connector_type_id: Type-specific connector number. -+ * -+ * This is not an object ID. This is a per-type connector number. Each -+ * (type, type_id) combination is unique across all connectors of a DRM -+ * device. -+ */ -+ __u32 connector_type_id; -+ -+ /** -+ * @connection: Status of the connector. -+ * -+ * See enum drm_connector_status. -+ */ -+ __u32 connection; -+ /** @mm_width: Width of the connected sink in millimeters. */ -+ __u32 mm_width; -+ /** @mm_height: Height of the connected sink in millimeters. */ -+ __u32 mm_height; -+ /** -+ * @subpixel: Subpixel order of the connected sink. -+ * -+ * See enum subpixel_order. -+ */ -+ __u32 subpixel; -+ -+ /** @pad: Padding, must be zero. */ -+ __u32 pad; -+}; -+ -+#define DRM_MODE_PROP_PENDING (1<<0) /* deprecated, do not use */ -+#define DRM_MODE_PROP_RANGE (1<<1) -+#define DRM_MODE_PROP_IMMUTABLE (1<<2) -+#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ -+#define DRM_MODE_PROP_BLOB (1<<4) -+#define DRM_MODE_PROP_BITMASK (1<<5) /* bitmask of enumerated types */ -+ -+/* non-extended types: legacy bitmask, one bit per type: */ -+#define DRM_MODE_PROP_LEGACY_TYPE ( \ -+ DRM_MODE_PROP_RANGE | \ -+ DRM_MODE_PROP_ENUM | \ -+ DRM_MODE_PROP_BLOB | \ -+ DRM_MODE_PROP_BITMASK) -+ -+/* extended-types: rather than continue to consume a bit per type, -+ * grab a chunk of the bits to use as integer type id. -+ */ -+#define DRM_MODE_PROP_EXTENDED_TYPE 0x0000ffc0 -+#define DRM_MODE_PROP_TYPE(n) ((n) << 6) -+#define DRM_MODE_PROP_OBJECT DRM_MODE_PROP_TYPE(1) -+#define DRM_MODE_PROP_SIGNED_RANGE DRM_MODE_PROP_TYPE(2) -+ -+/* the PROP_ATOMIC flag is used to hide properties from userspace that -+ * is not aware of atomic properties. This is mostly to work around -+ * older userspace (DDX drivers) that read/write each prop they find, -+ * witout being aware that this could be triggering a lengthy modeset. -+ */ -+#define DRM_MODE_PROP_ATOMIC 0x80000000 -+ -+/** -+ * struct drm_mode_property_enum - Description for an enum/bitfield entry. -+ * @value: numeric value for this enum entry. -+ * @name: symbolic name for this enum entry. -+ * -+ * See struct drm_property_enum for details. -+ */ -+struct drm_mode_property_enum { -+ __u64 value; -+ char name[DRM_PROP_NAME_LEN]; -+}; -+ -+/** -+ * struct drm_mode_get_property - Get property metadata. -+ * -+ * User-space can perform a GETPROPERTY ioctl to retrieve information about a -+ * property. The same property may be attached to multiple objects, see -+ * "Modeset Base Object Abstraction". -+ * -+ * The meaning of the @values_ptr field changes depending on the property type. -+ * See &drm_property.flags for more details. -+ * -+ * The @enum_blob_ptr and @count_enum_blobs fields are only meaningful when the -+ * property has the type &DRM_MODE_PROP_ENUM or &DRM_MODE_PROP_BITMASK. For -+ * backwards compatibility, the kernel will always set @count_enum_blobs to -+ * zero when the property has the type &DRM_MODE_PROP_BLOB. User-space must -+ * ignore these two fields if the property has a different type. -+ * -+ * User-space is expected to retrieve values and enums by performing this ioctl -+ * at least twice: the first time to retrieve the number of elements, the -+ * second time to retrieve the elements themselves. -+ * -+ * To retrieve the number of elements, set @count_values and @count_enum_blobs -+ * to zero, then call the ioctl. @count_values will be updated with the number -+ * of elements. If the property has the type &DRM_MODE_PROP_ENUM or -+ * &DRM_MODE_PROP_BITMASK, @count_enum_blobs will be updated as well. -+ * -+ * To retrieve the elements themselves, allocate an array for @values_ptr and -+ * set @count_values to its capacity. If the property has the type -+ * &DRM_MODE_PROP_ENUM or &DRM_MODE_PROP_BITMASK, allocate an array for -+ * @enum_blob_ptr and set @count_enum_blobs to its capacity. Calling the ioctl -+ * again will fill the arrays. -+ */ -+struct drm_mode_get_property { -+ /** @values_ptr: Pointer to a ``__u64`` array. */ -+ __u64 values_ptr; -+ /** @enum_blob_ptr: Pointer to a struct drm_mode_property_enum array. */ -+ __u64 enum_blob_ptr; -+ -+ /** -+ * @prop_id: Object ID of the property which should be retrieved. Set -+ * by the caller. -+ */ -+ __u32 prop_id; -+ /** -+ * @flags: ``DRM_MODE_PROP_*`` bitfield. See &drm_property.flags for -+ * a definition of the flags. -+ */ -+ __u32 flags; -+ /** -+ * @name: Symbolic property name. User-space should use this field to -+ * recognize properties. -+ */ -+ char name[DRM_PROP_NAME_LEN]; -+ -+ /** @count_values: Number of elements in @values_ptr. */ -+ __u32 count_values; -+ /** @count_enum_blobs: Number of elements in @enum_blob_ptr. */ -+ __u32 count_enum_blobs; -+}; -+ -+struct drm_mode_connector_set_property { -+ __u64 value; -+ __u32 prop_id; -+ __u32 connector_id; -+}; -+ -+#define DRM_MODE_OBJECT_CRTC 0xcccccccc -+#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0 -+#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0 -+#define DRM_MODE_OBJECT_MODE 0xdededede -+#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0 -+#define DRM_MODE_OBJECT_FB 0xfbfbfbfb -+#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb -+#define DRM_MODE_OBJECT_PLANE 0xeeeeeeee -+#define DRM_MODE_OBJECT_ANY 0 -+ -+struct drm_mode_obj_get_properties { -+ __u64 props_ptr; -+ __u64 prop_values_ptr; -+ __u32 count_props; -+ __u32 obj_id; -+ __u32 obj_type; -+}; -+ -+struct drm_mode_obj_set_property { -+ __u64 value; -+ __u32 prop_id; -+ __u32 obj_id; -+ __u32 obj_type; -+}; -+ -+struct drm_mode_get_blob { -+ __u32 blob_id; -+ __u32 length; -+ __u64 data; -+}; -+ -+struct drm_mode_fb_cmd { -+ __u32 fb_id; -+ __u32 width; -+ __u32 height; -+ __u32 pitch; -+ __u32 bpp; -+ __u32 depth; -+ /* driver specific handle */ -+ __u32 handle; -+}; -+ -+#define DRM_MODE_FB_INTERLACED (1<<0) /* for interlaced framebuffers */ -+#define DRM_MODE_FB_MODIFIERS (1<<1) /* enables ->modifer[] */ -+ -+struct drm_mode_fb_cmd2 { -+ __u32 fb_id; -+ __u32 width; -+ __u32 height; -+ __u32 pixel_format; /* fourcc code from drm_fourcc.h */ -+ __u32 flags; /* see above flags */ -+ -+ /* -+ * In case of planar formats, this ioctl allows up to 4 -+ * buffer objects with offsets and pitches per plane. -+ * The pitch and offset order is dictated by the fourcc, -+ * e.g. NV12 (https://fourcc.org/yuv.php#NV12) is described as: -+ * -+ * YUV 4:2:0 image with a plane of 8 bit Y samples -+ * followed by an interleaved U/V plane containing -+ * 8 bit 2x2 subsampled colour difference samples. -+ * -+ * So it would consist of Y as offsets[0] and UV as -+ * offsets[1]. Note that offsets[0] will generally -+ * be 0 (but this is not required). -+ * -+ * To accommodate tiled, compressed, etc formats, a -+ * modifier can be specified. The default value of zero -+ * indicates "native" format as specified by the fourcc. -+ * Vendor specific modifier token. Note that even though -+ * it looks like we have a modifier per-plane, we in fact -+ * do not. The modifier for each plane must be identical. -+ * Thus all combinations of different data layouts for -+ * multi plane formats must be enumerated as separate -+ * modifiers. -+ */ -+ __u32 handles[4]; -+ __u32 pitches[4]; /* pitch for each plane */ -+ __u32 offsets[4]; /* offset of each plane */ -+ __u64 modifier[4]; /* ie, tiling, compress */ -+}; -+ -+#define DRM_MODE_FB_DIRTY_ANNOTATE_COPY 0x01 -+#define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02 -+#define DRM_MODE_FB_DIRTY_FLAGS 0x03 -+ -+#define DRM_MODE_FB_DIRTY_MAX_CLIPS 256 -+ -+/* -+ * Mark a region of a framebuffer as dirty. -+ * -+ * Some hardware does not automatically update display contents -+ * as a hardware or software draw to a framebuffer. This ioctl -+ * allows userspace to tell the kernel and the hardware what -+ * regions of the framebuffer have changed. -+ * -+ * The kernel or hardware is free to update more then just the -+ * region specified by the clip rects. The kernel or hardware -+ * may also delay and/or coalesce several calls to dirty into a -+ * single update. -+ * -+ * Userspace may annotate the updates, the annotates are a -+ * promise made by the caller that the change is either a copy -+ * of pixels or a fill of a single color in the region specified. -+ * -+ * If the DRM_MODE_FB_DIRTY_ANNOTATE_COPY flag is given then -+ * the number of updated regions are half of num_clips given, -+ * where the clip rects are paired in src and dst. The width and -+ * height of each one of the pairs must match. -+ * -+ * If the DRM_MODE_FB_DIRTY_ANNOTATE_FILL flag is given the caller -+ * promises that the region specified of the clip rects is filled -+ * completely with a single color as given in the color argument. -+ */ -+ -+struct drm_mode_fb_dirty_cmd { -+ __u32 fb_id; -+ __u32 flags; -+ __u32 color; -+ __u32 num_clips; -+ __u64 clips_ptr; -+}; -+ -+struct drm_mode_mode_cmd { -+ __u32 connector_id; -+ struct drm_mode_modeinfo mode; -+}; -+ -+#define DRM_MODE_CURSOR_BO 0x01 -+#define DRM_MODE_CURSOR_MOVE 0x02 -+#define DRM_MODE_CURSOR_FLAGS 0x03 -+ -+/* -+ * depending on the value in flags different members are used. -+ * -+ * CURSOR_BO uses -+ * crtc_id -+ * width -+ * height -+ * handle - if 0 turns the cursor off -+ * -+ * CURSOR_MOVE uses -+ * crtc_id -+ * x -+ * y -+ */ -+struct drm_mode_cursor { -+ __u32 flags; -+ __u32 crtc_id; -+ __s32 x; -+ __s32 y; -+ __u32 width; -+ __u32 height; -+ /* driver specific handle */ -+ __u32 handle; -+}; -+ -+struct drm_mode_cursor2 { -+ __u32 flags; -+ __u32 crtc_id; -+ __s32 x; -+ __s32 y; -+ __u32 width; -+ __u32 height; -+ /* driver specific handle */ -+ __u32 handle; -+ __s32 hot_x; -+ __s32 hot_y; -+}; -+ -+struct drm_mode_crtc_lut { -+ __u32 crtc_id; -+ __u32 gamma_size; -+ -+ /* pointers to arrays */ -+ __u64 red; -+ __u64 green; -+ __u64 blue; -+}; -+ -+struct drm_color_ctm { -+ /* -+ * Conversion matrix in S31.32 sign-magnitude -+ * (not two's complement!) format. -+ */ -+ __u64 matrix[9]; -+}; -+ -+struct drm_color_lut { -+ /* -+ * Values are mapped linearly to 0.0 - 1.0 range, with 0x0 == 0.0 and -+ * 0xffff == 1.0. -+ */ -+ __u16 red; -+ __u16 green; -+ __u16 blue; -+ __u16 reserved; -+}; -+ -+/** -+ * struct hdr_metadata_infoframe - HDR Metadata Infoframe Data. -+ * -+ * HDR Metadata Infoframe as per CTA 861.G spec. This is expected -+ * to match exactly with the spec. -+ * -+ * Userspace is expected to pass the metadata information as per -+ * the format described in this structure. -+ */ -+struct hdr_metadata_infoframe { -+ /** -+ * @eotf: Electro-Optical Transfer Function (EOTF) -+ * used in the stream. -+ */ -+ __u8 eotf; -+ /** -+ * @metadata_type: Static_Metadata_Descriptor_ID. -+ */ -+ __u8 metadata_type; -+ /** -+ * @display_primaries: Color Primaries of the Data. -+ * These are coded as unsigned 16-bit values in units of -+ * 0.00002, where 0x0000 represents zero and 0xC350 -+ * represents 1.0000. -+ * @display_primaries.x: X cordinate of color primary. -+ * @display_primaries.y: Y cordinate of color primary. -+ */ -+ struct { -+ __u16 x, y; -+ } display_primaries[3]; -+ /** -+ * @white_point: White Point of Colorspace Data. -+ * These are coded as unsigned 16-bit values in units of -+ * 0.00002, where 0x0000 represents zero and 0xC350 -+ * represents 1.0000. -+ * @white_point.x: X cordinate of whitepoint of color primary. -+ * @white_point.y: Y cordinate of whitepoint of color primary. -+ */ -+ struct { -+ __u16 x, y; -+ } white_point; -+ /** -+ * @max_display_mastering_luminance: Max Mastering Display Luminance. -+ * This value is coded as an unsigned 16-bit value in units of 1 cd/m2, -+ * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2. -+ */ -+ __u16 max_display_mastering_luminance; -+ /** -+ * @min_display_mastering_luminance: Min Mastering Display Luminance. -+ * This value is coded as an unsigned 16-bit value in units of -+ * 0.0001 cd/m2, where 0x0001 represents 0.0001 cd/m2 and 0xFFFF -+ * represents 6.5535 cd/m2. -+ */ -+ __u16 min_display_mastering_luminance; -+ /** -+ * @max_cll: Max Content Light Level. -+ * This value is coded as an unsigned 16-bit value in units of 1 cd/m2, -+ * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2. -+ */ -+ __u16 max_cll; -+ /** -+ * @max_fall: Max Frame Average Light Level. -+ * This value is coded as an unsigned 16-bit value in units of 1 cd/m2, -+ * where 0x0001 represents 1 cd/m2 and 0xFFFF represents 65535 cd/m2. -+ */ -+ __u16 max_fall; -+}; -+ -+/** -+ * struct hdr_output_metadata - HDR output metadata -+ * -+ * Metadata Information to be passed from userspace -+ */ -+struct hdr_output_metadata { -+ /** -+ * @metadata_type: Static_Metadata_Descriptor_ID. -+ */ -+ __u32 metadata_type; -+ /** -+ * @hdmi_metadata_type1: HDR Metadata Infoframe. -+ */ -+ union { -+ struct hdr_metadata_infoframe hdmi_metadata_type1; -+ }; -+}; -+ -+#define DRM_MODE_PAGE_FLIP_EVENT 0x01 -+#define DRM_MODE_PAGE_FLIP_ASYNC 0x02 -+#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4 -+#define DRM_MODE_PAGE_FLIP_TARGET_RELATIVE 0x8 -+#define DRM_MODE_PAGE_FLIP_TARGET (DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE | \ -+ DRM_MODE_PAGE_FLIP_TARGET_RELATIVE) -+#define DRM_MODE_PAGE_FLIP_FLAGS (DRM_MODE_PAGE_FLIP_EVENT | \ -+ DRM_MODE_PAGE_FLIP_ASYNC | \ -+ DRM_MODE_PAGE_FLIP_TARGET) -+ -+/* -+ * Request a page flip on the specified crtc. -+ * -+ * This ioctl will ask KMS to schedule a page flip for the specified -+ * crtc. Once any pending rendering targeting the specified fb (as of -+ * ioctl time) has completed, the crtc will be reprogrammed to display -+ * that fb after the next vertical refresh. The ioctl returns -+ * immediately, but subsequent rendering to the current fb will block -+ * in the execbuffer ioctl until the page flip happens. If a page -+ * flip is already pending as the ioctl is called, EBUSY will be -+ * returned. -+ * -+ * Flag DRM_MODE_PAGE_FLIP_EVENT requests that drm sends back a vblank -+ * event (see drm.h: struct drm_event_vblank) when the page flip is -+ * done. The user_data field passed in with this ioctl will be -+ * returned as the user_data field in the vblank event struct. -+ * -+ * Flag DRM_MODE_PAGE_FLIP_ASYNC requests that the flip happen -+ * 'as soon as possible', meaning that it not delay waiting for vblank. -+ * This may cause tearing on the screen. -+ * -+ * The reserved field must be zero. -+ */ -+ -+struct drm_mode_crtc_page_flip { -+ __u32 crtc_id; -+ __u32 fb_id; -+ __u32 flags; -+ __u32 reserved; -+ __u64 user_data; -+}; -+ -+/* -+ * Request a page flip on the specified crtc. -+ * -+ * Same as struct drm_mode_crtc_page_flip, but supports new flags and -+ * re-purposes the reserved field: -+ * -+ * The sequence field must be zero unless either of the -+ * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is specified. When -+ * the ABSOLUTE flag is specified, the sequence field denotes the absolute -+ * vblank sequence when the flip should take effect. When the RELATIVE -+ * flag is specified, the sequence field denotes the relative (to the -+ * current one when the ioctl is called) vblank sequence when the flip -+ * should take effect. NOTE: DRM_IOCTL_WAIT_VBLANK must still be used to -+ * make sure the vblank sequence before the target one has passed before -+ * calling this ioctl. The purpose of the -+ * DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE/RELATIVE flags is merely to clarify -+ * the target for when code dealing with a page flip runs during a -+ * vertical blank period. -+ */ -+ -+struct drm_mode_crtc_page_flip_target { -+ __u32 crtc_id; -+ __u32 fb_id; -+ __u32 flags; -+ __u32 sequence; -+ __u64 user_data; -+}; -+ -+/* create a dumb scanout buffer */ -+struct drm_mode_create_dumb { -+ __u32 height; -+ __u32 width; -+ __u32 bpp; -+ __u32 flags; -+ /* handle, pitch, size will be returned */ -+ __u32 handle; -+ __u32 pitch; -+ __u64 size; -+}; -+ -+/* set up for mmap of a dumb scanout buffer */ -+struct drm_mode_map_dumb { -+ /** Handle for the object being mapped. */ -+ __u32 handle; -+ __u32 pad; -+ /** -+ * Fake offset to use for subsequent mmap call -+ * -+ * This is a fixed-size type for 32/64 compatibility. -+ */ -+ __u64 offset; -+}; -+ -+struct drm_mode_destroy_dumb { -+ __u32 handle; -+}; -+ -+/* page-flip flags are valid, plus: */ -+#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100 -+#define DRM_MODE_ATOMIC_NONBLOCK 0x0200 -+#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400 -+ -+#define DRM_MODE_ATOMIC_FLAGS (\ -+ DRM_MODE_PAGE_FLIP_EVENT |\ -+ DRM_MODE_PAGE_FLIP_ASYNC |\ -+ DRM_MODE_ATOMIC_TEST_ONLY |\ -+ DRM_MODE_ATOMIC_NONBLOCK |\ -+ DRM_MODE_ATOMIC_ALLOW_MODESET) -+ -+struct drm_mode_atomic { -+ __u32 flags; -+ __u32 count_objs; -+ __u64 objs_ptr; -+ __u64 count_props_ptr; -+ __u64 props_ptr; -+ __u64 prop_values_ptr; -+ __u64 reserved; -+ __u64 user_data; -+}; -+ -+struct drm_format_modifier_blob { -+#define FORMAT_BLOB_CURRENT 1 -+ /* Version of this blob format */ -+ __u32 version; -+ -+ /* Flags */ -+ __u32 flags; -+ -+ /* Number of fourcc formats supported */ -+ __u32 count_formats; -+ -+ /* Where in this blob the formats exist (in bytes) */ -+ __u32 formats_offset; -+ -+ /* Number of drm_format_modifiers */ -+ __u32 count_modifiers; -+ -+ /* Where in this blob the modifiers exist (in bytes) */ -+ __u32 modifiers_offset; -+ -+ /* __u32 formats[] */ -+ /* struct drm_format_modifier modifiers[] */ -+}; -+ -+struct drm_format_modifier { -+ /* Bitmask of formats in get_plane format list this info applies to. The -+ * offset allows a sliding window of which 64 formats (bits). -+ * -+ * Some examples: -+ * In today's world with < 65 formats, and formats 0, and 2 are -+ * supported -+ * 0x0000000000000005 -+ * ^-offset = 0, formats = 5 -+ * -+ * If the number formats grew to 128, and formats 98-102 are -+ * supported with the modifier: -+ * -+ * 0x0000007c00000000 0000000000000000 -+ * ^ -+ * |__offset = 64, formats = 0x7c00000000 -+ * -+ */ -+ __u64 formats; -+ __u32 offset; -+ __u32 pad; -+ -+ /* The modifier that applies to the >get_plane format list bitmask. */ -+ __u64 modifier; -+}; -+ -+/** -+ * struct drm_mode_create_blob - Create New blob property -+ * -+ * Create a new 'blob' data property, copying length bytes from data pointer, -+ * and returning new blob ID. -+ */ -+struct drm_mode_create_blob { -+ /** @data: Pointer to data to copy. */ -+ __u64 data; -+ /** @length: Length of data to copy. */ -+ __u32 length; -+ /** @blob_id: Return: new property ID. */ -+ __u32 blob_id; -+}; -+ -+/** -+ * struct drm_mode_destroy_blob - Destroy user blob -+ * @blob_id: blob_id to destroy -+ * -+ * Destroy a user-created blob property. -+ * -+ * User-space can release blobs as soon as they do not need to refer to them by -+ * their blob object ID. For instance, if you are using a MODE_ID blob in an -+ * atomic commit and you will not make another commit re-using the same ID, you -+ * can destroy the blob as soon as the commit has been issued, without waiting -+ * for it to complete. -+ */ -+struct drm_mode_destroy_blob { -+ __u32 blob_id; -+}; -+ -+/** -+ * struct drm_mode_create_lease - Create lease -+ * -+ * Lease mode resources, creating another drm_master. -+ * -+ * The @object_ids array must reference at least one CRTC, one connector and -+ * one plane if &DRM_CLIENT_CAP_UNIVERSAL_PLANES is enabled. Alternatively, -+ * the lease can be completely empty. -+ */ -+struct drm_mode_create_lease { -+ /** @object_ids: Pointer to array of object ids (__u32) */ -+ __u64 object_ids; -+ /** @object_count: Number of object ids */ -+ __u32 object_count; -+ /** @flags: flags for new FD (O_CLOEXEC, etc) */ -+ __u32 flags; -+ -+ /** @lessee_id: Return: unique identifier for lessee. */ -+ __u32 lessee_id; -+ /** @fd: Return: file descriptor to new drm_master file */ -+ __u32 fd; -+}; -+ -+/** -+ * struct drm_mode_list_lessees - List lessees -+ * -+ * List lesses from a drm_master. -+ */ -+struct drm_mode_list_lessees { -+ /** -+ * @count_lessees: Number of lessees. -+ * -+ * On input, provides length of the array. -+ * On output, provides total number. No -+ * more than the input number will be written -+ * back, so two calls can be used to get -+ * the size and then the data. -+ */ -+ __u32 count_lessees; -+ /** @pad: Padding. */ -+ __u32 pad; -+ -+ /** -+ * @lessees_ptr: Pointer to lessees. -+ * -+ * Pointer to __u64 array of lessee ids -+ */ -+ __u64 lessees_ptr; -+}; -+ -+/** -+ * struct drm_mode_get_lease - Get Lease -+ * -+ * Get leased objects. -+ */ -+struct drm_mode_get_lease { -+ /** -+ * @count_objects: Number of leased objects. -+ * -+ * On input, provides length of the array. -+ * On output, provides total number. No -+ * more than the input number will be written -+ * back, so two calls can be used to get -+ * the size and then the data. -+ */ -+ __u32 count_objects; -+ /** @pad: Padding. */ -+ __u32 pad; -+ -+ /** -+ * @objects_ptr: Pointer to objects. -+ * -+ * Pointer to __u32 array of object ids. -+ */ -+ __u64 objects_ptr; -+}; -+ -+/** -+ * struct drm_mode_revoke_lease - Revoke lease -+ */ -+struct drm_mode_revoke_lease { -+ /** @lessee_id: Unique ID of lessee */ -+ __u32 lessee_id; -+}; -+ -+/** -+ * struct drm_mode_rect - Two dimensional rectangle. -+ * @x1: Horizontal starting coordinate (inclusive). -+ * @y1: Vertical starting coordinate (inclusive). -+ * @x2: Horizontal ending coordinate (exclusive). -+ * @y2: Vertical ending coordinate (exclusive). -+ * -+ * With drm subsystem using struct drm_rect to manage rectangular area this -+ * export it to user-space. -+ * -+ * Currently used by drm_mode_atomic blob property FB_DAMAGE_CLIPS. -+ */ -+struct drm_mode_rect { -+ __s32 x1; -+ __s32 y1; -+ __s32 x2; -+ __s32 y2; -+}; -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif -diff --git a/third_party/drm/drm/xf86drm.h b/third_party/drm/drm/xf86drm.h -new file mode 100644 -index 0000000..58d66f1 ---- /dev/null -+++ b/third_party/drm/drm/xf86drm.h -@@ -0,0 +1,966 @@ -+/** -+ * \file xf86drm.h -+ * OS-independent header for DRM user-level library interface. -+ * -+ * \author Rickard E. (Rik) Faith -+ */ -+ -+/* -+ * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. -+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. -+ * All Rights Reserved. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -+ * DEALINGS IN THE SOFTWARE. -+ * -+ */ -+ -+#ifndef _XF86DRM_H_ -+#define _XF86DRM_H_ -+ -+#include -+#include -+#include -+#include -+ -+#if defined(__cplusplus) -+extern "C" { -+#endif -+ -+#ifndef DRM_MAX_MINOR -+#define DRM_MAX_MINOR 16 -+#endif -+ -+#if defined(__linux__) -+ -+#define DRM_IOCTL_NR(n) _IOC_NR(n) -+#define DRM_IOC_VOID _IOC_NONE -+#define DRM_IOC_READ _IOC_READ -+#define DRM_IOC_WRITE _IOC_WRITE -+#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE -+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) -+ -+#else /* One of the *BSDs */ -+ -+#include -+#define DRM_IOCTL_NR(n) ((n) & 0xff) -+#define DRM_IOC_VOID IOC_VOID -+#define DRM_IOC_READ IOC_OUT -+#define DRM_IOC_WRITE IOC_IN -+#define DRM_IOC_READWRITE IOC_INOUT -+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) -+ -+#endif -+ -+ /* Defaults, if nothing set in xf86config */ -+#define DRM_DEV_UID 0 -+#define DRM_DEV_GID 0 -+/* Default /dev/dri directory permissions 0755 */ -+#define DRM_DEV_DIRMODE \ -+ (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) -+#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) -+ -+#ifdef __OpenBSD__ -+#define DRM_DIR_NAME "/dev" -+#define DRM_PRIMARY_MINOR_NAME "drm" -+#define DRM_CONTROL_MINOR_NAME "drmC" -+#define DRM_RENDER_MINOR_NAME "drmR" -+#else -+#define DRM_DIR_NAME "/dev/dri" -+#define DRM_PRIMARY_MINOR_NAME "card" -+#define DRM_CONTROL_MINOR_NAME "controlD" -+#define DRM_RENDER_MINOR_NAME "renderD" -+#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */ -+#endif -+ -+#define DRM_DEV_NAME "%s/" DRM_PRIMARY_MINOR_NAME "%d" -+#define DRM_CONTROL_DEV_NAME "%s/" DRM_CONTROL_MINOR_NAME "%d" -+#define DRM_RENDER_DEV_NAME "%s/" DRM_RENDER_MINOR_NAME "%d" -+ -+#define DRM_NODE_NAME_MAX \ -+ (sizeof(DRM_DIR_NAME) + 1 /* slash */ \ -+ + MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), \ -+ sizeof(DRM_CONTROL_MINOR_NAME), \ -+ sizeof(DRM_RENDER_MINOR_NAME)) \ -+ + sizeof("144") /* highest possible node number */ \ -+ + 1) /* NULL-terminator */ -+ -+#define DRM_ERR_NO_DEVICE (-1001) -+#define DRM_ERR_NO_ACCESS (-1002) -+#define DRM_ERR_NOT_ROOT (-1003) -+#define DRM_ERR_INVALID (-1004) -+#define DRM_ERR_NO_FD (-1005) -+ -+#define DRM_AGP_NO_HANDLE 0 -+ -+typedef unsigned int drmSize, *drmSizePtr; /**< For mapped regions */ -+typedef void *drmAddress, **drmAddressPtr; /**< For mapped regions */ -+ -+#if (__GNUC__ >= 3) -+#define DRM_PRINTFLIKE(f, a) __attribute__ ((format(__printf__, f, a))) -+#else -+#define DRM_PRINTFLIKE(f, a) -+#endif -+ -+typedef struct _drmServerInfo { -+ int (*debug_print)(const char *format, va_list ap) DRM_PRINTFLIKE(1,0); -+ int (*load_module)(const char *name); -+ void (*get_perms)(gid_t *, mode_t *); -+} drmServerInfo, *drmServerInfoPtr; -+ -+typedef struct drmHashEntry { -+ int fd; -+ void (*f)(int, void *, void *); -+ void *tagTable; -+} drmHashEntry; -+ -+extern int drmIoctl(int fd, unsigned long request, void *arg); -+extern void *drmGetHashTable(void); -+extern drmHashEntry *drmGetEntry(int fd); -+ -+/** -+ * Driver version information. -+ * -+ * \sa drmGetVersion() and drmSetVersion(). -+ */ -+typedef struct _drmVersion { -+ int version_major; /**< Major version */ -+ int version_minor; /**< Minor version */ -+ int version_patchlevel; /**< Patch level */ -+ int name_len; /**< Length of name buffer */ -+ char *name; /**< Name of driver */ -+ int date_len; /**< Length of date buffer */ -+ char *date; /**< User-space buffer to hold date */ -+ int desc_len; /**< Length of desc buffer */ -+ char *desc; /**< User-space buffer to hold desc */ -+} drmVersion, *drmVersionPtr; -+ -+typedef struct _drmStats { -+ unsigned long count; /**< Number of data */ -+ struct { -+ unsigned long value; /**< Value from kernel */ -+ const char *long_format; /**< Suggested format for long_name */ -+ const char *long_name; /**< Long name for value */ -+ const char *rate_format; /**< Suggested format for rate_name */ -+ const char *rate_name; /**< Short name for value per second */ -+ int isvalue; /**< True if value (vs. counter) */ -+ const char *mult_names; /**< Multiplier names (e.g., "KGM") */ -+ int mult; /**< Multiplier value (e.g., 1024) */ -+ int verbose; /**< Suggest only in verbose output */ -+ } data[15]; -+} drmStatsT; -+ -+ -+ /* All of these enums *MUST* match with the -+ kernel implementation -- so do *NOT* -+ change them! (The drmlib implementation -+ will just copy the flags instead of -+ translating them.) */ -+typedef enum { -+ DRM_FRAME_BUFFER = 0, /**< WC, no caching, no core dump */ -+ DRM_REGISTERS = 1, /**< no caching, no core dump */ -+ DRM_SHM = 2, /**< shared, cached */ -+ DRM_AGP = 3, /**< AGP/GART */ -+ DRM_SCATTER_GATHER = 4, /**< PCI scatter/gather */ -+ DRM_CONSISTENT = 5 /**< PCI consistent */ -+} drmMapType; -+ -+typedef enum { -+ DRM_RESTRICTED = 0x0001, /**< Cannot be mapped to client-virtual */ -+ DRM_READ_ONLY = 0x0002, /**< Read-only in client-virtual */ -+ DRM_LOCKED = 0x0004, /**< Physical pages locked */ -+ DRM_KERNEL = 0x0008, /**< Kernel requires access */ -+ DRM_WRITE_COMBINING = 0x0010, /**< Use write-combining, if available */ -+ DRM_CONTAINS_LOCK = 0x0020, /**< SHM page that contains lock */ -+ DRM_REMOVABLE = 0x0040 /**< Removable mapping */ -+} drmMapFlags; -+ -+/** -+ * \warning These values *MUST* match drm.h -+ */ -+typedef enum { -+ /** \name Flags for DMA buffer dispatch */ -+ /*@{*/ -+ DRM_DMA_BLOCK = 0x01, /**< -+ * Block until buffer dispatched. -+ * -+ * \note the buffer may not yet have been -+ * processed by the hardware -- getting a -+ * hardware lock with the hardware quiescent -+ * will ensure that the buffer has been -+ * processed. -+ */ -+ DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */ -+ DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */ -+ /*@}*/ -+ -+ /** \name Flags for DMA buffer request */ -+ /*@{*/ -+ DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */ -+ DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */ -+ DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */ -+ /*@}*/ -+} drmDMAFlags; -+ -+typedef enum { -+ DRM_PAGE_ALIGN = 0x01, -+ DRM_AGP_BUFFER = 0x02, -+ DRM_SG_BUFFER = 0x04, -+ DRM_FB_BUFFER = 0x08, -+ DRM_PCI_BUFFER_RO = 0x10 -+} drmBufDescFlags; -+ -+typedef enum { -+ DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */ -+ DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */ -+ DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */ -+ DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */ -+ /* These *HALT* flags aren't supported yet -+ -- they will be used to support the -+ full-screen DGA-like mode. */ -+ DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */ -+ DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */ -+} drmLockFlags; -+ -+typedef enum { -+ DRM_CONTEXT_PRESERVED = 0x01, /**< This context is preserved and -+ never swapped. */ -+ DRM_CONTEXT_2DONLY = 0x02 /**< This context is for 2D rendering only. */ -+} drm_context_tFlags, *drm_context_tFlagsPtr; -+ -+typedef struct _drmBufDesc { -+ int count; /**< Number of buffers of this size */ -+ int size; /**< Size in bytes */ -+ int low_mark; /**< Low water mark */ -+ int high_mark; /**< High water mark */ -+} drmBufDesc, *drmBufDescPtr; -+ -+typedef struct _drmBufInfo { -+ int count; /**< Number of buffers described in list */ -+ drmBufDescPtr list; /**< List of buffer descriptions */ -+} drmBufInfo, *drmBufInfoPtr; -+ -+typedef struct _drmBuf { -+ int idx; /**< Index into the master buffer list */ -+ int total; /**< Buffer size */ -+ int used; /**< Amount of buffer in use (for DMA) */ -+ drmAddress address; /**< Address */ -+} drmBuf, *drmBufPtr; -+ -+/** -+ * Buffer mapping information. -+ * -+ * Used by drmMapBufs() and drmUnmapBufs() to store information about the -+ * mapped buffers. -+ */ -+typedef struct _drmBufMap { -+ int count; /**< Number of buffers mapped */ -+ drmBufPtr list; /**< Buffers */ -+} drmBufMap, *drmBufMapPtr; -+ -+typedef struct _drmLock { -+ volatile unsigned int lock; -+ char padding[60]; -+ /* This is big enough for most current (and future?) architectures: -+ DEC Alpha: 32 bytes -+ Intel Merced: ? -+ Intel P5/PPro/PII/PIII: 32 bytes -+ Intel StrongARM: 32 bytes -+ Intel i386/i486: 16 bytes -+ MIPS: 32 bytes (?) -+ Motorola 68k: 16 bytes -+ Motorola PowerPC: 32 bytes -+ Sun SPARC: 32 bytes -+ */ -+} drmLock, *drmLockPtr; -+ -+/** -+ * Indices here refer to the offset into -+ * list in drmBufInfo -+ */ -+typedef struct _drmDMAReq { -+ drm_context_t context; /**< Context handle */ -+ int send_count; /**< Number of buffers to send */ -+ int *send_list; /**< List of handles to buffers */ -+ int *send_sizes; /**< Lengths of data to send, in bytes */ -+ drmDMAFlags flags; /**< Flags */ -+ int request_count; /**< Number of buffers requested */ -+ int request_size; /**< Desired size of buffers requested */ -+ int *request_list; /**< Buffer information */ -+ int *request_sizes; /**< Minimum acceptable sizes */ -+ int granted_count; /**< Number of buffers granted at this size */ -+} drmDMAReq, *drmDMAReqPtr; -+ -+typedef struct _drmRegion { -+ drm_handle_t handle; -+ unsigned int offset; -+ drmSize size; -+ drmAddress map; -+} drmRegion, *drmRegionPtr; -+ -+typedef struct _drmTextureRegion { -+ unsigned char next; -+ unsigned char prev; -+ unsigned char in_use; -+ unsigned char padding; /**< Explicitly pad this out */ -+ unsigned int age; -+} drmTextureRegion, *drmTextureRegionPtr; -+ -+ -+typedef enum { -+ DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */ -+ DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */ -+ /* bits 1-6 are reserved for high crtcs */ -+ DRM_VBLANK_HIGH_CRTC_MASK = 0x0000003e, -+ DRM_VBLANK_EVENT = 0x4000000, /**< Send event instead of blocking */ -+ DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */ -+ DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */ -+ DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */ -+ DRM_VBLANK_SIGNAL = 0x40000000 /* Send signal instead of blocking */ -+} drmVBlankSeqType; -+#define DRM_VBLANK_HIGH_CRTC_SHIFT 1 -+ -+typedef struct _drmVBlankReq { -+ drmVBlankSeqType type; -+ unsigned int sequence; -+ unsigned long signal; -+} drmVBlankReq, *drmVBlankReqPtr; -+ -+typedef struct _drmVBlankReply { -+ drmVBlankSeqType type; -+ unsigned int sequence; -+ long tval_sec; -+ long tval_usec; -+} drmVBlankReply, *drmVBlankReplyPtr; -+ -+typedef union _drmVBlank { -+ drmVBlankReq request; -+ drmVBlankReply reply; -+} drmVBlank, *drmVBlankPtr; -+ -+typedef struct _drmSetVersion { -+ int drm_di_major; -+ int drm_di_minor; -+ int drm_dd_major; -+ int drm_dd_minor; -+} drmSetVersion, *drmSetVersionPtr; -+ -+#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -+ -+#define DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */ -+#define DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */ -+ -+#if defined(__GNUC__) && (__GNUC__ >= 2) -+# if defined(__i386) || defined(__AMD64__) || defined(__x86_64__) || defined(__amd64__) -+ /* Reflect changes here to drmP.h */ -+#define DRM_CAS(lock,old,new,__ret) \ -+ do { \ -+ int __dummy; /* Can't mark eax as clobbered */ \ -+ __asm__ __volatile__( \ -+ "lock ; cmpxchg %4,%1\n\t" \ -+ "setnz %0" \ -+ : "=d" (__ret), \ -+ "=m" (__drm_dummy_lock(lock)), \ -+ "=a" (__dummy) \ -+ : "2" (old), \ -+ "r" (new)); \ -+ } while (0) -+ -+#elif defined(__alpha__) -+ -+#define DRM_CAS(lock, old, new, ret) \ -+ do { \ -+ int tmp, old32; \ -+ __asm__ __volatile__( \ -+ " addl $31, %5, %3\n" \ -+ "1: ldl_l %0, %2\n" \ -+ " cmpeq %0, %3, %1\n" \ -+ " beq %1, 2f\n" \ -+ " mov %4, %0\n" \ -+ " stl_c %0, %2\n" \ -+ " beq %0, 3f\n" \ -+ " mb\n" \ -+ "2: cmpeq %1, 0, %1\n" \ -+ ".subsection 2\n" \ -+ "3: br 1b\n" \ -+ ".previous" \ -+ : "=&r"(tmp), "=&r"(ret), \ -+ "=m"(__drm_dummy_lock(lock)), \ -+ "=&r"(old32) \ -+ : "r"(new), "r"(old) \ -+ : "memory"); \ -+ } while (0) -+ -+#elif defined(__sparc__) -+ -+#define DRM_CAS(lock,old,new,__ret) \ -+do { register unsigned int __old __asm("o0"); \ -+ register unsigned int __new __asm("o1"); \ -+ register volatile unsigned int *__lock __asm("o2"); \ -+ __old = old; \ -+ __new = new; \ -+ __lock = (volatile unsigned int *)lock; \ -+ __asm__ __volatile__( \ -+ /*"cas [%2], %3, %0"*/ \ -+ ".word 0xd3e29008\n\t" \ -+ /*"membar #StoreStore | #StoreLoad"*/ \ -+ ".word 0x8143e00a" \ -+ : "=&r" (__new) \ -+ : "0" (__new), \ -+ "r" (__lock), \ -+ "r" (__old) \ -+ : "memory"); \ -+ __ret = (__new != __old); \ -+} while(0) -+ -+#elif defined(__ia64__) -+ -+#ifdef __INTEL_COMPILER -+/* this currently generates bad code (missing stop bits)... */ -+#include -+ -+#define DRM_CAS(lock,old,new,__ret) \ -+ do { \ -+ unsigned long __result, __old = (old) & 0xffffffff; \ -+ __mf(); \ -+ __result = _InterlockedCompareExchange_acq(&__drm_dummy_lock(lock), (new), __old);\ -+ __ret = (__result) != (__old); \ -+/* __ret = (__sync_val_compare_and_swap(&__drm_dummy_lock(lock), \ -+ (old), (new)) \ -+ != (old)); */\ -+ } while (0) -+ -+#else -+#define DRM_CAS(lock,old,new,__ret) \ -+ do { \ -+ unsigned int __result, __old = (old); \ -+ __asm__ __volatile__( \ -+ "mf\n" \ -+ "mov ar.ccv=%2\n" \ -+ ";;\n" \ -+ "cmpxchg4.acq %0=%1,%3,ar.ccv" \ -+ : "=r" (__result), "=m" (__drm_dummy_lock(lock)) \ -+ : "r" ((unsigned long)__old), "r" (new) \ -+ : "memory"); \ -+ __ret = (__result) != (__old); \ -+ } while (0) -+ -+#endif -+ -+#elif defined(__powerpc__) -+ -+#define DRM_CAS(lock,old,new,__ret) \ -+ do { \ -+ __asm__ __volatile__( \ -+ "sync;" \ -+ "0: lwarx %0,0,%1;" \ -+ " xor. %0,%3,%0;" \ -+ " bne 1f;" \ -+ " stwcx. %2,0,%1;" \ -+ " bne- 0b;" \ -+ "1: " \ -+ "sync;" \ -+ : "=&r"(__ret) \ -+ : "r"(lock), "r"(new), "r"(old) \ -+ : "cr0", "memory"); \ -+ } while (0) -+ -+# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ -+ || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ -+ || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) \ -+ || defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ -+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ -+ || defined(__ARM_ARCH_7EM__) -+ /* excluding ARMv4/ARMv5 and lower (lacking ldrex/strex support) */ -+ #undef DRM_DEV_MODE -+ #define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) -+ -+ #define DRM_CAS(lock,old,new,__ret) \ -+ do { \ -+ __asm__ __volatile__ ( \ -+ "1: ldrex %0, [%1]\n" \ -+ " teq %0, %2\n" \ -+ " ite eq\n" \ -+ " strexeq %0, %3, [%1]\n" \ -+ " movne %0, #1\n" \ -+ : "=&r" (__ret) \ -+ : "r" (lock), "r" (old), "r" (new) \ -+ : "cc","memory"); \ -+ } while (0) -+ -+#endif /* architecture */ -+#endif /* __GNUC__ >= 2 */ -+ -+#ifndef DRM_CAS -+#define DRM_CAS(lock,old,new,ret) do { ret=1; } while (0) /* FAST LOCK FAILS */ -+#endif -+ -+#if defined(__alpha__) -+#define DRM_CAS_RESULT(_result) long _result -+#elif defined(__powerpc__) -+#define DRM_CAS_RESULT(_result) int _result -+#else -+#define DRM_CAS_RESULT(_result) char _result -+#endif -+ -+#define DRM_LIGHT_LOCK(fd,lock,context) \ -+ do { \ -+ DRM_CAS_RESULT(__ret); \ -+ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ -+ if (__ret) drmGetLock(fd,context,0); \ -+ } while(0) -+ -+ /* This one counts fast locks -- for -+ benchmarking only. */ -+#define DRM_LIGHT_LOCK_COUNT(fd,lock,context,count) \ -+ do { \ -+ DRM_CAS_RESULT(__ret); \ -+ DRM_CAS(lock,context,DRM_LOCK_HELD|context,__ret); \ -+ if (__ret) drmGetLock(fd,context,0); \ -+ else ++count; \ -+ } while(0) -+ -+#define DRM_LOCK(fd,lock,context,flags) \ -+ do { \ -+ if (flags) drmGetLock(fd,context,flags); \ -+ else DRM_LIGHT_LOCK(fd,lock,context); \ -+ } while(0) -+ -+#define DRM_UNLOCK(fd,lock,context) \ -+ do { \ -+ DRM_CAS_RESULT(__ret); \ -+ DRM_CAS(lock,DRM_LOCK_HELD|context,context,__ret); \ -+ if (__ret) drmUnlock(fd,context); \ -+ } while(0) -+ -+ /* Simple spin locks */ -+#define DRM_SPINLOCK(spin,val) \ -+ do { \ -+ DRM_CAS_RESULT(__ret); \ -+ do { \ -+ DRM_CAS(spin,0,val,__ret); \ -+ if (__ret) while ((spin)->lock); \ -+ } while (__ret); \ -+ } while(0) -+ -+#define DRM_SPINLOCK_TAKE(spin,val) \ -+ do { \ -+ DRM_CAS_RESULT(__ret); \ -+ int cur; \ -+ do { \ -+ cur = (*spin).lock; \ -+ DRM_CAS(spin,cur,val,__ret); \ -+ } while (__ret); \ -+ } while(0) -+ -+#define DRM_SPINLOCK_COUNT(spin,val,count,__ret) \ -+ do { \ -+ int __i; \ -+ __ret = 1; \ -+ for (__i = 0; __ret && __i < count; __i++) { \ -+ DRM_CAS(spin,0,val,__ret); \ -+ if (__ret) for (;__i < count && (spin)->lock; __i++); \ -+ } \ -+ } while(0) -+ -+#define DRM_SPINUNLOCK(spin,val) \ -+ do { \ -+ DRM_CAS_RESULT(__ret); \ -+ if ((*spin).lock == val) { /* else server stole lock */ \ -+ do { \ -+ DRM_CAS(spin,val,0,__ret); \ -+ } while (__ret); \ -+ } \ -+ } while(0) -+ -+ -+ -+/* General user-level programmer's API: unprivileged */ -+extern int drmAvailable(void); -+extern int drmOpen(const char *name, const char *busid); -+ -+#define DRM_NODE_PRIMARY 0 -+#define DRM_NODE_CONTROL 1 -+#define DRM_NODE_RENDER 2 -+#define DRM_NODE_MAX 3 -+ -+extern int drmOpenWithType(const char *name, const char *busid, -+ int type); -+ -+extern int drmOpenControl(int minor); -+extern int drmOpenRender(int minor); -+extern int drmClose(int fd); -+extern drmVersionPtr drmGetVersion(int fd); -+extern drmVersionPtr drmGetLibVersion(int fd); -+extern int drmGetCap(int fd, uint64_t capability, uint64_t *value); -+extern void drmFreeVersion(drmVersionPtr); -+extern int drmGetMagic(int fd, drm_magic_t * magic); -+extern char *drmGetBusid(int fd); -+extern int drmGetInterruptFromBusID(int fd, int busnum, int devnum, -+ int funcnum); -+extern int drmGetMap(int fd, int idx, drm_handle_t *offset, -+ drmSize *size, drmMapType *type, -+ drmMapFlags *flags, drm_handle_t *handle, -+ int *mtrr); -+extern int drmGetClient(int fd, int idx, int *auth, int *pid, -+ int *uid, unsigned long *magic, -+ unsigned long *iocs); -+extern int drmGetStats(int fd, drmStatsT *stats); -+extern int drmSetInterfaceVersion(int fd, drmSetVersion *version); -+extern int drmCommandNone(int fd, unsigned long drmCommandIndex); -+extern int drmCommandRead(int fd, unsigned long drmCommandIndex, -+ void *data, unsigned long size); -+extern int drmCommandWrite(int fd, unsigned long drmCommandIndex, -+ void *data, unsigned long size); -+extern int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, -+ void *data, unsigned long size); -+ -+/* General user-level programmer's API: X server (root) only */ -+extern void drmFreeBusid(const char *busid); -+extern int drmSetBusid(int fd, const char *busid); -+extern int drmAuthMagic(int fd, drm_magic_t magic); -+extern int drmAddMap(int fd, -+ drm_handle_t offset, -+ drmSize size, -+ drmMapType type, -+ drmMapFlags flags, -+ drm_handle_t * handle); -+extern int drmRmMap(int fd, drm_handle_t handle); -+extern int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id, -+ drm_handle_t handle); -+ -+extern int drmAddBufs(int fd, int count, int size, -+ drmBufDescFlags flags, -+ int agp_offset); -+extern int drmMarkBufs(int fd, double low, double high); -+extern int drmCreateContext(int fd, drm_context_t * handle); -+extern int drmSetContextFlags(int fd, drm_context_t context, -+ drm_context_tFlags flags); -+extern int drmGetContextFlags(int fd, drm_context_t context, -+ drm_context_tFlagsPtr flags); -+extern int drmAddContextTag(int fd, drm_context_t context, void *tag); -+extern int drmDelContextTag(int fd, drm_context_t context); -+extern void *drmGetContextTag(int fd, drm_context_t context); -+extern drm_context_t * drmGetReservedContextList(int fd, int *count); -+extern void drmFreeReservedContextList(drm_context_t *); -+extern int drmSwitchToContext(int fd, drm_context_t context); -+extern int drmDestroyContext(int fd, drm_context_t handle); -+extern int drmCreateDrawable(int fd, drm_drawable_t * handle); -+extern int drmDestroyDrawable(int fd, drm_drawable_t handle); -+extern int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, -+ drm_drawable_info_type_t type, -+ unsigned int num, void *data); -+extern int drmCtlInstHandler(int fd, int irq); -+extern int drmCtlUninstHandler(int fd); -+extern int drmSetClientCap(int fd, uint64_t capability, -+ uint64_t value); -+ -+extern int drmCrtcGetSequence(int fd, uint32_t crtcId, -+ uint64_t *sequence, uint64_t *ns); -+extern int drmCrtcQueueSequence(int fd, uint32_t crtcId, -+ uint32_t flags, uint64_t sequence, -+ uint64_t *sequence_queued, -+ uint64_t user_data); -+/* General user-level programmer's API: authenticated client and/or X */ -+extern int drmMap(int fd, -+ drm_handle_t handle, -+ drmSize size, -+ drmAddressPtr address); -+extern int drmUnmap(drmAddress address, drmSize size); -+extern drmBufInfoPtr drmGetBufInfo(int fd); -+extern drmBufMapPtr drmMapBufs(int fd); -+extern int drmUnmapBufs(drmBufMapPtr bufs); -+extern int drmDMA(int fd, drmDMAReqPtr request); -+extern int drmFreeBufs(int fd, int count, int *list); -+extern int drmGetLock(int fd, -+ drm_context_t context, -+ drmLockFlags flags); -+extern int drmUnlock(int fd, drm_context_t context); -+extern int drmFinish(int fd, int context, drmLockFlags flags); -+extern int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id, -+ drm_handle_t * handle); -+ -+/* AGP/GART support: X server (root) only */ -+extern int drmAgpAcquire(int fd); -+extern int drmAgpRelease(int fd); -+extern int drmAgpEnable(int fd, unsigned long mode); -+extern int drmAgpAlloc(int fd, unsigned long size, -+ unsigned long type, unsigned long *address, -+ drm_handle_t *handle); -+extern int drmAgpFree(int fd, drm_handle_t handle); -+extern int drmAgpBind(int fd, drm_handle_t handle, -+ unsigned long offset); -+extern int drmAgpUnbind(int fd, drm_handle_t handle); -+ -+/* AGP/GART info: authenticated client and/or X */ -+extern int drmAgpVersionMajor(int fd); -+extern int drmAgpVersionMinor(int fd); -+extern unsigned long drmAgpGetMode(int fd); -+extern unsigned long drmAgpBase(int fd); /* Physical location */ -+extern unsigned long drmAgpSize(int fd); /* Bytes */ -+extern unsigned long drmAgpMemoryUsed(int fd); -+extern unsigned long drmAgpMemoryAvail(int fd); -+extern unsigned int drmAgpVendorId(int fd); -+extern unsigned int drmAgpDeviceId(int fd); -+ -+/* PCI scatter/gather support: X server (root) only */ -+extern int drmScatterGatherAlloc(int fd, unsigned long size, -+ drm_handle_t *handle); -+extern int drmScatterGatherFree(int fd, drm_handle_t handle); -+ -+extern int drmWaitVBlank(int fd, drmVBlankPtr vbl); -+ -+/* Support routines */ -+extern void drmSetServerInfo(drmServerInfoPtr info); -+extern int drmError(int err, const char *label); -+extern void *drmMalloc(int size); -+extern void drmFree(void *pt); -+ -+/* Hash table routines */ -+extern void *drmHashCreate(void); -+extern int drmHashDestroy(void *t); -+extern int drmHashLookup(void *t, unsigned long key, void **value); -+extern int drmHashInsert(void *t, unsigned long key, void *value); -+extern int drmHashDelete(void *t, unsigned long key); -+extern int drmHashFirst(void *t, unsigned long *key, void **value); -+extern int drmHashNext(void *t, unsigned long *key, void **value); -+ -+/* PRNG routines */ -+extern void *drmRandomCreate(unsigned long seed); -+extern int drmRandomDestroy(void *state); -+extern unsigned long drmRandom(void *state); -+extern double drmRandomDouble(void *state); -+ -+/* Skip list routines */ -+ -+extern void *drmSLCreate(void); -+extern int drmSLDestroy(void *l); -+extern int drmSLLookup(void *l, unsigned long key, void **value); -+extern int drmSLInsert(void *l, unsigned long key, void *value); -+extern int drmSLDelete(void *l, unsigned long key); -+extern int drmSLNext(void *l, unsigned long *key, void **value); -+extern int drmSLFirst(void *l, unsigned long *key, void **value); -+extern void drmSLDump(void *l); -+extern int drmSLLookupNeighbors(void *l, unsigned long key, -+ unsigned long *prev_key, void **prev_value, -+ unsigned long *next_key, void **next_value); -+ -+extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened); -+extern int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type); -+extern void drmCloseOnce(int fd); -+extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2); -+ -+extern int drmSetMaster(int fd); -+extern int drmDropMaster(int fd); -+extern int drmIsMaster(int fd); -+ -+#define DRM_EVENT_CONTEXT_VERSION 4 -+ -+typedef struct _drmEventContext { -+ -+ /* This struct is versioned so we can add more pointers if we -+ * add more events. */ -+ int version; -+ -+ void (*vblank_handler)(int fd, -+ unsigned int sequence, -+ unsigned int tv_sec, -+ unsigned int tv_usec, -+ void *user_data); -+ -+ void (*page_flip_handler)(int fd, -+ unsigned int sequence, -+ unsigned int tv_sec, -+ unsigned int tv_usec, -+ void *user_data); -+ -+ void (*page_flip_handler2)(int fd, -+ unsigned int sequence, -+ unsigned int tv_sec, -+ unsigned int tv_usec, -+ unsigned int crtc_id, -+ void *user_data); -+ -+ void (*sequence_handler)(int fd, -+ uint64_t sequence, -+ uint64_t ns, -+ uint64_t user_data); -+} drmEventContext, *drmEventContextPtr; -+ -+extern int drmHandleEvent(int fd, drmEventContextPtr evctx); -+ -+extern char *drmGetDeviceNameFromFd(int fd); -+ -+/* Improved version of drmGetDeviceNameFromFd which attributes for any type of -+ * device/node - card, control or renderD. -+ */ -+extern char *drmGetDeviceNameFromFd2(int fd); -+extern int drmGetNodeTypeFromFd(int fd); -+ -+/* Convert between GEM handles and DMA-BUF file descriptors. -+ * -+ * Warning: since GEM handles are not reference-counted and are unique per -+ * DRM file description, the caller is expected to perform its own reference -+ * counting. drmPrimeFDToHandle is guaranteed to return the same handle for -+ * different FDs if they reference the same underlying buffer object. This -+ * could even be a buffer object originally created on the same DRM FD. -+ * -+ * When sharing a DRM FD with an API such as EGL or GBM, the caller must not -+ * use drmPrimeHandleToFD nor drmPrimeFDToHandle. A single user-space -+ * reference-counting implementation is necessary to avoid double-closing GEM -+ * handles. -+ * -+ * Two processes can't share the same DRM FD and both use it to create or -+ * import GEM handles, even when using a single user-space reference-counting -+ * implementation like GBM, because GBM doesn't share its state between -+ * processes. -+ */ -+extern int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd); -+extern int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle); -+ -+extern int drmCloseBufferHandle(int fd, uint32_t handle); -+ -+extern char *drmGetPrimaryDeviceNameFromFd(int fd); -+extern char *drmGetRenderDeviceNameFromFd(int fd); -+ -+#define DRM_BUS_PCI 0 -+#define DRM_BUS_USB 1 -+#define DRM_BUS_PLATFORM 2 -+#define DRM_BUS_HOST1X 3 -+ -+typedef struct _drmPciBusInfo { -+ uint16_t domain; -+ uint8_t bus; -+ uint8_t dev; -+ uint8_t func; -+} drmPciBusInfo, *drmPciBusInfoPtr; -+ -+typedef struct _drmPciDeviceInfo { -+ uint16_t vendor_id; -+ uint16_t device_id; -+ uint16_t subvendor_id; -+ uint16_t subdevice_id; -+ uint8_t revision_id; -+} drmPciDeviceInfo, *drmPciDeviceInfoPtr; -+ -+typedef struct _drmUsbBusInfo { -+ uint8_t bus; -+ uint8_t dev; -+} drmUsbBusInfo, *drmUsbBusInfoPtr; -+ -+typedef struct _drmUsbDeviceInfo { -+ uint16_t vendor; -+ uint16_t product; -+} drmUsbDeviceInfo, *drmUsbDeviceInfoPtr; -+ -+#define DRM_PLATFORM_DEVICE_NAME_LEN 512 -+ -+typedef struct _drmPlatformBusInfo { -+ char fullname[DRM_PLATFORM_DEVICE_NAME_LEN]; -+} drmPlatformBusInfo, *drmPlatformBusInfoPtr; -+ -+typedef struct _drmPlatformDeviceInfo { -+ char **compatible; /* NULL terminated list of compatible strings */ -+} drmPlatformDeviceInfo, *drmPlatformDeviceInfoPtr; -+ -+#define DRM_HOST1X_DEVICE_NAME_LEN 512 -+ -+typedef struct _drmHost1xBusInfo { -+ char fullname[DRM_HOST1X_DEVICE_NAME_LEN]; -+} drmHost1xBusInfo, *drmHost1xBusInfoPtr; -+ -+typedef struct _drmHost1xDeviceInfo { -+ char **compatible; /* NULL terminated list of compatible strings */ -+} drmHost1xDeviceInfo, *drmHost1xDeviceInfoPtr; -+ -+typedef struct _drmDevice { -+ char **nodes; /* DRM_NODE_MAX sized array */ -+ int available_nodes; /* DRM_NODE_* bitmask */ -+ int bustype; -+ union { -+ drmPciBusInfoPtr pci; -+ drmUsbBusInfoPtr usb; -+ drmPlatformBusInfoPtr platform; -+ drmHost1xBusInfoPtr host1x; -+ } businfo; -+ union { -+ drmPciDeviceInfoPtr pci; -+ drmUsbDeviceInfoPtr usb; -+ drmPlatformDeviceInfoPtr platform; -+ drmHost1xDeviceInfoPtr host1x; -+ } deviceinfo; -+} drmDevice, *drmDevicePtr; -+ -+extern int drmGetDevice(int fd, drmDevicePtr *device); -+extern void drmFreeDevice(drmDevicePtr *device); -+ -+extern int drmGetDevices(drmDevicePtr devices[], int max_devices); -+extern void drmFreeDevices(drmDevicePtr devices[], int count); -+ -+#define DRM_DEVICE_GET_PCI_REVISION (1 << 0) -+extern int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device); -+extern int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices); -+ -+extern int drmGetDeviceFromDevId(dev_t dev_id, uint32_t flags, drmDevicePtr *device); -+ -+extern int drmDevicesEqual(drmDevicePtr a, drmDevicePtr b); -+ -+extern int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle); -+extern int drmSyncobjDestroy(int fd, uint32_t handle); -+extern int drmSyncobjHandleToFD(int fd, uint32_t handle, int *obj_fd); -+extern int drmSyncobjFDToHandle(int fd, int obj_fd, uint32_t *handle); -+ -+extern int drmSyncobjImportSyncFile(int fd, uint32_t handle, int sync_file_fd); -+extern int drmSyncobjExportSyncFile(int fd, uint32_t handle, int *sync_file_fd); -+extern int drmSyncobjWait(int fd, uint32_t *handles, unsigned num_handles, -+ int64_t timeout_nsec, unsigned flags, -+ uint32_t *first_signaled); -+extern int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t handle_count); -+extern int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t handle_count); -+extern int drmSyncobjTimelineSignal(int fd, const uint32_t *handles, -+ uint64_t *points, uint32_t handle_count); -+extern int drmSyncobjTimelineWait(int fd, uint32_t *handles, uint64_t *points, -+ unsigned num_handles, -+ int64_t timeout_nsec, unsigned flags, -+ uint32_t *first_signaled); -+extern int drmSyncobjQuery(int fd, uint32_t *handles, uint64_t *points, -+ uint32_t handle_count); -+extern int drmSyncobjQuery2(int fd, uint32_t *handles, uint64_t *points, -+ uint32_t handle_count, uint32_t flags); -+extern int drmSyncobjTransfer(int fd, -+ uint32_t dst_handle, uint64_t dst_point, -+ uint32_t src_handle, uint64_t src_point, -+ uint32_t flags); -+ -+extern char * -+drmGetFormatModifierVendor(uint64_t modifier); -+ -+extern char * -+drmGetFormatModifierName(uint64_t modifier); -+ -+#ifndef fourcc_mod_get_vendor -+#define fourcc_mod_get_vendor(modifier) \ -+ (((modifier) >> 56) & 0xff) -+#endif -+ -+#if defined(__cplusplus) -+} -+#endif -+ -+#endif -diff --git a/third_party/drm/libdrm/moz.build b/third_party/drm/libdrm/moz.build -new file mode 100644 -index 0000000..3b37b91 ---- /dev/null -+++ b/third_party/drm/libdrm/moz.build -@@ -0,0 +1,16 @@ -+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -+# vim: set filetype=python: -+# This Source Code Form is subject to the terms of the Mozilla Public -+# License, v. 2.0. If a copy of the MPL was not distributed with this -+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ -+SOURCES += [ -+ 'mozdrm.cpp', -+] -+ -+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": -+ CXXFLAGS += CONFIG['MOZ_GTK3_CFLAGS'] -+ -+LOCAL_INCLUDES += ['/third_party/drm'] -+ -+FINAL_LIBRARY = 'xul' -diff --git a/third_party/drm/libdrm/mozdrm.cpp b/third_party/drm/libdrm/mozdrm.cpp -new file mode 100644 -index 0000000..b2fb59b ---- /dev/null -+++ b/third_party/drm/libdrm/mozdrm.cpp -@@ -0,0 +1,66 @@ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim:expandtab:shiftwidth=4:tabstop=4: -+ */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+#include "mozilla/Types.h" -+#include "prlink.h" -+ -+#include -+ -+#define GET_FUNC(func, lib) \ -+ func##_fn = \ -+ (decltype(func##_fn))PR_FindFunctionSymbol(lib, #func) \ -+ -+#define IS_FUNC_LOADED(func) \ -+ (func != nullptr) \ -+ -+static int (*drmGetDevices2_fn)(uint32_t flags, drmDevicePtr devices[], int max_devices); -+static void (*drmFreeDevices_fn)(drmDevicePtr devices[], int count); -+ -+bool IsDRMLibraryLoaded() { -+ static bool isLoaded = -+ (IS_FUNC_LOADED(drmGetDevices2_fn) && -+ IS_FUNC_LOADED(drmFreeDevices_fn)); -+ -+ return isLoaded; -+} -+ -+bool LoadDRMLibrary() { -+ static PRLibrary* drmLib = nullptr; -+ static bool drmInitialized = false; -+ -+ //TODO Thread safe -+ if (!drmInitialized) { -+ drmInitialized = true; -+ drmLib = PR_LoadLibrary("libdrm.so.2"); -+ if (!drmLib) { -+ return false; -+ } -+ -+ GET_FUNC(drmGetDevices2, drmLib); -+ GET_FUNC(drmFreeDevices, drmLib); -+ } -+ -+ return IsDRMLibraryLoaded(); -+} -+ -+int -+drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) -+{ -+ if (!LoadDRMLibrary()) { -+ return 0; -+ } -+ return drmGetDevices2_fn(flags, devices, max_devices); -+} -+ -+void -+drmFreeDevices(drmDevicePtr devices[], int count) -+{ -+ if (!LoadDRMLibrary()) { -+ return; -+ } -+ return drmFreeDevices_fn(devices, count); -+} -diff --git a/third_party/gbm/README b/third_party/gbm/README -new file mode 100644 -index 0000000..4b6e2e8 ---- /dev/null -+++ b/third_party/gbm/README -@@ -0,0 +1,4 @@ -+Libgbm is a gbm library wrapper needed to build and run Firefox with -+Pipewire support on Linux (https://gitlab.freedesktop.org/mesa/gbm). -+ -+libgbm directory stores headers of libgbm needed for build only. -diff --git a/third_party/gbm/gbm/gbm.h b/third_party/gbm/gbm/gbm.h -new file mode 100644 -index 0000000..a963ed7 ---- /dev/null -+++ b/third_party/gbm/gbm/gbm.h -@@ -0,0 +1,452 @@ -+/* -+ * Copyright © 2011 Intel Corporation -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -+ * DEALINGS IN THE SOFTWARE. -+ * -+ * Authors: -+ * Benjamin Franzke -+ */ -+ -+#ifndef _GBM_H_ -+#define _GBM_H_ -+ -+#define __GBM__ 1 -+ -+#include -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+ -+/** -+ * \file gbm.h -+ * \brief Generic Buffer Manager -+ */ -+ -+struct gbm_device; -+struct gbm_bo; -+struct gbm_surface; -+ -+/** -+ * \mainpage The Generic Buffer Manager -+ * -+ * This module provides an abstraction that the caller can use to request a -+ * buffer from the underlying memory management system for the platform. -+ * -+ * This allows the creation of portable code whilst still allowing access to -+ * the underlying memory manager. -+ */ -+ -+/** -+ * Abstraction representing the handle to a buffer allocated by the -+ * manager -+ */ -+union gbm_bo_handle { -+ void *ptr; -+ int32_t s32; -+ uint32_t u32; -+ int64_t s64; -+ uint64_t u64; -+}; -+ -+/** Format of the allocated buffer */ -+enum gbm_bo_format { -+ /** RGB with 8 bits per channel in a 32 bit value */ -+ GBM_BO_FORMAT_XRGB8888, -+ /** ARGB with 8 bits per channel in a 32 bit value */ -+ GBM_BO_FORMAT_ARGB8888 -+}; -+ -+ -+/** -+ * The FourCC format codes are taken from the drm_fourcc.h definition, and -+ * re-namespaced. New GBM formats must not be added, unless they are -+ * identical ports from drm_fourcc. -+ */ -+#define __gbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ -+ ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) -+ -+#define GBM_FORMAT_BIG_ENDIAN (1<<31) /* format is big endian instead of little endian */ -+ -+/* color index */ -+#define GBM_FORMAT_C8 __gbm_fourcc_code('C', '8', ' ', ' ') /* [7:0] C */ -+ -+/* 8 bpp Red */ -+#define GBM_FORMAT_R8 __gbm_fourcc_code('R', '8', ' ', ' ') /* [7:0] R */ -+ -+/* 16 bpp Red */ -+#define GBM_FORMAT_R16 __gbm_fourcc_code('R', '1', '6', ' ') /* [15:0] R little endian */ -+ -+/* 16 bpp RG */ -+#define GBM_FORMAT_GR88 __gbm_fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */ -+ -+/* 8 bpp RGB */ -+#define GBM_FORMAT_RGB332 __gbm_fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */ -+#define GBM_FORMAT_BGR233 __gbm_fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */ -+ -+/* 16 bpp RGB */ -+#define GBM_FORMAT_XRGB4444 __gbm_fourcc_code('X', 'R', '1', '2') /* [15:0] x:R:G:B 4:4:4:4 little endian */ -+#define GBM_FORMAT_XBGR4444 __gbm_fourcc_code('X', 'B', '1', '2') /* [15:0] x:B:G:R 4:4:4:4 little endian */ -+#define GBM_FORMAT_RGBX4444 __gbm_fourcc_code('R', 'X', '1', '2') /* [15:0] R:G:B:x 4:4:4:4 little endian */ -+#define GBM_FORMAT_BGRX4444 __gbm_fourcc_code('B', 'X', '1', '2') /* [15:0] B:G:R:x 4:4:4:4 little endian */ -+ -+#define GBM_FORMAT_ARGB4444 __gbm_fourcc_code('A', 'R', '1', '2') /* [15:0] A:R:G:B 4:4:4:4 little endian */ -+#define GBM_FORMAT_ABGR4444 __gbm_fourcc_code('A', 'B', '1', '2') /* [15:0] A:B:G:R 4:4:4:4 little endian */ -+#define GBM_FORMAT_RGBA4444 __gbm_fourcc_code('R', 'A', '1', '2') /* [15:0] R:G:B:A 4:4:4:4 little endian */ -+#define GBM_FORMAT_BGRA4444 __gbm_fourcc_code('B', 'A', '1', '2') /* [15:0] B:G:R:A 4:4:4:4 little endian */ -+ -+#define GBM_FORMAT_XRGB1555 __gbm_fourcc_code('X', 'R', '1', '5') /* [15:0] x:R:G:B 1:5:5:5 little endian */ -+#define GBM_FORMAT_XBGR1555 __gbm_fourcc_code('X', 'B', '1', '5') /* [15:0] x:B:G:R 1:5:5:5 little endian */ -+#define GBM_FORMAT_RGBX5551 __gbm_fourcc_code('R', 'X', '1', '5') /* [15:0] R:G:B:x 5:5:5:1 little endian */ -+#define GBM_FORMAT_BGRX5551 __gbm_fourcc_code('B', 'X', '1', '5') /* [15:0] B:G:R:x 5:5:5:1 little endian */ -+ -+#define GBM_FORMAT_ARGB1555 __gbm_fourcc_code('A', 'R', '1', '5') /* [15:0] A:R:G:B 1:5:5:5 little endian */ -+#define GBM_FORMAT_ABGR1555 __gbm_fourcc_code('A', 'B', '1', '5') /* [15:0] A:B:G:R 1:5:5:5 little endian */ -+#define GBM_FORMAT_RGBA5551 __gbm_fourcc_code('R', 'A', '1', '5') /* [15:0] R:G:B:A 5:5:5:1 little endian */ -+#define GBM_FORMAT_BGRA5551 __gbm_fourcc_code('B', 'A', '1', '5') /* [15:0] B:G:R:A 5:5:5:1 little endian */ -+ -+#define GBM_FORMAT_RGB565 __gbm_fourcc_code('R', 'G', '1', '6') /* [15:0] R:G:B 5:6:5 little endian */ -+#define GBM_FORMAT_BGR565 __gbm_fourcc_code('B', 'G', '1', '6') /* [15:0] B:G:R 5:6:5 little endian */ -+ -+/* 24 bpp RGB */ -+#define GBM_FORMAT_RGB888 __gbm_fourcc_code('R', 'G', '2', '4') /* [23:0] R:G:B little endian */ -+#define GBM_FORMAT_BGR888 __gbm_fourcc_code('B', 'G', '2', '4') /* [23:0] B:G:R little endian */ -+ -+/* 32 bpp RGB */ -+#define GBM_FORMAT_XRGB8888 __gbm_fourcc_code('X', 'R', '2', '4') /* [31:0] x:R:G:B 8:8:8:8 little endian */ -+#define GBM_FORMAT_XBGR8888 __gbm_fourcc_code('X', 'B', '2', '4') /* [31:0] x:B:G:R 8:8:8:8 little endian */ -+#define GBM_FORMAT_RGBX8888 __gbm_fourcc_code('R', 'X', '2', '4') /* [31:0] R:G:B:x 8:8:8:8 little endian */ -+#define GBM_FORMAT_BGRX8888 __gbm_fourcc_code('B', 'X', '2', '4') /* [31:0] B:G:R:x 8:8:8:8 little endian */ -+ -+#define GBM_FORMAT_ARGB8888 __gbm_fourcc_code('A', 'R', '2', '4') /* [31:0] A:R:G:B 8:8:8:8 little endian */ -+#define GBM_FORMAT_ABGR8888 __gbm_fourcc_code('A', 'B', '2', '4') /* [31:0] A:B:G:R 8:8:8:8 little endian */ -+#define GBM_FORMAT_RGBA8888 __gbm_fourcc_code('R', 'A', '2', '4') /* [31:0] R:G:B:A 8:8:8:8 little endian */ -+#define GBM_FORMAT_BGRA8888 __gbm_fourcc_code('B', 'A', '2', '4') /* [31:0] B:G:R:A 8:8:8:8 little endian */ -+ -+#define GBM_FORMAT_XRGB2101010 __gbm_fourcc_code('X', 'R', '3', '0') /* [31:0] x:R:G:B 2:10:10:10 little endian */ -+#define GBM_FORMAT_XBGR2101010 __gbm_fourcc_code('X', 'B', '3', '0') /* [31:0] x:B:G:R 2:10:10:10 little endian */ -+#define GBM_FORMAT_RGBX1010102 __gbm_fourcc_code('R', 'X', '3', '0') /* [31:0] R:G:B:x 10:10:10:2 little endian */ -+#define GBM_FORMAT_BGRX1010102 __gbm_fourcc_code('B', 'X', '3', '0') /* [31:0] B:G:R:x 10:10:10:2 little endian */ -+ -+#define GBM_FORMAT_ARGB2101010 __gbm_fourcc_code('A', 'R', '3', '0') /* [31:0] A:R:G:B 2:10:10:10 little endian */ -+#define GBM_FORMAT_ABGR2101010 __gbm_fourcc_code('A', 'B', '3', '0') /* [31:0] A:B:G:R 2:10:10:10 little endian */ -+#define GBM_FORMAT_RGBA1010102 __gbm_fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */ -+#define GBM_FORMAT_BGRA1010102 __gbm_fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */ -+ -+/* -+ * Floating point 64bpp RGB -+ * IEEE 754-2008 binary16 half-precision float -+ * [15:0] sign:exponent:mantissa 1:5:10 -+ */ -+#define GBM_FORMAT_XBGR16161616F __gbm_fourcc_code('X', 'B', '4', 'H') /* [63:0] x:B:G:R 16:16:16:16 little endian */ -+ -+#define GBM_FORMAT_ABGR16161616F __gbm_fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */ -+ -+/* packed YCbCr */ -+#define GBM_FORMAT_YUYV __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ -+#define GBM_FORMAT_YVYU __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ -+#define GBM_FORMAT_UYVY __gbm_fourcc_code('U', 'Y', 'V', 'Y') /* [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian */ -+#define GBM_FORMAT_VYUY __gbm_fourcc_code('V', 'Y', 'U', 'Y') /* [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian */ -+ -+#define GBM_FORMAT_AYUV __gbm_fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */ -+ -+/* -+ * 2 plane YCbCr -+ * index 0 = Y plane, [7:0] Y -+ * index 1 = Cr:Cb plane, [15:0] Cr:Cb little endian -+ * or -+ * index 1 = Cb:Cr plane, [15:0] Cb:Cr little endian -+ */ -+#define GBM_FORMAT_NV12 __gbm_fourcc_code('N', 'V', '1', '2') /* 2x2 subsampled Cr:Cb plane */ -+#define GBM_FORMAT_NV21 __gbm_fourcc_code('N', 'V', '2', '1') /* 2x2 subsampled Cb:Cr plane */ -+#define GBM_FORMAT_NV16 __gbm_fourcc_code('N', 'V', '1', '6') /* 2x1 subsampled Cr:Cb plane */ -+#define GBM_FORMAT_NV61 __gbm_fourcc_code('N', 'V', '6', '1') /* 2x1 subsampled Cb:Cr plane */ -+ -+/* -+ * 3 plane YCbCr -+ * index 0: Y plane, [7:0] Y -+ * index 1: Cb plane, [7:0] Cb -+ * index 2: Cr plane, [7:0] Cr -+ * or -+ * index 1: Cr plane, [7:0] Cr -+ * index 2: Cb plane, [7:0] Cb -+ */ -+#define GBM_FORMAT_YUV410 __gbm_fourcc_code('Y', 'U', 'V', '9') /* 4x4 subsampled Cb (1) and Cr (2) planes */ -+#define GBM_FORMAT_YVU410 __gbm_fourcc_code('Y', 'V', 'U', '9') /* 4x4 subsampled Cr (1) and Cb (2) planes */ -+#define GBM_FORMAT_YUV411 __gbm_fourcc_code('Y', 'U', '1', '1') /* 4x1 subsampled Cb (1) and Cr (2) planes */ -+#define GBM_FORMAT_YVU411 __gbm_fourcc_code('Y', 'V', '1', '1') /* 4x1 subsampled Cr (1) and Cb (2) planes */ -+#define GBM_FORMAT_YUV420 __gbm_fourcc_code('Y', 'U', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes */ -+#define GBM_FORMAT_YVU420 __gbm_fourcc_code('Y', 'V', '1', '2') /* 2x2 subsampled Cr (1) and Cb (2) planes */ -+#define GBM_FORMAT_YUV422 __gbm_fourcc_code('Y', 'U', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes */ -+#define GBM_FORMAT_YVU422 __gbm_fourcc_code('Y', 'V', '1', '6') /* 2x1 subsampled Cr (1) and Cb (2) planes */ -+#define GBM_FORMAT_YUV444 __gbm_fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ -+#define GBM_FORMAT_YVU444 __gbm_fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ -+ -+struct gbm_format_name_desc { -+ char name[5]; -+}; -+ -+/** -+ * Flags to indicate the intended use for the buffer - these are passed into -+ * gbm_bo_create(). The caller must set the union of all the flags that are -+ * appropriate -+ * -+ * \sa Use gbm_device_is_format_supported() to check if the combination of format -+ * and use flags are supported -+ */ -+enum gbm_bo_flags { -+ /** -+ * Buffer is going to be presented to the screen using an API such as KMS -+ */ -+ GBM_BO_USE_SCANOUT = (1 << 0), -+ /** -+ * Buffer is going to be used as cursor -+ */ -+ GBM_BO_USE_CURSOR = (1 << 1), -+ /** -+ * Deprecated -+ */ -+ GBM_BO_USE_CURSOR_64X64 = GBM_BO_USE_CURSOR, -+ /** -+ * Buffer is to be used for rendering - for example it is going to be used -+ * as the storage for a color buffer -+ */ -+ GBM_BO_USE_RENDERING = (1 << 2), -+ /** -+ * Buffer can be used for gbm_bo_write. This is guaranteed to work -+ * with GBM_BO_USE_CURSOR, but may not work for other combinations. -+ */ -+ GBM_BO_USE_WRITE = (1 << 3), -+ /** -+ * Buffer is linear, i.e. not tiled. -+ */ -+ GBM_BO_USE_LINEAR = (1 << 4), -+ /** -+ * Buffer is protected, i.e. encrypted and not readable by CPU or any -+ * other non-secure / non-trusted components nor by non-trusted OpenGL, -+ * OpenCL, and Vulkan applications. -+ */ -+ GBM_BO_USE_PROTECTED = (1 << 5), -+}; -+ -+int -+gbm_device_get_fd(struct gbm_device *gbm); -+ -+const char * -+gbm_device_get_backend_name(struct gbm_device *gbm); -+ -+int -+gbm_device_is_format_supported(struct gbm_device *gbm, -+ uint32_t format, uint32_t flags); -+ -+int -+gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm, -+ uint32_t format, -+ uint64_t modifier); -+ -+void -+gbm_device_destroy(struct gbm_device *gbm); -+ -+struct gbm_device * -+gbm_create_device(int fd); -+ -+struct gbm_bo * -+gbm_bo_create(struct gbm_device *gbm, -+ uint32_t width, uint32_t height, -+ uint32_t format, uint32_t flags); -+ -+struct gbm_bo * -+gbm_bo_create_with_modifiers(struct gbm_device *gbm, -+ uint32_t width, uint32_t height, -+ uint32_t format, -+ const uint64_t *modifiers, -+ const unsigned int count); -+ -+struct gbm_bo * -+gbm_bo_create_with_modifiers2(struct gbm_device *gbm, -+ uint32_t width, uint32_t height, -+ uint32_t format, -+ const uint64_t *modifiers, -+ const unsigned int count, -+ uint32_t flags); -+ -+#define GBM_BO_IMPORT_WL_BUFFER 0x5501 -+#define GBM_BO_IMPORT_EGL_IMAGE 0x5502 -+#define GBM_BO_IMPORT_FD 0x5503 -+#define GBM_BO_IMPORT_FD_MODIFIER 0x5504 -+ -+struct gbm_import_fd_data { -+ int fd; -+ uint32_t width; -+ uint32_t height; -+ uint32_t stride; -+ uint32_t format; -+}; -+ -+#define GBM_MAX_PLANES 4 -+ -+struct gbm_import_fd_modifier_data { -+ uint32_t width; -+ uint32_t height; -+ uint32_t format; -+ uint32_t num_fds; -+ int fds[GBM_MAX_PLANES]; -+ int strides[GBM_MAX_PLANES]; -+ int offsets[GBM_MAX_PLANES]; -+ uint64_t modifier; -+}; -+ -+struct gbm_bo * -+gbm_bo_import(struct gbm_device *gbm, uint32_t type, -+ void *buffer, uint32_t flags); -+ -+/** -+ * Flags to indicate the type of mapping for the buffer - these are -+ * passed into gbm_bo_map(). The caller must set the union of all the -+ * flags that are appropriate. -+ * -+ * These flags are independent of the GBM_BO_USE_* creation flags. However, -+ * mapping the buffer may require copying to/from a staging buffer. -+ * -+ * See also: pipe_map_flags -+ */ -+enum gbm_bo_transfer_flags { -+ /** -+ * Buffer contents read back (or accessed directly) at transfer -+ * create time. -+ */ -+ GBM_BO_TRANSFER_READ = (1 << 0), -+ /** -+ * Buffer contents will be written back at unmap time -+ * (or modified as a result of being accessed directly). -+ */ -+ GBM_BO_TRANSFER_WRITE = (1 << 1), -+ /** -+ * Read/modify/write -+ */ -+ GBM_BO_TRANSFER_READ_WRITE = (GBM_BO_TRANSFER_READ | GBM_BO_TRANSFER_WRITE), -+}; -+ -+void * -+gbm_bo_map(struct gbm_bo *bo, -+ uint32_t x, uint32_t y, uint32_t width, uint32_t height, -+ uint32_t flags, uint32_t *stride, void **map_data); -+ -+void -+gbm_bo_unmap(struct gbm_bo *bo, void *map_data); -+ -+uint32_t -+gbm_bo_get_width(struct gbm_bo *bo); -+ -+uint32_t -+gbm_bo_get_height(struct gbm_bo *bo); -+ -+uint32_t -+gbm_bo_get_stride(struct gbm_bo *bo); -+ -+uint32_t -+gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane); -+ -+uint32_t -+gbm_bo_get_format(struct gbm_bo *bo); -+ -+uint32_t -+gbm_bo_get_bpp(struct gbm_bo *bo); -+ -+uint32_t -+gbm_bo_get_offset(struct gbm_bo *bo, int plane); -+ -+struct gbm_device * -+gbm_bo_get_device(struct gbm_bo *bo); -+ -+union gbm_bo_handle -+gbm_bo_get_handle(struct gbm_bo *bo); -+ -+int -+gbm_bo_get_fd(struct gbm_bo *bo); -+ -+uint64_t -+gbm_bo_get_modifier(struct gbm_bo *bo); -+ -+int -+gbm_bo_get_plane_count(struct gbm_bo *bo); -+ -+union gbm_bo_handle -+gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane); -+ -+int -+gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane); -+ -+int -+gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count); -+ -+void -+gbm_bo_set_user_data(struct gbm_bo *bo, void *data, -+ void (*destroy_user_data)(struct gbm_bo *, void *)); -+ -+void * -+gbm_bo_get_user_data(struct gbm_bo *bo); -+ -+void -+gbm_bo_destroy(struct gbm_bo *bo); -+ -+struct gbm_surface * -+gbm_surface_create(struct gbm_device *gbm, -+ uint32_t width, uint32_t height, -+ uint32_t format, uint32_t flags); -+ -+struct gbm_surface * -+gbm_surface_create_with_modifiers(struct gbm_device *gbm, -+ uint32_t width, uint32_t height, -+ uint32_t format, -+ const uint64_t *modifiers, -+ const unsigned int count); -+ -+struct gbm_surface * -+gbm_surface_create_with_modifiers2(struct gbm_device *gbm, -+ uint32_t width, uint32_t height, -+ uint32_t format, -+ const uint64_t *modifiers, -+ const unsigned int count, -+ uint32_t flags); -+ -+struct gbm_bo * -+gbm_surface_lock_front_buffer(struct gbm_surface *surface); -+ -+void -+gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo); -+ -+int -+gbm_surface_has_free_buffers(struct gbm_surface *surface); -+ -+void -+gbm_surface_destroy(struct gbm_surface *surface); -+ -+char * -+gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/third_party/gbm/libgbm/moz.build b/third_party/gbm/libgbm/moz.build -new file mode 100644 -index 0000000..0953d2f ---- /dev/null -+++ b/third_party/gbm/libgbm/moz.build -@@ -0,0 +1,16 @@ -+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -+# vim: set filetype=python: -+# This Source Code Form is subject to the terms of the Mozilla Public -+# License, v. 2.0. If a copy of the MPL was not distributed with this -+# file, You can obtain one at http://mozilla.org/MPL/2.0/. -+ -+SOURCES += [ -+ 'mozgbm.cpp', -+] -+ -+if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": -+ CXXFLAGS += CONFIG['MOZ_GTK3_CFLAGS'] -+ -+LOCAL_INCLUDES += ['/third_party/gbm'] -+ -+FINAL_LIBRARY = 'xul' -diff --git a/third_party/gbm/libgbm/mozgbm.cpp b/third_party/gbm/libgbm/mozgbm.cpp -new file mode 100644 -index 0000000..bc024a1 ---- /dev/null -+++ b/third_party/gbm/libgbm/mozgbm.cpp -@@ -0,0 +1,66 @@ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim:expandtab:shiftwidth=4:tabstop=4: -+ */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+#include "mozilla/Types.h" -+#include "prlink.h" -+ -+#include -+ -+#define GET_FUNC(func, lib) \ -+ func##_fn = \ -+ (decltype(func##_fn))PR_FindFunctionSymbol(lib, #func) \ -+ -+#define IS_FUNC_LOADED(func) \ -+ (func != nullptr) \ -+ -+static struct gbm_device * (*gbm_create_device_fn)(int fd); -+static void (*gbm_device_destroy_fn)(struct gbm_device* gbm); -+ -+bool IsGBMLibraryLoaded() { -+ static bool isLoaded = -+ (IS_FUNC_LOADED(gbm_create_device_fn) && -+ IS_FUNC_LOADED(gbm_device_destroy_fn)); -+ -+ return isLoaded; -+} -+ -+bool LoadGBMLibrary() { -+ static PRLibrary* gbmLib = nullptr; -+ static bool gbmInitialized = false; -+ -+ //TODO Thread safe -+ if (!gbmInitialized) { -+ gbmInitialized = true; -+ gbmLib = PR_LoadLibrary("libgbm.so.1"); -+ if (!gbmLib) { -+ return false; -+ } -+ -+ GET_FUNC(gbm_create_device, gbmLib); -+ GET_FUNC(gbm_device_destroy, gbmLib); -+ } -+ -+ return IsGBMLibraryLoaded(); -+} -+ -+struct gbm_device * -+gbm_create_device(int fd) -+{ -+ if (!LoadGBMLibrary()) { -+ return nullptr; -+ } -+ return gbm_create_device_fn(fd); -+} -+ -+void -+gbm_device_destroy(struct gbm_device* gbm) -+{ -+ if (!LoadGBMLibrary()) { -+ return; -+ } -+ return gbm_device_destroy_fn(gbm); -+} -diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc -index c89896d..c8ef822 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc -+++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.cc -@@ -14,6 +14,9 @@ - #elif defined(WEBRTC_WIN) - #include "modules/desktop_capture/win/full_screen_win_application_handler.h" - #endif -+#if defined(WEBRTC_USE_PIPEWIRE) -+#include "modules/desktop_capture/linux/shared_screencast_stream.h" -+#endif - - namespace webrtc { - -@@ -35,6 +38,9 @@ DesktopCaptureOptions DesktopCaptureOptions::CreateDefault() { - #if defined(WEBRTC_USE_X11) - result.set_x_display(SharedXDisplay::CreateDefault()); - #endif -+#if defined(WEBRTC_USE_PIPEWIRE) -+ result.set_screencast_stream(SharedScreenCastStream::CreateDefault()); -+#endif - #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - result.set_configuration_monitor(new DesktopConfigurationMonitor()); - result.set_full_screen_window_detector( -diff --git a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h -index ee0dd3a..ac56c8c 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h -+++ b/third_party/libwebrtc/modules/desktop_capture/desktop_capture_options.h -@@ -17,6 +17,10 @@ - #include "modules/desktop_capture/linux/shared_x_display.h" - #endif - -+#if defined(WEBRTC_USE_PIPEWIRE) -+#include "modules/desktop_capture/linux/shared_screencast_stream.h" -+#endif -+ - #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - #include "modules/desktop_capture/mac/desktop_configuration_monitor.h" - #endif -@@ -149,13 +153,26 @@ class RTC_EXPORT DesktopCaptureOptions { - #if defined(WEBRTC_USE_PIPEWIRE) - bool allow_pipewire() const { return allow_pipewire_; } - void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; } -+ -+ const rtc::scoped_refptr& screencast_stream() const { -+ return screencast_stream_; -+ } -+ void set_screencast_stream( -+ rtc::scoped_refptr stream) { -+ screencast_stream_ = stream; -+ } - #endif - - private: - #if defined(WEBRTC_USE_X11) - rtc::scoped_refptr x_display_; - #endif -- -+#if defined(WEBRTC_USE_PIPEWIRE) -+ // An instance of shared PipeWire ScreenCast stream we share between -+ // BaseCapturerPipeWire and MouseCursorMonitorPipeWire as cursor information -+ // is sent together with screen content. -+ rtc::scoped_refptr screencast_stream_; -+#endif - #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - rtc::scoped_refptr configuration_monitor_; - bool allow_iosurface_ = false; -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc b/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc -index 2fd3b1a..e4685fc 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc -@@ -10,937 +10,67 @@ - - #include "modules/desktop_capture/linux/base_capturer_pipewire.h" - --#include --#include --#include --#include -- --#include --#include --#include -- --#include --#include --#include -- --#include "absl/memory/memory.h" - #include "modules/desktop_capture/desktop_capture_options.h" - #include "modules/desktop_capture/desktop_capturer.h" - #include "rtc_base/checks.h" - #include "rtc_base/logging.h" - --#if defined(WEBRTC_DLOPEN_PIPEWIRE) --#include "modules/desktop_capture/linux/pipewire_stubs.h" -- --using modules_desktop_capture_linux::InitializeStubs; --using modules_desktop_capture_linux::kModulePipewire; --using modules_desktop_capture_linux::StubPathMap; --#endif // defined(WEBRTC_DLOPEN_PIPEWIRE) -- - namespace webrtc { - --const char kDesktopBusName[] = "org.freedesktop.portal.Desktop"; --const char kDesktopObjectPath[] = "/org/freedesktop/portal/desktop"; --const char kDesktopRequestObjectPath[] = -- "/org/freedesktop/portal/desktop/request"; --const char kSessionInterfaceName[] = "org.freedesktop.portal.Session"; --const char kRequestInterfaceName[] = "org.freedesktop.portal.Request"; --const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast"; -- --const int kBytesPerPixel = 4; -- --#if defined(WEBRTC_DLOPEN_PIPEWIRE) --const char kPipeWireLib[] = "libpipewire-0.2.so.1"; --#endif -- --// static --struct dma_buf_sync { -- uint64_t flags; --}; --#define DMA_BUF_SYNC_READ (1 << 0) --#define DMA_BUF_SYNC_START (0 << 2) --#define DMA_BUF_SYNC_END (1 << 2) --#define DMA_BUF_BASE 'b' --#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) -- --static void SyncDmaBuf(int fd, uint64_t start_or_end) { -- struct dma_buf_sync sync = { 0 }; -- -- sync.flags = start_or_end | DMA_BUF_SYNC_READ; -- -- while(true) { -- int ret; -- ret = ioctl (fd, DMA_BUF_IOCTL_SYNC, &sync); -- if (ret == -1 && errno == EINTR) { -- continue; -- } else if (ret == -1) { -- RTC_LOG(LS_ERROR) << "Failed to synchronize DMA buffer: " << g_strerror(errno); -- break; -- } else { -- break; -- } -- } --} -- --// static --void BaseCapturerPipeWire::OnCoreError(void *data, -- uint32_t id, -- int seq, -- int res, -- const char *message) { -- RTC_LOG(LS_ERROR) << "core error: " << message; --} -- --// static --void BaseCapturerPipeWire::OnStreamStateChanged(void* data, -- pw_stream_state old_state, -- pw_stream_state state, -- const char* error_message) { -- BaseCapturerPipeWire* that = static_cast(data); -- RTC_DCHECK(that); -- -- switch (state) { -- case PW_STREAM_STATE_ERROR: -- RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message; -- break; -- case PW_STREAM_STATE_PAUSED: -- case PW_STREAM_STATE_STREAMING: -- case PW_STREAM_STATE_UNCONNECTED: -- case PW_STREAM_STATE_CONNECTING: -- break; -- } -+BaseCapturerPipeWire::BaseCapturerPipeWire(const DesktopCaptureOptions& options) -+ : options_(options) { -+ screencast_portal_ = std::make_unique( -+ ScreenCastPortal::CaptureSourceType::kAnyScreenContent, this); - } - --// static --void BaseCapturerPipeWire::OnStreamParamChanged(void *data, uint32_t id, -- const struct spa_pod *format) { -- BaseCapturerPipeWire* that = static_cast(data); -- RTC_DCHECK(that); -- -- RTC_LOG(LS_INFO) << "PipeWire stream param changed."; -- -- if (!format || id != SPA_PARAM_Format) { -- return; -- } -- -- spa_format_video_raw_parse(format, &that->spa_video_format_); -- -- auto width = that->spa_video_format_.size.width; -- auto height = that->spa_video_format_.size.height; -- // In order to be able to build in the non unified environment kBytesPerPixel -- // must be fully qualified, see Bug 1725145 -- auto stride = SPA_ROUND_UP_N(width * BasicDesktopFrame::kBytesPerPixel, 4); -- auto size = height * stride; -- -- that->desktop_size_ = DesktopSize(width, height); -- -- uint8_t buffer[1024] = {}; -- auto builder = spa_pod_builder{buffer, sizeof(buffer)}; -- -- // Setup buffers and meta header for new format. -- const struct spa_pod* params[3]; -- params[0] = reinterpret_cast(spa_pod_builder_add_object(&builder, -- SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, -- SPA_PARAM_BUFFERS_dataType, SPA_POD_CHOICE_FLAGS_Int((1<(spa_pod_builder_add_object(&builder, -- SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, -- SPA_PARAM_META_type, SPA_POD_Id(SPA_META_Header), -- SPA_PARAM_META_size, SPA_POD_Int(sizeof(struct spa_meta_header)))); -- params[2] = reinterpret_cast(spa_pod_builder_add_object(&builder, -- SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, -- SPA_PARAM_META_type, SPA_POD_Id (SPA_META_VideoCrop), -- SPA_PARAM_META_size, SPA_POD_Int (sizeof(struct spa_meta_region)))); -- pw_stream_update_params(that->pw_stream_, params, 3); --} -- --// static --void BaseCapturerPipeWire::OnStreamProcess(void* data) { -- BaseCapturerPipeWire* that = static_cast(data); -- RTC_DCHECK(that); -- -- struct pw_buffer *next_buffer; -- struct pw_buffer *buffer = nullptr; -+BaseCapturerPipeWire::~BaseCapturerPipeWire() {} - -- next_buffer = pw_stream_dequeue_buffer(that->pw_stream_); -- while (next_buffer) { -- buffer = next_buffer; -- next_buffer = pw_stream_dequeue_buffer(that->pw_stream_); -- -- if (next_buffer) { -- pw_stream_queue_buffer (that->pw_stream_, buffer); -- } -- } -- -- if (!buffer) { -- return; -+void BaseCapturerPipeWire::OnScreenCastRequestResult( -+ ScreenCastPortal::RequestResponse result, -+ uint32_t stream_node_id, -+ int fd) { -+ if (result != ScreenCastPortal::RequestResponse::kSuccess || -+ !options_.screencast_stream()->StartScreenCastStream(stream_node_id, -+ fd)) { -+ capturer_failed_ = true; -+ RTC_LOG(LS_ERROR) << "ScreenCastPortal failed: " -+ << static_cast(result); - } -- -- that->HandleBuffer(buffer); -- -- pw_stream_queue_buffer(that->pw_stream_, buffer); - } - --BaseCapturerPipeWire::BaseCapturerPipeWire(CaptureSourceType source_type) -- : capture_source_type_(source_type) {} -- --BaseCapturerPipeWire::~BaseCapturerPipeWire() { -- if (pw_main_loop_) { -- pw_thread_loop_stop(pw_main_loop_); -- } -- -- if (pw_stream_) { -- pw_stream_destroy(pw_stream_); -- } -- -- if (pw_core_) { -- pw_core_disconnect(pw_core_); -- } -- -- if (pw_context_) { -- pw_context_destroy(pw_context_); -- } -- -- if (pw_main_loop_) { -- pw_thread_loop_destroy(pw_main_loop_); -+void BaseCapturerPipeWire::OnScreenCastSessionClosed() { -+ if (!capturer_failed_) { -+ options_.screencast_stream()->StopScreenCastStream(); - } -- -- if (start_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_); -- } -- if (sources_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(connection_, -- sources_request_signal_id_); -- } -- if (session_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(connection_, -- session_request_signal_id_); -- } -- -- if (session_handle_) { -- GDBusMessage* message = g_dbus_message_new_method_call( -- kDesktopBusName, session_handle_, kSessionInterfaceName, "Close"); -- if (message) { -- GError* error = nullptr; -- g_dbus_connection_send_message(connection_, message, -- G_DBUS_SEND_MESSAGE_FLAGS_NONE, -- /*out_serial=*/nullptr, &error); -- if (error) { -- RTC_LOG(LS_ERROR) << "Failed to close the session: " << error->message; -- g_error_free(error); -- } -- g_object_unref(message); -- } -- } -- -- g_free(start_handle_); -- g_free(sources_handle_); -- g_free(session_handle_); -- g_free(portal_handle_); -- -- if (cancellable_) { -- g_cancellable_cancel(cancellable_); -- g_object_unref(cancellable_); -- cancellable_ = nullptr; -- } -- -- if (proxy_) { -- g_object_unref(proxy_); -- proxy_ = nullptr; -- } -- -- if (pw_fd_ != -1) { -- close(pw_fd_); -- } --} -- --void BaseCapturerPipeWire::InitPortal() { -- cancellable_ = g_cancellable_new(); -- g_dbus_proxy_new_for_bus( -- G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, /*info=*/nullptr, -- kDesktopBusName, kDesktopObjectPath, kScreenCastInterfaceName, -- cancellable_, -- reinterpret_cast(OnProxyRequested), this); --} -- --void BaseCapturerPipeWire::InitPipeWire() { --#if defined(WEBRTC_DLOPEN_PIPEWIRE) -- StubPathMap paths; -- -- // Check if the PipeWire library is available. -- paths[kModulePipewire].push_back(kPipeWireLib); -- if (!InitializeStubs(paths)) { -- RTC_LOG(LS_ERROR) << "Failed to load the PipeWire library and symbols."; -- portal_init_failed_ = true; -- return; -- } --#endif // defined(WEBRTC_DLOPEN_PIPEWIRE) -- -- pw_init(/*argc=*/nullptr, /*argc=*/nullptr); -- -- pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr); -- pw_context_ = pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), nullptr, 0); -- if (!pw_context_) { -- RTC_LOG(LS_ERROR) << "Failed to create PipeWire context"; -- return; -- } -- -- pw_core_ = pw_context_connect_fd(pw_context_, pw_fd_, nullptr, 0); -- if (!pw_core_) { -- RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context"; -- return; -- } -- -- // Initialize event handlers, remote end and stream-related. -- pw_core_events_.version = PW_VERSION_CORE_EVENTS; -- pw_core_events_.error = &OnCoreError; -- -- pw_stream_events_.version = PW_VERSION_STREAM_EVENTS; -- pw_stream_events_.state_changed = &OnStreamStateChanged; -- pw_stream_events_.param_changed = &OnStreamParamChanged; -- pw_stream_events_.process = &OnStreamProcess; -- -- pw_core_add_listener(pw_core_, &spa_core_listener_, &pw_core_events_, this); -- -- pw_stream_ = CreateReceivingStream(); -- if (!pw_stream_) { -- RTC_LOG(LS_ERROR) << "Failed to create PipeWire stream"; -- return; -- } -- -- if (pw_thread_loop_start(pw_main_loop_) < 0) { -- RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop"; -- portal_init_failed_ = true; -- } -- -- RTC_LOG(LS_INFO) << "PipeWire remote opened."; --} -- --pw_stream* BaseCapturerPipeWire::CreateReceivingStream() { -- spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1}; -- spa_rectangle pwMaxScreenBounds = spa_rectangle{UINT32_MAX, UINT32_MAX}; -- -- auto stream = pw_stream_new(pw_core_, "webrtc-pipewire-stream", nullptr); -- -- if (!stream) { -- RTC_LOG(LS_ERROR) << "Could not create receiving stream."; -- return nullptr; -- } -- -- uint8_t buffer[1024] = {}; -- const spa_pod* params[2]; -- spa_pod_builder builder = SPA_POD_BUILDER_INIT(buffer, sizeof (buffer)); -- -- params[0] = reinterpret_cast(spa_pod_builder_add_object(&builder, -- SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat, -- SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video), -- SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), -- SPA_FORMAT_VIDEO_format, SPA_POD_CHOICE_ENUM_Id(5, SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx, SPA_VIDEO_FORMAT_RGBA, -- SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_BGRA), -- SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(&pwMinScreenBounds, -- &pwMinScreenBounds, -- &pwMaxScreenBounds), -- 0)); -- pw_stream_add_listener(stream, &spa_stream_listener_, &pw_stream_events_, this); -- -- if (pw_stream_connect(stream, PW_DIRECTION_INPUT, pw_stream_node_id_, -- PW_STREAM_FLAG_AUTOCONNECT, params, 1) != 0) { -- RTC_LOG(LS_ERROR) << "Could not connect receiving stream."; -- portal_init_failed_ = true; -- } -- -- return stream; --} -- --static void SpaBufferUnmap(unsigned char *map, int map_size, bool IsDMABuf, int fd) { -- if (map) { -- if (IsDMABuf) { -- SyncDmaBuf(fd, DMA_BUF_SYNC_END); -- } -- munmap(map, map_size); -- } --} -- --void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) { -- spa_buffer* spaBuffer = buffer->buffer; -- uint8_t *map = nullptr; -- uint8_t* src = nullptr; -- -- if (spaBuffer->datas[0].chunk->size == 0) { -- RTC_LOG(LS_ERROR) << "Failed to get video stream: Zero size."; -- return; -- } -- -- switch (spaBuffer->datas[0].type) { -- case SPA_DATA_MemFd: -- case SPA_DATA_DmaBuf: -- map = static_cast(mmap( -- nullptr, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset, -- PROT_READ, MAP_PRIVATE, spaBuffer->datas[0].fd, 0)); -- if (map == MAP_FAILED) { -- RTC_LOG(LS_ERROR) << "Failed to mmap memory: " << std::strerror(errno); -- return; -- } -- if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) { -- SyncDmaBuf(spaBuffer->datas[0].fd, DMA_BUF_SYNC_START); -- } -- src = SPA_MEMBER(map, spaBuffer->datas[0].mapoffset, uint8_t); -- break; -- case SPA_DATA_MemPtr: -- map = nullptr; -- src = static_cast(spaBuffer->datas[0].data); -- break; -- default: -- return; -- } -- -- if (!src) { -- RTC_LOG(LS_ERROR) << "Failed to get video stream: Wrong data after mmap()"; -- SpaBufferUnmap(map, -- spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset, -- spaBuffer->datas[0].type == SPA_DATA_DmaBuf, spaBuffer->datas[0].fd); -- return; -- } -- -- struct spa_meta_region* video_metadata = -- static_cast( -- spa_buffer_find_meta_data(spaBuffer, SPA_META_VideoCrop, sizeof(*video_metadata))); -- -- // Video size from metada is bigger than an actual video stream size. -- // The metadata are wrong or we should up-scale te video...in both cases -- // just quit now. -- if (video_metadata && -- (video_metadata->region.size.width > (uint32_t)desktop_size_.width() || -- video_metadata->region.size.height > (uint32_t)desktop_size_.height())) { -- RTC_LOG(LS_ERROR) << "Stream metadata sizes are wrong!"; -- SpaBufferUnmap(map, -- spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset, -- spaBuffer->datas[0].type == SPA_DATA_DmaBuf, spaBuffer->datas[0].fd); -- return; -- } -- -- // Use video metada when video size from metadata is set and smaller than -- // video stream size, so we need to adjust it. -- video_metadata_use_ = (video_metadata && -- video_metadata->region.size.width != 0 && -- video_metadata->region.size.height != 0 && -- (video_metadata->region.size.width < (uint32_t)desktop_size_.width() || -- video_metadata->region.size.height < (uint32_t)desktop_size_.height())); -- -- DesktopSize video_size_prev = video_size_; -- if (video_metadata_use_) { -- video_size_ = DesktopSize(video_metadata->region.size.width, -- video_metadata->region.size.height); -- } else { -- video_size_ = desktop_size_; -- } -- -- webrtc::MutexLock lock(¤t_frame_lock_); -- if (!current_frame_ || !video_size_.equals(video_size_prev)) { -- current_frame_ = -- std::make_unique -- (video_size_.width() * video_size_.height() * BasicDesktopFrame::kBytesPerPixel); -- } -- -- const int32_t dstStride = video_size_.width() * BasicDesktopFrame::kBytesPerPixel; -- const int32_t srcStride = spaBuffer->datas[0].chunk->stride; -- -- // Adjust source content based on metadata video position -- if (video_metadata_use_ && -- (video_metadata->region.position.y + video_size_.height() <= desktop_size_.height())) { -- src += srcStride * video_metadata->region.position.y; -- } -- const int xOffset = -- video_metadata_use_ && -- (video_metadata->region.position.x + video_size_.width() <= desktop_size_.width()) -- ? video_metadata->region.position.x * BasicDesktopFrame::kBytesPerPixel -- : 0; -- -- uint8_t* dst = current_frame_.get(); -- for (int i = 0; i < video_size_.height(); ++i) { -- // Adjust source content based on crop video position if needed -- src += xOffset; -- std::memcpy(dst, src, dstStride); -- // If both sides decided to go with the RGBx format we need to convert it to -- // BGRx to match color format expected by WebRTC. -- if (spa_video_format_.format == SPA_VIDEO_FORMAT_RGBx || -- spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) { -- ConvertRGBxToBGRx(dst, dstStride); -- } -- src += srcStride - xOffset; -- dst += dstStride; -- } -- -- SpaBufferUnmap(map, -- spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset, -- spaBuffer->datas[0].type == SPA_DATA_DmaBuf, spaBuffer->datas[0].fd); --} -- --void BaseCapturerPipeWire::ConvertRGBxToBGRx(uint8_t* frame, uint32_t size) { -- // Change color format for KDE KWin which uses RGBx and not BGRx -- for (uint32_t i = 0; i < size; i += 4) { -- uint8_t tempR = frame[i]; -- uint8_t tempB = frame[i + 2]; -- frame[i] = tempB; -- frame[i + 2] = tempR; -- } --} -- --guint BaseCapturerPipeWire::SetupRequestResponseSignal( -- const gchar* object_path, -- GDBusSignalCallback callback) { -- return g_dbus_connection_signal_subscribe( -- connection_, kDesktopBusName, kRequestInterfaceName, "Response", -- object_path, /*arg0=*/nullptr, G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, -- callback, this, /*user_data_free_func=*/nullptr); --} -- --// static --void BaseCapturerPipeWire::OnProxyRequested(GObject* /*object*/, -- GAsyncResult* result, -- gpointer user_data) { -- BaseCapturerPipeWire* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- GError* error = nullptr; -- GDBusProxy *proxy = g_dbus_proxy_new_finish(result, &error); -- if (!proxy) { -- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to create a proxy for the screen cast portal: " -- << error->message; -- g_error_free(error); -- that->portal_init_failed_ = true; -- return; -- } -- that->proxy_ = proxy; -- that->connection_ = g_dbus_proxy_get_connection(that->proxy_); -- -- RTC_LOG(LS_INFO) << "Created proxy for the screen cast portal."; -- that->SessionRequest(); --} -- --// static --gchar* BaseCapturerPipeWire::PrepareSignalHandle(GDBusConnection* connection, -- const gchar* token) { -- gchar* sender = g_strdup(g_dbus_connection_get_unique_name(connection) + 1); -- for (int i = 0; sender[i]; i++) { -- if (sender[i] == '.') { -- sender[i] = '_'; -- } -- } -- -- gchar* handle = g_strconcat(kDesktopRequestObjectPath, "/", sender, "/", -- token, /*end of varargs*/ nullptr); -- g_free(sender); -- -- return handle; --} -- --void BaseCapturerPipeWire::SessionRequest() { -- GVariantBuilder builder; -- gchar* variant_string; -- -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- variant_string = -- g_strdup_printf("webrtc_session%d", g_random_int_range(0, G_MAXINT)); -- g_variant_builder_add(&builder, "{sv}", "session_handle_token", -- g_variant_new_string(variant_string)); -- g_free(variant_string); -- variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); -- g_variant_builder_add(&builder, "{sv}", "handle_token", -- g_variant_new_string(variant_string)); -- -- portal_handle_ = PrepareSignalHandle(connection_, variant_string); -- session_request_signal_id_ = SetupRequestResponseSignal( -- portal_handle_, OnSessionRequestResponseSignal); -- g_free(variant_string); -- -- RTC_LOG(LS_INFO) << "Screen cast session requested."; -- g_dbus_proxy_call( -- proxy_, "CreateSession", g_variant_new("(a{sv})", &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, -- reinterpret_cast(OnSessionRequested), this); --} -- --// static --void BaseCapturerPipeWire::OnSessionRequested(GDBusProxy *proxy, -- GAsyncResult* result, -- gpointer user_data) { -- BaseCapturerPipeWire* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- GError* error = nullptr; -- GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error); -- if (!variant) { -- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to create a screen cast session: " -- << error->message; -- g_error_free(error); -- that->portal_init_failed_ = true; -- return; -- } -- RTC_LOG(LS_INFO) << "Initializing the screen cast session."; -- -- gchar* handle = nullptr; -- g_variant_get_child(variant, 0, "o", &handle); -- g_variant_unref(variant); -- if (!handle) { -- RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session."; -- if (that->session_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->session_request_signal_id_); -- that->session_request_signal_id_ = 0; -- } -- that->portal_init_failed_ = true; -- return; -- } -- -- g_free(handle); -- -- RTC_LOG(LS_INFO) << "Subscribing to the screen cast session."; --} -- --// static --void BaseCapturerPipeWire::OnSessionRequestResponseSignal( -- GDBusConnection* connection, -- const gchar* sender_name, -- const gchar* object_path, -- const gchar* interface_name, -- const gchar* signal_name, -- GVariant* parameters, -- gpointer user_data) { -- BaseCapturerPipeWire* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- RTC_LOG(LS_INFO) -- << "Received response for the screen cast session subscription."; -- -- guint32 portal_response; -- GVariant* response_data; -- g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data); -- -- GVariant* session_handle = -- g_variant_lookup_value(response_data, "session_handle", NULL); -- that->session_handle_ = g_variant_dup_string(session_handle, NULL); -- -- g_variant_unref(session_handle); -- g_variant_unref(response_data); -- -- if (!that->session_handle_ || portal_response) { -- RTC_LOG(LS_ERROR) -- << "Failed to request the screen cast session subscription."; -- that->portal_init_failed_ = true; -- return; -- } -- -- that->SourcesRequest(); --} -- --void BaseCapturerPipeWire::SourcesRequest() { -- GVariantBuilder builder; -- gchar* variant_string; -- -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- // We want to record monitor content. -- g_variant_builder_add(&builder, "{sv}", "types", -- g_variant_new_uint32(capture_source_type_)); -- // We don't want to allow selection of multiple sources. -- g_variant_builder_add(&builder, "{sv}", "multiple", -- g_variant_new_boolean(false)); -- variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); -- g_variant_builder_add(&builder, "{sv}", "handle_token", -- g_variant_new_string(variant_string)); -- -- sources_handle_ = PrepareSignalHandle(connection_, variant_string); -- sources_request_signal_id_ = SetupRequestResponseSignal( -- sources_handle_, OnSourcesRequestResponseSignal); -- g_free(variant_string); -- -- RTC_LOG(LS_INFO) << "Requesting sources from the screen cast session."; -- g_dbus_proxy_call( -- proxy_, "SelectSources", -- g_variant_new("(oa{sv})", session_handle_, &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, -- reinterpret_cast(OnSourcesRequested), this); --} -- --// static --void BaseCapturerPipeWire::OnSourcesRequested(GDBusProxy *proxy, -- GAsyncResult* result, -- gpointer user_data) { -- BaseCapturerPipeWire* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- GError* error = nullptr; -- GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error); -- if (!variant) { -- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to request the sources: " << error->message; -- g_error_free(error); -- that->portal_init_failed_ = true; -- return; -- } -- -- RTC_LOG(LS_INFO) << "Sources requested from the screen cast session."; -- -- gchar* handle = nullptr; -- g_variant_get_child(variant, 0, "o", &handle); -- g_variant_unref(variant); -- if (!handle) { -- RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session."; -- if (that->sources_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->sources_request_signal_id_); -- that->sources_request_signal_id_ = 0; -- } -- that->portal_init_failed_ = true; -- return; -- } -- -- g_free(handle); -- -- RTC_LOG(LS_INFO) << "Subscribed to sources signal."; --} -- --// static --void BaseCapturerPipeWire::OnSourcesRequestResponseSignal( -- GDBusConnection* connection, -- const gchar* sender_name, -- const gchar* object_path, -- const gchar* interface_name, -- const gchar* signal_name, -- GVariant* parameters, -- gpointer user_data) { -- BaseCapturerPipeWire* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- RTC_LOG(LS_INFO) << "Received sources signal from session."; -- -- guint32 portal_response; -- g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); -- if (portal_response) { -- RTC_LOG(LS_ERROR) -- << "Failed to select sources for the screen cast session."; -- that->portal_init_failed_ = true; -- return; -- } -- -- that->StartRequest(); --} -- --void BaseCapturerPipeWire::StartRequest() { -- GVariantBuilder builder; -- gchar* variant_string; -- -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); -- g_variant_builder_add(&builder, "{sv}", "handle_token", -- g_variant_new_string(variant_string)); -- -- start_handle_ = PrepareSignalHandle(connection_, variant_string); -- start_request_signal_id_ = -- SetupRequestResponseSignal(start_handle_, OnStartRequestResponseSignal); -- g_free(variant_string); -- -- // "Identifier for the application window", this is Wayland, so not "x11:...". -- const gchar parent_window[] = ""; -- -- RTC_LOG(LS_INFO) << "Starting the screen cast session."; -- g_dbus_proxy_call( -- proxy_, "Start", -- g_variant_new("(osa{sv})", session_handle_, parent_window, &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, -- reinterpret_cast(OnStartRequested), this); --} -- --// static --void BaseCapturerPipeWire::OnStartRequested(GDBusProxy *proxy, -- GAsyncResult* result, -- gpointer user_data) { -- BaseCapturerPipeWire* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- GError* error = nullptr; -- GVariant* variant = g_dbus_proxy_call_finish(proxy, result, &error); -- if (!variant) { -- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to start the screen cast session: " -- << error->message; -- g_error_free(error); -- that->portal_init_failed_ = true; -- return; -- } -- -- RTC_LOG(LS_INFO) << "Initializing the start of the screen cast session."; -- -- gchar* handle = nullptr; -- g_variant_get_child(variant, 0, "o", &handle); -- g_variant_unref(variant); -- if (!handle) { -- RTC_LOG(LS_ERROR) -- << "Failed to initialize the start of the screen cast session."; -- if (that->start_request_signal_id_) { -- g_dbus_connection_signal_unsubscribe(that->connection_, -- that->start_request_signal_id_); -- that->start_request_signal_id_ = 0; -- } -- that->portal_init_failed_ = true; -- return; -- } -- -- g_free(handle); -- -- RTC_LOG(LS_INFO) << "Subscribed to the start signal."; --} -- --// static --void BaseCapturerPipeWire::OnStartRequestResponseSignal( -- GDBusConnection* connection, -- const gchar* sender_name, -- const gchar* object_path, -- const gchar* interface_name, -- const gchar* signal_name, -- GVariant* parameters, -- gpointer user_data) { -- BaseCapturerPipeWire* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- RTC_LOG(LS_INFO) << "Start signal received."; -- guint32 portal_response; -- GVariant* response_data; -- GVariantIter* iter = nullptr; -- g_variant_get(parameters, "(u@a{sv})", &portal_response, &response_data); -- if (portal_response || !response_data) { -- RTC_LOG(LS_ERROR) << "Failed to start the screen cast session."; -- that->portal_init_failed_ = true; -- return; -- } -- -- // Array of PipeWire streams. See -- // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml -- // documentation for . -- if (g_variant_lookup(response_data, "streams", "a(ua{sv})", &iter)) { -- GVariant* variant; -- -- while (g_variant_iter_next(iter, "@(ua{sv})", &variant)) { -- guint32 stream_id; -- GVariant* options; -- -- g_variant_get(variant, "(u@a{sv})", &stream_id, &options); -- RTC_DCHECK(options != nullptr); -- -- that->pw_stream_node_id_ = stream_id; -- g_variant_unref(options); -- g_variant_unref(variant); -- } -- } -- g_variant_iter_free(iter); -- g_variant_unref(response_data); -- -- that->OpenPipeWireRemote(); --} -- --void BaseCapturerPipeWire::OpenPipeWireRemote() { -- GVariantBuilder builder; -- g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -- -- RTC_LOG(LS_INFO) << "Opening the PipeWire remote."; -- -- g_dbus_proxy_call_with_unix_fd_list( -- proxy_, "OpenPipeWireRemote", -- g_variant_new("(oa{sv})", session_handle_, &builder), -- G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, /*fd_list=*/nullptr, -- cancellable_, -- reinterpret_cast(OnOpenPipeWireRemoteRequested), -- this); --} -- --// static --void BaseCapturerPipeWire::OnOpenPipeWireRemoteRequested( -- GDBusProxy *proxy, -- GAsyncResult* result, -- gpointer user_data) { -- BaseCapturerPipeWire* that = static_cast(user_data); -- RTC_DCHECK(that); -- -- GError* error = nullptr; -- GUnixFDList* outlist = nullptr; -- GVariant* variant = g_dbus_proxy_call_with_unix_fd_list_finish( -- proxy, &outlist, result, &error); -- if (!variant) { -- if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) -- return; -- RTC_LOG(LS_ERROR) << "Failed to open the PipeWire remote: " -- << error->message; -- g_error_free(error); -- that->portal_init_failed_ = true; -- return; -- } -- -- gint32 index; -- g_variant_get(variant, "(h)", &index); -- -- if ((that->pw_fd_ = g_unix_fd_list_get(outlist, index, &error)) == -1) { -- RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " -- << error->message; -- g_error_free(error); -- g_variant_unref(variant); -- that->portal_init_failed_ = true; -- return; -- } -- -- g_variant_unref(variant); -- g_object_unref(outlist); -- -- that->InitPipeWire(); - } - - void BaseCapturerPipeWire::Start(Callback* callback) { - RTC_DCHECK(!callback_); - RTC_DCHECK(callback); - -- InitPortal(); -- - callback_ = callback; -+ -+ screencast_portal_->Start(); - } - - void BaseCapturerPipeWire::CaptureFrame() { -- if (portal_init_failed_) { -+ if (capturer_failed_) { - callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); - return; - } - -- webrtc::MutexLock lock(¤t_frame_lock_); -- if (!current_frame_) { -- callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); -- return; -- } -- -- DesktopSize frame_size = desktop_size_; -- if (video_metadata_use_) { -- frame_size = video_size_; -- } -+ std::unique_ptr frame = -+ options_.screencast_stream()->CaptureFrame(); - -- std::unique_ptr result(new BasicDesktopFrame(frame_size)); -- result->CopyPixelsFrom( -- current_frame_.get(), (frame_size.width() * BasicDesktopFrame::kBytesPerPixel), -- DesktopRect::MakeWH(frame_size.width(), frame_size.height())); -- if (!result) { -+ if (!frame || !frame->data()) { - callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); - return; - } - -- // TODO(julien.isorce): http://crbug.com/945468. Set the icc profile on the -- // frame, see ScreenCapturerX11::CaptureFrame. -+ // TODO(julien.isorce): http://crbug.com/945468. Set the icc profile on -+ // the frame, see ScreenCapturerX11::CaptureFrame. - -- callback_->OnCaptureResult(Result::SUCCESS, std::move(result)); -+ callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); - } - - // Keep in sync with defines at browser/actors/WebRTCParent.jsm -@@ -953,31 +83,13 @@ void BaseCapturerPipeWire::CaptureFrame() { - #define PIPEWIRE_NAME "####_PIPEWIRE_PORTAL_####" - - bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) { -+ RTC_DCHECK(sources->size() == 0); - sources->push_back({PIPEWIRE_ID, 0, PIPEWIRE_NAME}); - return true; - } - - bool BaseCapturerPipeWire::SelectSource(SourceId id) { -- // Screen selection is handled by the xdg-desktop-portal. - return id == PIPEWIRE_ID; - } - --// static --std::unique_ptr --BaseCapturerPipeWire::CreateRawScreenCapturer( -- const DesktopCaptureOptions& options) { -- std::unique_ptr capturer = -- std::make_unique(BaseCapturerPipeWire::CaptureSourceType::kAny); -- return std::move(capturer);} -- --// static --std::unique_ptr --BaseCapturerPipeWire::CreateRawWindowCapturer( -- const DesktopCaptureOptions& options) { -- -- std::unique_ptr capturer = -- std::make_unique(BaseCapturerPipeWire::CaptureSourceType::kAny); -- return std::move(capturer); --} -- - } // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.h b/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.h -index af8e20c..5db09e0 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.h -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.h -@@ -11,160 +11,39 @@ - #ifndef MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_ - #define MODULES_DESKTOP_CAPTURE_LINUX_BASE_CAPTURER_PIPEWIRE_H_ - --#include --#define typeof __typeof__ --#include --#include -- - #include "modules/desktop_capture/desktop_capture_options.h" - #include "modules/desktop_capture/desktop_capturer.h" --#include "rtc_base/synchronization/mutex.h" -+#include "modules/desktop_capture/linux/screencast_portal.h" -+#include "modules/desktop_capture/linux/shared_screencast_stream.h" - - namespace webrtc { - --class BaseCapturerPipeWire : public DesktopCapturer { -+class BaseCapturerPipeWire : public DesktopCapturer, -+ public ScreenCastPortal::PortalNotifier { - public: -- enum CaptureSourceType : uint32_t { -- kScreen = 0b01, -- kWindow = 0b10, -- kAny = 0b11 -- }; -- -- explicit BaseCapturerPipeWire(CaptureSourceType source_type); -+ BaseCapturerPipeWire(const DesktopCaptureOptions& options); - ~BaseCapturerPipeWire() override; - -+ BaseCapturerPipeWire(const BaseCapturerPipeWire&) = delete; -+ BaseCapturerPipeWire& operator=(const BaseCapturerPipeWire&) = delete; -+ - // DesktopCapturer interface. - void Start(Callback* delegate) override; - void CaptureFrame() override; - bool GetSourceList(SourceList* sources) override; - bool SelectSource(SourceId id) override; - -- static std::unique_ptr CreateRawScreenCapturer( -- const DesktopCaptureOptions& options); -- -- static std::unique_ptr CreateRawWindowCapturer( -- const DesktopCaptureOptions& options); -+ // ScreenCastPortal::PortalNotifier interface. -+ void OnScreenCastRequestResult(ScreenCastPortal::RequestResponse result, -+ uint32_t stream_node_id, -+ int fd) override; -+ void OnScreenCastSessionClosed() override; - - private: -- // PipeWire types --> -- pw_context* pw_context_ = nullptr; -- pw_core* pw_core_ = nullptr; -- pw_stream* pw_stream_ = nullptr; -- pw_thread_loop* pw_main_loop_ = nullptr; -- -- spa_hook spa_core_listener_ = {}; -- spa_hook spa_stream_listener_ = {}; -- -- pw_core_events pw_core_events_ = {}; -- pw_stream_events pw_stream_events_ = {}; -- -- struct spa_video_info_raw spa_video_format_; -- -- guint32 pw_stream_node_id_ = 0; -- gint32 pw_fd_ = -1; -- -- CaptureSourceType capture_source_type_ = -- BaseCapturerPipeWire::CaptureSourceType::kAny; -- -- // <-- end of PipeWire types -- -- GDBusConnection* connection_ = nullptr; -- GDBusProxy* proxy_ = nullptr; -- GCancellable *cancellable_ = nullptr; -- gchar* portal_handle_ = nullptr; -- gchar* session_handle_ = nullptr; -- gchar* sources_handle_ = nullptr; -- gchar* start_handle_ = nullptr; -- guint session_request_signal_id_ = 0; -- guint sources_request_signal_id_ = 0; -- guint start_request_signal_id_ = 0; -- -- bool video_metadata_use_ = false; -- DesktopSize video_size_; -- DesktopSize desktop_size_ = {}; - DesktopCaptureOptions options_ = {}; -- -- webrtc::Mutex current_frame_lock_; -- std::unique_ptr current_frame_; - Callback* callback_ = nullptr; -- -- bool portal_init_failed_ = false; -- -- void InitPortal(); -- void InitPipeWire(); -- -- pw_stream* CreateReceivingStream(); -- void HandleBuffer(pw_buffer* buffer); -- -- void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size); -- -- static void OnCoreError(void *data, -- uint32_t id, -- int seq, -- int res, -- const char *message); -- static void OnStreamParamChanged(void *data, -- uint32_t id, -- const struct spa_pod *format); -- static void OnStreamStateChanged(void* data, -- pw_stream_state old_state, -- pw_stream_state state, -- const char* error_message); -- static void OnStreamProcess(void* data); -- static void OnNewBuffer(void* data, uint32_t id); -- -- guint SetupRequestResponseSignal(const gchar* object_path, -- GDBusSignalCallback callback); -- -- static void OnProxyRequested(GObject* object, -- GAsyncResult* result, -- gpointer user_data); -- -- static gchar* PrepareSignalHandle(GDBusConnection* connection, -- const gchar* token); -- -- void SessionRequest(); -- static void OnSessionRequested(GDBusProxy *proxy, -- GAsyncResult* result, -- gpointer user_data); -- static void OnSessionRequestResponseSignal(GDBusConnection* connection, -- const gchar* sender_name, -- const gchar* object_path, -- const gchar* interface_name, -- const gchar* signal_name, -- GVariant* parameters, -- gpointer user_data); -- -- void SourcesRequest(); -- static void OnSourcesRequested(GDBusProxy *proxy, -- GAsyncResult* result, -- gpointer user_data); -- static void OnSourcesRequestResponseSignal(GDBusConnection* connection, -- const gchar* sender_name, -- const gchar* object_path, -- const gchar* interface_name, -- const gchar* signal_name, -- GVariant* parameters, -- gpointer user_data); -- -- void StartRequest(); -- static void OnStartRequested(GDBusProxy *proxy, -- GAsyncResult* result, -- gpointer user_data); -- static void OnStartRequestResponseSignal(GDBusConnection* connection, -- const gchar* sender_name, -- const gchar* object_path, -- const gchar* interface_name, -- const gchar* signal_name, -- GVariant* parameters, -- gpointer user_data); -- -- void OpenPipeWireRemote(); -- static void OnOpenPipeWireRemoteRequested(GDBusProxy *proxy, -- GAsyncResult* result, -- gpointer user_data); -- -- RTC_DISALLOW_COPY_AND_ASSIGN(BaseCapturerPipeWire); -+ bool capturer_failed_ = false; -+ std::unique_ptr screencast_portal_; - }; - - } // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/drm.sigs b/third_party/libwebrtc/modules/desktop_capture/linux/drm.sigs -new file mode 100644 -index 0000000..226979f ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/drm.sigs -@@ -0,0 +1,11 @@ -+// Copyright 2021 The WebRTC project authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+//------------------------------------------------ -+// Functions from DRM used in capturer code. -+//-------- -+ -+// xf86drm.h -+int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices); -+void drmFreeDevices(drmDevicePtr devices[], int count); -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/egl_dmabuf.cc b/third_party/libwebrtc/modules/desktop_capture/linux/egl_dmabuf.cc -new file mode 100644 -index 0000000..de63c2a ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/egl_dmabuf.cc -@@ -0,0 +1,695 @@ -+/* -+ * Copyright 2021 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#include "modules/desktop_capture/linux/egl_dmabuf.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "absl/memory/memory.h" -+#include "absl/types/optional.h" -+#include "rtc_base/checks.h" -+#include "rtc_base/logging.h" -+#include "rtc_base/sanitizer.h" -+#include "rtc_base/string_encode.h" -+ -+namespace webrtc { -+ -+// EGL -+typedef EGLBoolean (*eglBindAPI_func)(EGLenum api); -+typedef EGLContext (*eglCreateContext_func)(EGLDisplay dpy, -+ EGLConfig config, -+ EGLContext share_context, -+ const EGLint* attrib_list); -+typedef EGLBoolean (*eglDestroyContext_func)(EGLDisplay display, -+ EGLContext context); -+typedef EGLBoolean (*eglTerminate_func)(EGLDisplay display); -+typedef EGLImageKHR (*eglCreateImageKHR_func)(EGLDisplay dpy, -+ EGLContext ctx, -+ EGLenum target, -+ EGLClientBuffer buffer, -+ const EGLint* attrib_list); -+typedef EGLBoolean (*eglDestroyImageKHR_func)(EGLDisplay dpy, -+ EGLImageKHR image); -+typedef EGLint (*eglGetError_func)(void); -+typedef void* (*eglGetProcAddress_func)(const char*); -+typedef EGLDisplay (*eglGetPlatformDisplayEXT_func)(EGLenum platform, -+ void* native_display, -+ const EGLint* attrib_list); -+typedef EGLDisplay (*eglGetPlatformDisplay_func)(EGLenum platform, -+ void* native_display, -+ const EGLAttrib* attrib_list); -+ -+typedef EGLBoolean (*eglInitialize_func)(EGLDisplay dpy, -+ EGLint* major, -+ EGLint* minor); -+typedef EGLBoolean (*eglMakeCurrent_func)(EGLDisplay dpy, -+ EGLSurface draw, -+ EGLSurface read, -+ EGLContext ctx); -+typedef EGLBoolean (*eglQueryDmaBufFormatsEXT_func)(EGLDisplay dpy, -+ EGLint max_formats, -+ EGLint* formats, -+ EGLint* num_formats); -+typedef EGLBoolean (*eglQueryDmaBufModifiersEXT_func)(EGLDisplay dpy, -+ EGLint format, -+ EGLint max_modifiers, -+ EGLuint64KHR* modifiers, -+ EGLBoolean* external_only, -+ EGLint* num_modifiers); -+typedef const char* (*eglQueryString_func)(EGLDisplay dpy, EGLint name); -+typedef void (*glEGLImageTargetTexture2DOES_func)(GLenum target, -+ GLeglImageOES image); -+ -+// This doesn't follow naming conventions in WebRTC, where the naming -+// should look like e.g. egl_bind_api instead of EglBindAPI, however -+// we named them according to the exported functions they map to for -+// consistency. -+eglBindAPI_func EglBindAPI = nullptr; -+eglCreateContext_func EglCreateContext = nullptr; -+eglDestroyContext_func EglDestroyContext = nullptr; -+eglTerminate_func EglTerminate = nullptr; -+eglCreateImageKHR_func EglCreateImageKHR = nullptr; -+eglDestroyImageKHR_func EglDestroyImageKHR = nullptr; -+eglGetError_func EglGetError = nullptr; -+eglGetProcAddress_func EglGetProcAddress = nullptr; -+eglGetPlatformDisplayEXT_func EglGetPlatformDisplayEXT = nullptr; -+eglGetPlatformDisplay_func EglGetPlatformDisplay = nullptr; -+eglInitialize_func EglInitialize = nullptr; -+eglMakeCurrent_func EglMakeCurrent = nullptr; -+eglQueryDmaBufFormatsEXT_func EglQueryDmaBufFormatsEXT = nullptr; -+eglQueryDmaBufModifiersEXT_func EglQueryDmaBufModifiersEXT = nullptr; -+eglQueryString_func EglQueryString = nullptr; -+glEGLImageTargetTexture2DOES_func GlEGLImageTargetTexture2DOES = nullptr; -+ -+// GL -+typedef void (*glBindTexture_func)(GLenum target, GLuint texture); -+typedef void (*glDeleteTextures_func)(GLsizei n, const GLuint* textures); -+typedef void (*glGenTextures_func)(GLsizei n, GLuint* textures); -+typedef GLenum (*glGetError_func)(void); -+typedef const GLubyte* (*glGetString_func)(GLenum name); -+typedef void (*glGetTexImage_func)(GLenum target, -+ GLint level, -+ GLenum format, -+ GLenum type, -+ void* pixels); -+typedef void (*glTexParameteri_func)(GLenum target, GLenum pname, GLint param); -+typedef void* (*glXGetProcAddressARB_func)(const char*); -+ -+// This doesn't follow naming conventions in WebRTC, where the naming -+// should look like e.g. egl_bind_api instead of EglBindAPI, however -+// we named them according to the exported functions they map to for -+// consistency. -+glBindTexture_func GlBindTexture = nullptr; -+glDeleteTextures_func GlDeleteTextures = nullptr; -+glGenTextures_func GlGenTextures = nullptr; -+glGetError_func GlGetError = nullptr; -+glGetString_func GlGetString = nullptr; -+glGetTexImage_func GlGetTexImage = nullptr; -+glTexParameteri_func GlTexParameteri = nullptr; -+glXGetProcAddressARB_func GlXGetProcAddressARB = nullptr; -+ -+static const std::string FormatGLError(GLenum err) { -+ switch (err) { -+ case GL_NO_ERROR: -+ return "GL_NO_ERROR"; -+ case GL_INVALID_ENUM: -+ return "GL_INVALID_ENUM"; -+ case GL_INVALID_VALUE: -+ return "GL_INVALID_VALUE"; -+ case GL_INVALID_OPERATION: -+ return "GL_INVALID_OPERATION"; -+ case GL_STACK_OVERFLOW: -+ return "GL_STACK_OVERFLOW"; -+ case GL_STACK_UNDERFLOW: -+ return "GL_STACK_UNDERFLOW"; -+ case GL_OUT_OF_MEMORY: -+ return "GL_OUT_OF_MEMORY"; -+ default: -+ return "GL error code: " + std::to_string(err); -+ } -+} -+ -+static const std::string FormatEGLError(EGLint err) { -+ switch (err) { -+ case EGL_NOT_INITIALIZED: -+ return "EGL_NOT_INITIALIZED"; -+ case EGL_BAD_ACCESS: -+ return "EGL_BAD_ACCESS"; -+ case EGL_BAD_ALLOC: -+ return "EGL_BAD_ALLOC"; -+ case EGL_BAD_ATTRIBUTE: -+ return "EGL_BAD_ATTRIBUTE"; -+ case EGL_BAD_CONTEXT: -+ return "EGL_BAD_CONTEXT"; -+ case EGL_BAD_CONFIG: -+ return "EGL_BAD_CONFIG"; -+ case EGL_BAD_CURRENT_SURFACE: -+ return "EGL_BAD_CURRENT_SURFACE"; -+ case EGL_BAD_DISPLAY: -+ return "EGL_BAD_DISPLAY"; -+ case EGL_BAD_SURFACE: -+ return "EGL_BAD_SURFACE"; -+ case EGL_BAD_MATCH: -+ return "EGL_BAD_MATCH"; -+ case EGL_BAD_PARAMETER: -+ return "EGL_BAD_PARAMETER"; -+ case EGL_BAD_NATIVE_PIXMAP: -+ return "EGL_BAD_NATIVE_PIXMAP"; -+ case EGL_BAD_NATIVE_WINDOW: -+ return "EGL_BAD_NATIVE_WINDOW"; -+ case EGL_CONTEXT_LOST: -+ return "EGL_CONTEXT_LOST"; -+ default: -+ return "EGL error code: " + std::to_string(err); -+ } -+} -+ -+static uint32_t SpaPixelFormatToDrmFormat(uint32_t spa_format) { -+ switch (spa_format) { -+ case SPA_VIDEO_FORMAT_RGBA: -+ return DRM_FORMAT_ABGR8888; -+ case SPA_VIDEO_FORMAT_RGBx: -+ return DRM_FORMAT_XBGR8888; -+ case SPA_VIDEO_FORMAT_BGRA: -+ return DRM_FORMAT_ARGB8888; -+ case SPA_VIDEO_FORMAT_BGRx: -+ return DRM_FORMAT_XRGB8888; -+ default: -+ return DRM_FORMAT_INVALID; -+ } -+} -+ -+static void CloseLibrary(void* library) { -+ if (library) { -+ dlclose(library); -+ library = nullptr; -+ } -+} -+ -+static void* g_lib_egl = nullptr; -+ -+static bool OpenEGL() { -+ g_lib_egl = dlopen("libEGL.so.1", RTLD_NOW | RTLD_GLOBAL); -+ if (g_lib_egl) { -+ EglGetProcAddress = -+ (eglGetProcAddress_func)dlsym(g_lib_egl, "eglGetProcAddress"); -+ return EglGetProcAddress; -+ } -+ -+ return false; -+} -+ -+static bool LoadEGL() { -+ if (OpenEGL()) { -+ EglBindAPI = (eglBindAPI_func)EglGetProcAddress("eglBindAPI"); -+ EglCreateContext = -+ (eglCreateContext_func)EglGetProcAddress("eglCreateContext"); -+ EglDestroyContext = -+ (eglDestroyContext_func)EglGetProcAddress("eglDestroyContext"); -+ EglTerminate = (eglTerminate_func)EglGetProcAddress("eglTerminate"); -+ EglCreateImageKHR = -+ (eglCreateImageKHR_func)EglGetProcAddress("eglCreateImageKHR"); -+ EglDestroyImageKHR = -+ (eglDestroyImageKHR_func)EglGetProcAddress("eglDestroyImageKHR"); -+ EglGetError = (eglGetError_func)EglGetProcAddress("eglGetError"); -+ EglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_func)EglGetProcAddress( -+ "eglGetPlatformDisplayEXT"); -+ EglGetPlatformDisplay = -+ (eglGetPlatformDisplay_func)EglGetProcAddress("eglGetPlatformDisplay"); -+ EglInitialize = (eglInitialize_func)EglGetProcAddress("eglInitialize"); -+ EglMakeCurrent = (eglMakeCurrent_func)EglGetProcAddress("eglMakeCurrent"); -+ EglQueryString = (eglQueryString_func)EglGetProcAddress("eglQueryString"); -+ GlEGLImageTargetTexture2DOES = -+ (glEGLImageTargetTexture2DOES_func)EglGetProcAddress( -+ "glEGLImageTargetTexture2DOES"); -+ -+ return EglBindAPI && EglCreateContext && EglCreateImageKHR && -+ EglTerminate && EglDestroyContext && EglDestroyImageKHR && -+ EglGetError && EglGetPlatformDisplayEXT && EglGetPlatformDisplay && -+ EglInitialize && EglMakeCurrent && EglQueryString && -+ GlEGLImageTargetTexture2DOES; -+ } -+ -+ return false; -+} -+ -+static void* g_lib_gl = nullptr; -+ -+static bool OpenGL() { -+ std::vector names = {"libGL.so.1", "libGL.so"}; -+ for (const std::string& name : names) { -+ g_lib_gl = dlopen(name.c_str(), RTLD_NOW | RTLD_GLOBAL); -+ if (g_lib_gl) { -+ GlXGetProcAddressARB = -+ (glXGetProcAddressARB_func)dlsym(g_lib_gl, "glXGetProcAddressARB"); -+ return GlXGetProcAddressARB; -+ } -+ } -+ -+ return false; -+} -+ -+static bool LoadGL() { -+ if (OpenGL()) { -+ GlGetString = (glGetString_func)GlXGetProcAddressARB("glGetString"); -+ if (!GlGetString) { -+ return false; -+ } -+ -+ GlBindTexture = (glBindTexture_func)GlXGetProcAddressARB("glBindTexture"); -+ GlDeleteTextures = -+ (glDeleteTextures_func)GlXGetProcAddressARB("glDeleteTextures"); -+ GlGenTextures = (glGenTextures_func)GlXGetProcAddressARB("glGenTextures"); -+ GlGetError = (glGetError_func)GlXGetProcAddressARB("glGetError"); -+ GlGetTexImage = (glGetTexImage_func)GlXGetProcAddressARB("glGetTexImage"); -+ GlTexParameteri = -+ (glTexParameteri_func)GlXGetProcAddressARB("glTexParameteri"); -+ -+ return GlBindTexture && GlDeleteTextures && GlGenTextures && GlGetError && -+ GlGetTexImage && GlTexParameteri; -+ } -+ -+ return false; -+} -+ -+EglDmaBuf::EglDmaBuf() { -+ if (!LoadEGL()) { -+ RTC_LOG(LS_ERROR) << "Unable to load EGL entry functions."; -+ CloseLibrary(g_lib_egl); -+ return; -+ } -+ -+ if (!LoadGL()) { -+ RTC_LOG(LS_ERROR) << "Failed to load OpenGL entry functions."; -+ CloseLibrary(g_lib_gl); -+ return; -+ } -+ -+ if (!GetClientExtensions(EGL_NO_DISPLAY, EGL_EXTENSIONS)) { -+ return; -+ } -+ -+ bool has_platform_base_ext = false; -+ bool has_platform_gbm_ext = false; -+ bool has_khr_platform_gbm_ext = false; -+ -+ for (const auto& extension : egl_.extensions) { -+ if (extension == "EGL_EXT_platform_base") { -+ has_platform_base_ext = true; -+ continue; -+ } else if (extension == "EGL_MESA_platform_gbm") { -+ has_platform_gbm_ext = true; -+ continue; -+ } else if (extension == "EGL_KHR_platform_gbm") { -+ has_khr_platform_gbm_ext = true; -+ continue; -+ } -+ } -+ -+ if (!has_platform_base_ext || !has_platform_gbm_ext || -+ !has_khr_platform_gbm_ext) { -+ RTC_LOG(LS_ERROR) << "One of required EGL extensions is missing"; -+ return; -+ } -+ -+ egl_.display = EglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, -+ (void*)EGL_DEFAULT_DISPLAY, nullptr); -+ -+ if (egl_.display == EGL_NO_DISPLAY) { -+ RTC_LOG(LS_ERROR) << "Failed to obtain default EGL display: " -+ << FormatEGLError(EglGetError()) << "\n" -+ << "Defaulting to using first available render node"; -+ absl::optional render_node = GetRenderNode(); -+ if (!render_node) { -+ return; -+ } -+ -+ drm_fd_ = open(render_node->c_str(), O_RDWR); -+ -+ if (drm_fd_ < 0) { -+ RTC_LOG(LS_ERROR) << "Failed to open drm render node: " -+ << strerror(errno); -+ return; -+ } -+ -+ gbm_device_ = gbm_create_device(drm_fd_); -+ -+ if (!gbm_device_) { -+ RTC_LOG(LS_ERROR) << "Cannot create GBM device: " << strerror(errno); -+ close(drm_fd_); -+ return; -+ } -+ -+ // Use eglGetPlatformDisplayEXT() to get the display pointer -+ // if the implementation supports it. -+ egl_.display = -+ EglGetPlatformDisplayEXT(EGL_PLATFORM_GBM_KHR, gbm_device_, nullptr); -+ } -+ -+ if (egl_.display == EGL_NO_DISPLAY) { -+ RTC_LOG(LS_ERROR) << "Error during obtaining EGL display: " -+ << FormatEGLError(EglGetError()); -+ return; -+ } -+ -+ EGLint major, minor; -+ if (EglInitialize(egl_.display, &major, &minor) == EGL_FALSE) { -+ RTC_LOG(LS_ERROR) << "Error during eglInitialize: " -+ << FormatEGLError(EglGetError()); -+ return; -+ } -+ -+ if (EglBindAPI(EGL_OPENGL_API) == EGL_FALSE) { -+ RTC_LOG(LS_ERROR) << "bind OpenGL API failed"; -+ return; -+ } -+ -+ egl_.context = -+ EglCreateContext(egl_.display, nullptr, EGL_NO_CONTEXT, nullptr); -+ -+ if (egl_.context == EGL_NO_CONTEXT) { -+ RTC_LOG(LS_ERROR) << "Couldn't create EGL context: " -+ << FormatGLError(EglGetError()); -+ return; -+ } -+ -+ if (!GetClientExtensions(egl_.display, EGL_EXTENSIONS)) { -+ return; -+ } -+ -+ bool has_image_dma_buf_import_modifiers_ext = false; -+ -+ for (const auto& extension : egl_.extensions) { -+ if (extension == "EGL_EXT_image_dma_buf_import") { -+ has_image_dma_buf_import_ext_ = true; -+ continue; -+ } else if (extension == "EGL_EXT_image_dma_buf_import_modifiers") { -+ has_image_dma_buf_import_modifiers_ext = true; -+ continue; -+ } -+ } -+ -+ if (has_image_dma_buf_import_ext_ && has_image_dma_buf_import_modifiers_ext) { -+ EglQueryDmaBufFormatsEXT = (eglQueryDmaBufFormatsEXT_func)EglGetProcAddress( -+ "eglQueryDmaBufFormatsEXT"); -+ EglQueryDmaBufModifiersEXT = -+ (eglQueryDmaBufModifiersEXT_func)EglGetProcAddress( -+ "eglQueryDmaBufModifiersEXT"); -+ } -+ -+ RTC_LOG(LS_INFO) << "Egl initialization succeeded"; -+ egl_initialized_ = true; -+} -+ -+EglDmaBuf::~EglDmaBuf() { -+ if (gbm_device_) { -+ gbm_device_destroy(gbm_device_); -+ close(drm_fd_); -+ } -+ -+ if (egl_.context != EGL_NO_CONTEXT) { -+ EglDestroyContext(egl_.display, egl_.context); -+ } -+ -+ if (egl_.display != EGL_NO_DISPLAY) { -+ EglTerminate(egl_.display); -+ } -+ -+ // BUG: crbug.com/1290566 -+ // Closing libEGL.so.1 when using NVidia drivers causes a crash -+ // when EglGetPlatformDisplayEXT() is used, at least this one is enough -+ // to be called to make it crash. -+ // It also looks that libepoxy and glad don't dlclose it either -+ // CloseLibrary(g_lib_egl); -+ // CloseLibrary(g_lib_gl); -+} -+ -+bool EglDmaBuf::GetClientExtensions(EGLDisplay dpy, EGLint name) { -+ // Get the list of client extensions -+ const char* client_extensions_cstring = EglQueryString(dpy, name); -+ if (!client_extensions_cstring) { -+ // If eglQueryString() returned NULL, the implementation doesn't support -+ // EGL_EXT_client_extensions. Expect an EGL_BAD_DISPLAY error. -+ RTC_LOG(LS_ERROR) << "No client extensions defined! " -+ << FormatEGLError(EglGetError()); -+ return false; -+ } -+ -+ std::vector client_extensions; -+ rtc::split(client_extensions_cstring, ' ', -+ &client_extensions); -+ for (const auto& extension : client_extensions) { -+ egl_.extensions.push_back(extension); -+ } -+ -+ return true; -+} -+ -+std::unique_ptr EglDmaBuf::ImageFromDmaBuf( -+ const DesktopSize& size, -+ uint32_t format, -+ const std::vector& plane_datas, -+ uint64_t modifier) { -+ std::unique_ptr src; -+ -+ if (!egl_initialized_) { -+ return src; -+ } -+ -+ if (plane_datas.size() <= 0) { -+ RTC_LOG(LS_ERROR) << "Failed to process buffer: invalid number of planes"; -+ return src; -+ } -+ -+ EGLint attribs[47]; -+ int atti = 0; -+ -+ attribs[atti++] = EGL_WIDTH; -+ attribs[atti++] = static_cast(size.width()); -+ attribs[atti++] = EGL_HEIGHT; -+ attribs[atti++] = static_cast(size.height()); -+ attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT; -+ attribs[atti++] = SpaPixelFormatToDrmFormat(format); -+ -+ if (plane_datas.size() > 0) { -+ attribs[atti++] = EGL_DMA_BUF_PLANE0_FD_EXT; -+ attribs[atti++] = plane_datas[0].fd; -+ attribs[atti++] = EGL_DMA_BUF_PLANE0_OFFSET_EXT; -+ attribs[atti++] = plane_datas[0].offset; -+ attribs[atti++] = EGL_DMA_BUF_PLANE0_PITCH_EXT; -+ attribs[atti++] = plane_datas[0].stride; -+ -+ if (modifier != DRM_FORMAT_MOD_INVALID) { -+ attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT; -+ attribs[atti++] = modifier & 0xFFFFFFFF; -+ attribs[atti++] = EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT; -+ attribs[atti++] = modifier >> 32; -+ } -+ } -+ -+ if (plane_datas.size() > 1) { -+ attribs[atti++] = EGL_DMA_BUF_PLANE1_FD_EXT; -+ attribs[atti++] = plane_datas[1].fd; -+ attribs[atti++] = EGL_DMA_BUF_PLANE1_OFFSET_EXT; -+ attribs[atti++] = plane_datas[1].offset; -+ attribs[atti++] = EGL_DMA_BUF_PLANE1_PITCH_EXT; -+ attribs[atti++] = plane_datas[1].stride; -+ -+ if (modifier != DRM_FORMAT_MOD_INVALID) { -+ attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT; -+ attribs[atti++] = modifier & 0xFFFFFFFF; -+ attribs[atti++] = EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT; -+ attribs[atti++] = modifier >> 32; -+ } -+ } -+ -+ if (plane_datas.size() > 2) { -+ attribs[atti++] = EGL_DMA_BUF_PLANE2_FD_EXT; -+ attribs[atti++] = plane_datas[2].fd; -+ attribs[atti++] = EGL_DMA_BUF_PLANE2_OFFSET_EXT; -+ attribs[atti++] = plane_datas[2].offset; -+ attribs[atti++] = EGL_DMA_BUF_PLANE2_PITCH_EXT; -+ attribs[atti++] = plane_datas[2].stride; -+ -+ if (modifier != DRM_FORMAT_MOD_INVALID) { -+ attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT; -+ attribs[atti++] = modifier & 0xFFFFFFFF; -+ attribs[atti++] = EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT; -+ attribs[atti++] = modifier >> 32; -+ } -+ } -+ -+ if (plane_datas.size() > 3) { -+ attribs[atti++] = EGL_DMA_BUF_PLANE3_FD_EXT; -+ attribs[atti++] = plane_datas[3].fd; -+ attribs[atti++] = EGL_DMA_BUF_PLANE3_OFFSET_EXT; -+ attribs[atti++] = plane_datas[3].offset; -+ attribs[atti++] = EGL_DMA_BUF_PLANE3_PITCH_EXT; -+ attribs[atti++] = plane_datas[3].stride; -+ -+ if (modifier != DRM_FORMAT_MOD_INVALID) { -+ attribs[atti++] = EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT; -+ attribs[atti++] = modifier & 0xFFFFFFFF; -+ attribs[atti++] = EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT; -+ attribs[atti++] = modifier >> 32; -+ } -+ } -+ -+ attribs[atti++] = EGL_NONE; -+ -+ // bind context to render thread -+ EglMakeCurrent(egl_.display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_.context); -+ -+ // create EGL image from attribute list -+ EGLImageKHR image = EglCreateImageKHR( -+ egl_.display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs); -+ -+ if (image == EGL_NO_IMAGE) { -+ RTC_LOG(LS_ERROR) << "Failed to record frame: Error creating EGLImage - " -+ << FormatEGLError(EglGetError()); -+ return src; -+ } -+ -+ // create GL 2D texture for framebuffer -+ GLuint texture; -+ GlGenTextures(1, &texture); -+ GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); -+ GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); -+ GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -+ GlTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); -+ GlBindTexture(GL_TEXTURE_2D, texture); -+ GlEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); -+ -+ src = std::make_unique(plane_datas[0].stride * size.height()); -+ -+ GLenum gl_format = GL_BGRA; -+ switch (format) { -+ case SPA_VIDEO_FORMAT_RGBx: -+ gl_format = GL_RGBA; -+ break; -+ case SPA_VIDEO_FORMAT_RGBA: -+ gl_format = GL_RGBA; -+ break; -+ case SPA_VIDEO_FORMAT_BGRx: -+ gl_format = GL_BGRA; -+ break; -+ default: -+ gl_format = GL_BGRA; -+ break; -+ } -+ GlGetTexImage(GL_TEXTURE_2D, 0, gl_format, GL_UNSIGNED_BYTE, src.get()); -+ -+ if (GlGetError()) { -+ RTC_LOG(LS_ERROR) << "Failed to get image from DMA buffer."; -+ return src; -+ } -+ -+ GlDeleteTextures(1, &texture); -+ EglDestroyImageKHR(egl_.display, image); -+ -+ return src; -+} -+ -+std::vector EglDmaBuf::QueryDmaBufModifiers(uint32_t format) { -+ if (!egl_initialized_) { -+ return {}; -+ } -+ -+ // Explicit modifiers not supported, return just DRM_FORMAT_MOD_INVALID as we -+ // can still use modifier-less DMA-BUFs if we have required extension -+ if (EglQueryDmaBufFormatsEXT == nullptr || -+ EglQueryDmaBufModifiersEXT == nullptr) { -+ return has_image_dma_buf_import_ext_ -+ ? std::vector{DRM_FORMAT_MOD_INVALID} -+ : std::vector{}; -+ } -+ -+ uint32_t drm_format = SpaPixelFormatToDrmFormat(format); -+ // Should never happen as it's us who controls the list of supported formats -+ RTC_DCHECK(drm_format != DRM_FORMAT_INVALID); -+ -+ EGLint count = 0; -+ EGLBoolean success = -+ EglQueryDmaBufFormatsEXT(egl_.display, 0, nullptr, &count); -+ -+ if (!success || !count) { -+ RTC_LOG(LS_ERROR) << "Failed to query DMA-BUF formats."; -+ return {DRM_FORMAT_MOD_INVALID}; -+ } -+ -+ std::vector formats(count); -+ if (!EglQueryDmaBufFormatsEXT(egl_.display, count, -+ reinterpret_cast(formats.data()), -+ &count)) { -+ RTC_LOG(LS_ERROR) << "Failed to query DMA-BUF formats."; -+ return {DRM_FORMAT_MOD_INVALID}; -+ } -+ -+ if (std::find(formats.begin(), formats.end(), drm_format) == formats.end()) { -+ RTC_LOG(LS_ERROR) << "Format " << drm_format -+ << " not supported for modifiers."; -+ return {DRM_FORMAT_MOD_INVALID}; -+ } -+ -+ success = EglQueryDmaBufModifiersEXT(egl_.display, drm_format, 0, nullptr, -+ nullptr, &count); -+ -+ if (!success || !count) { -+ RTC_LOG(LS_ERROR) << "Failed to query DMA-BUF modifiers."; -+ return {DRM_FORMAT_MOD_INVALID}; -+ } -+ -+ std::vector modifiers(count); -+ if (!EglQueryDmaBufModifiersEXT(egl_.display, drm_format, count, -+ modifiers.data(), nullptr, &count)) { -+ RTC_LOG(LS_ERROR) << "Failed to query DMA-BUF modifiers."; -+ } -+ -+ // Support modifier-less buffers -+ modifiers.push_back(DRM_FORMAT_MOD_INVALID); -+ return modifiers; -+} -+ -+absl::optional EglDmaBuf::GetRenderNode() { -+ int max_devices = drmGetDevices2(0, nullptr, 0); -+ if (max_devices <= 0) { -+ RTC_LOG(LS_ERROR) << "drmGetDevices2() has not found any devices (errno=" -+ << -max_devices << ")"; -+ return absl::nullopt; -+ } -+ -+ std::vector devices(max_devices); -+ int ret = drmGetDevices2(0, devices.data(), max_devices); -+ if (ret < 0) { -+ RTC_LOG(LS_ERROR) << "drmGetDevices2() returned an error " << ret; -+ return absl::nullopt; -+ } -+ -+ std::string render_node; -+ -+ for (const drmDevicePtr& device : devices) { -+ if (device->available_nodes & (1 << DRM_NODE_RENDER)) { -+ render_node = device->nodes[DRM_NODE_RENDER]; -+ break; -+ } -+ } -+ -+ drmFreeDevices(devices.data(), ret); -+ return render_node; -+} -+ -+} // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/egl_dmabuf.h b/third_party/libwebrtc/modules/desktop_capture/linux/egl_dmabuf.h -new file mode 100644 -index 0000000..b755d8b ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/egl_dmabuf.h -@@ -0,0 +1,68 @@ -+/* -+ * Copyright 2021 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#ifndef MODULES_DESKTOP_CAPTURE_LINUX_EGL_DMABUF_H_ -+#define MODULES_DESKTOP_CAPTURE_LINUX_EGL_DMABUF_H_ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "absl/types/optional.h" -+#include "modules/desktop_capture/desktop_geometry.h" -+ -+namespace webrtc { -+ -+class EglDmaBuf { -+ public: -+ struct EGLStruct { -+ std::vector extensions; -+ EGLDisplay display = EGL_NO_DISPLAY; -+ EGLContext context = EGL_NO_CONTEXT; -+ }; -+ -+ struct PlaneData { -+ int32_t fd; -+ uint32_t stride; -+ uint32_t offset; -+ }; -+ -+ EglDmaBuf(); -+ ~EglDmaBuf(); -+ -+ std::unique_ptr ImageFromDmaBuf( -+ const DesktopSize& size, -+ uint32_t format, -+ const std::vector& plane_datas, -+ uint64_t modifiers); -+ std::vector QueryDmaBufModifiers(uint32_t format); -+ -+ bool IsEglInitialized() const { return egl_initialized_; } -+ -+ private: -+ bool GetClientExtensions(EGLDisplay dpy, EGLint name); -+ -+ bool egl_initialized_ = false; -+ bool has_image_dma_buf_import_ext_ = false; -+ int32_t drm_fd_ = -1; // for GBM buffer mmap -+ gbm_device* gbm_device_ = nullptr; // for passed GBM buffer retrieval -+ -+ EGLStruct egl_; -+ -+ absl::optional GetRenderNode(); -+}; -+ -+} // namespace webrtc -+ -+#endif // MODULES_DESKTOP_CAPTURE_LINUX_EGL_DMABUF_H_ -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.cc b/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.cc -new file mode 100644 -index 0000000..09dea24 ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.cc -@@ -0,0 +1,56 @@ -+/* -+ * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#include "modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.h" -+ -+#include -+ -+#include "modules/desktop_capture/desktop_capture_options.h" -+#include "modules/desktop_capture/desktop_capturer.h" -+#include "rtc_base/checks.h" -+#include "rtc_base/logging.h" -+ -+namespace webrtc { -+ -+MouseCursorMonitorPipeWire::MouseCursorMonitorPipeWire( -+ const DesktopCaptureOptions& options) -+ : options_(options) { -+} -+ -+MouseCursorMonitorPipeWire::~MouseCursorMonitorPipeWire() {} -+ -+void MouseCursorMonitorPipeWire::Init(Callback* callback, Mode mode) { -+ RTC_DCHECK(!callback_); -+ RTC_DCHECK(callback); -+ -+ callback_ = callback; -+ mode_ = mode; -+} -+ -+void MouseCursorMonitorPipeWire::Capture() { -+ RTC_DCHECK(callback_); -+ -+ std::unique_ptr mouse_cursor = -+ options_.screencast_stream()->CaptureCursor(); -+ -+ if (mouse_cursor && mouse_cursor->image()->data()) { -+ callback_->OnMouseCursor(mouse_cursor.release()); -+ } -+ -+ if (mode_ == SHAPE_AND_POSITION) { -+ absl::optional mouse_cursor_position = -+ options_.screencast_stream()->CaptureCursorPosition(); -+ if (mouse_cursor_position) { -+ callback_->OnMouseCursorPosition(mouse_cursor_position.value()); -+ } -+ } -+} -+ -+} // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.h b/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.h -new file mode 100644 -index 0000000..9b9ccf7 ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.h -@@ -0,0 +1,41 @@ -+/* -+ * Copyright 2022 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#ifndef MODULES_DESKTOP_CAPTURE_LINUX_MOUSE_CURSOR_MONITOR_PIPEWIRE_H_ -+#define MODULES_DESKTOP_CAPTURE_LINUX_MOUSE_CURSOR_MONITOR_PIPEWIRE_H_ -+ -+#include -+ -+#include "api/scoped_refptr.h" -+#include "modules/desktop_capture/desktop_capture_options.h" -+#include "modules/desktop_capture/desktop_capture_types.h" -+#include "modules/desktop_capture/linux/shared_screencast_stream.h" -+#include "modules/desktop_capture/mouse_cursor.h" -+#include "modules/desktop_capture/mouse_cursor_monitor.h" -+ -+namespace webrtc { -+ -+class MouseCursorMonitorPipeWire : public MouseCursorMonitor { -+ public: -+ explicit MouseCursorMonitorPipeWire(const DesktopCaptureOptions& options); -+ ~MouseCursorMonitorPipeWire() override; -+ -+ // MouseCursorMonitor: -+ void Init(Callback* callback, Mode mode) override; -+ void Capture() override; -+ -+ DesktopCaptureOptions options_; -+ Callback* callback_ = nullptr; -+ Mode mode_ = SHAPE_AND_POSITION; -+}; -+ -+} // namespace webrtc -+ -+#endif // MODULES_DESKTOP_CAPTURE_LINUX_MOUSE_CURSOR_MONITOR_PIPEWIRE_H_ -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/pipewire.sigs b/third_party/libwebrtc/modules/desktop_capture/linux/pipewire.sigs -index 3e21e9d..06a97b8 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/linux/pipewire.sigs -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/pipewire.sigs -@@ -7,38 +7,44 @@ - //------------------------------------------------ - - // core.h --void pw_core_destroy(pw_core *core); --pw_type *pw_core_get_type(pw_core *core); --pw_core * pw_core_new(pw_loop *main_loop, pw_properties *props); -+int pw_core_disconnect(pw_core *core); - - // loop.h - void pw_loop_destroy(pw_loop *loop); --pw_loop * pw_loop_new(pw_properties *properties); -+pw_loop * pw_loop_new(const spa_dict *props); -+ - - // pipewire.h - void pw_init(int *argc, char **argv[]); -+const char* pw_get_library_version(); - - // properties.h - pw_properties * pw_properties_new_string(const char *args); - --// remote.h --void pw_remote_add_listener(pw_remote *remote, spa_hook *listener, const pw_remote_events *events, void *data); --int pw_remote_connect_fd(pw_remote *remote, int fd); --void pw_remote_destroy(pw_remote *remote); --pw_remote * pw_remote_new(pw_core *core, pw_properties *properties, size_t user_data_size); -- - // stream.h - void pw_stream_add_listener(pw_stream *stream, spa_hook *listener, const pw_stream_events *events, void *data); --int pw_stream_connect(pw_stream *stream, enum pw_direction direction, const char *port_path, enum pw_stream_flags flags, const spa_pod **params, uint32_t n_params); -+int pw_stream_connect(pw_stream *stream, enum pw_direction direction, uint32_t target_id, enum pw_stream_flags flags, const spa_pod **params, uint32_t n_params); -+int pw_stream_disconnect(pw_stream *stream); - pw_buffer *pw_stream_dequeue_buffer(pw_stream *stream); - void pw_stream_destroy(pw_stream *stream); --void pw_stream_finish_format(pw_stream *stream, int res, const spa_pod **params, uint32_t n_params); --pw_stream * pw_stream_new(pw_remote *remote, const char *name, pw_properties *props); -+pw_stream * pw_stream_new(pw_core *core, const char *name, pw_properties *props); - int pw_stream_queue_buffer(pw_stream *stream, pw_buffer *buffer); - int pw_stream_set_active(pw_stream *stream, bool active); -+int pw_stream_update_params(pw_stream *stream, const spa_pod **params, uint32_t n_params); - - // thread-loop.h - void pw_thread_loop_destroy(pw_thread_loop *loop); --pw_thread_loop * pw_thread_loop_new(pw_loop *loop, const char *name); -+pw_thread_loop * pw_thread_loop_new(const char *name, const spa_dict *props); - int pw_thread_loop_start(pw_thread_loop *loop); - void pw_thread_loop_stop(pw_thread_loop *loop); -+void pw_thread_loop_lock(pw_thread_loop *loop); -+void pw_thread_loop_unlock(pw_thread_loop *loop); -+pw_loop * pw_thread_loop_get_loop(pw_thread_loop *loop); -+void pw_thread_loop_signal(pw_thread_loop *loop, bool wait_for_accept); -+void pw_thread_loop_wait(pw_thread_loop *loop); -+ -+// context.h -+void pw_context_destroy(pw_context *context); -+pw_context *pw_context_new(pw_loop *main_loop, pw_properties *props, size_t user_data_size); -+pw_core * pw_context_connect(pw_context *context, pw_properties *properties, size_t user_data_size); -+pw_core * pw_context_connect_fd(pw_context *context, int fd, pw_properties *properties, size_t user_data_size); -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/pipewire_stub_header.fragment b/third_party/libwebrtc/modules/desktop_capture/linux/pipewire_stub_header.fragment -index 9d7dbd2..06ae18d 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/linux/pipewire_stub_header.fragment -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/pipewire_stub_header.fragment -@@ -5,4 +5,5 @@ extern "C" { - - #include - -+#include - } -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/scoped_glib.cc b/third_party/libwebrtc/modules/desktop_capture/linux/scoped_glib.cc -new file mode 100644 -index 0000000..51ca57a ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/scoped_glib.cc -@@ -0,0 +1,57 @@ -+/* -+ * Copyright 2022 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#include "modules/desktop_capture/linux/scoped_glib.h" -+ -+namespace webrtc { -+ -+template <> -+Scoped::~Scoped() { -+ if (ptr_) { -+ g_error_free(ptr_); -+ } -+} -+ -+template <> -+Scoped::~Scoped() { -+ if (ptr_) { -+ g_free(ptr_); -+ } -+} -+ -+template <> -+Scoped::~Scoped() { -+ if (ptr_) { -+ g_variant_unref(ptr_); -+ } -+} -+ -+template <> -+Scoped::~Scoped() { -+ if (ptr_) { -+ g_variant_iter_free(ptr_); -+ } -+} -+ -+template <> -+Scoped::~Scoped() { -+ if (ptr_) { -+ g_object_unref(ptr_); -+ } -+} -+ -+template <> -+Scoped::~Scoped() { -+ if (ptr_) { -+ g_object_unref(ptr_); -+ } -+} -+ -+} // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/scoped_glib.h b/third_party/libwebrtc/modules/desktop_capture/linux/scoped_glib.h -new file mode 100644 -index 0000000..bf77855 ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/scoped_glib.h -@@ -0,0 +1,65 @@ -+/* -+ * Copyright 2022 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCOPED_GLIB_H_ -+#define MODULES_DESKTOP_CAPTURE_LINUX_SCOPED_GLIB_H_ -+ -+#include -+ -+#include "rtc_base/checks.h" -+ -+namespace webrtc { -+ -+template -+class Scoped { -+ public: -+ Scoped() {} -+ explicit Scoped(T* val) { ptr_ = val; } -+ ~Scoped() { RTC_DCHECK_NOTREACHED(); } -+ -+ T* operator->() const { return ptr_; } -+ -+ explicit operator bool() const { return ptr_ != nullptr; } -+ -+ bool operator!() const { return ptr_ == nullptr; } -+ -+ T* get() const { return ptr_; } -+ -+ T** receive() { -+ RTC_CHECK(!ptr_); -+ return &ptr_; -+ } -+ -+ Scoped& operator=(T* val) { -+ RTC_DCHECK(val); -+ ptr_ = val; -+ return *this; -+ } -+ -+ protected: -+ T* ptr_ = nullptr; -+}; -+ -+template <> -+Scoped::~Scoped(); -+template <> -+Scoped::~Scoped(); -+template <> -+Scoped::~Scoped(); -+template <> -+Scoped::~Scoped(); -+template <> -+Scoped::~Scoped(); -+template <> -+Scoped::~Scoped(); -+ -+} // namespace webrtc -+ -+#endif // MODULES_DESKTOP_CAPTURE_LINUX_SCOPED_GLIB_H_ -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc b/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc -deleted file mode 100644 -index 3813d69..0000000 ---- a/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc -+++ /dev/null -@@ -1,28 +0,0 @@ --/* -- * Copyright 2018 The WebRTC project authors. All Rights Reserved. -- * -- * Use of this source code is governed by a BSD-style license -- * that can be found in the LICENSE file in the root of the source -- * tree. An additional intellectual property rights grant can be found -- * in the file PATENTS. All contributing project authors may -- * be found in the AUTHORS file in the root of the source tree. -- */ -- --#include "modules/desktop_capture/linux/screen_capturer_pipewire.h" -- --#include -- --namespace webrtc { -- --ScreenCapturerPipeWire::ScreenCapturerPipeWire() -- : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::kScreen) {} --ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {} -- --// static --std::unique_ptr --ScreenCapturerPipeWire::CreateRawScreenCapturer( -- const DesktopCaptureOptions& options) { -- return std::make_unique(); --} -- --} // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h b/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h -deleted file mode 100644 -index 66dcd68..0000000 ---- a/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_pipewire.h -+++ /dev/null -@@ -1,33 +0,0 @@ --/* -- * Copyright 2018 The WebRTC project authors. All Rights Reserved. -- * -- * Use of this source code is governed by a BSD-style license -- * that can be found in the LICENSE file in the root of the source -- * tree. An additional intellectual property rights grant can be found -- * in the file PATENTS. All contributing project authors may -- * be found in the AUTHORS file in the root of the source tree. -- */ -- --#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_ --#define MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_ -- --#include -- --#include "modules/desktop_capture/linux/base_capturer_pipewire.h" -- --namespace webrtc { -- --class ScreenCapturerPipeWire : public BaseCapturerPipeWire { -- public: -- ScreenCapturerPipeWire(); -- ~ScreenCapturerPipeWire() override; -- -- static std::unique_ptr CreateRawScreenCapturer( -- const DesktopCaptureOptions& options); -- -- RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerPipeWire); --}; -- --} // namespace webrtc -- --#endif // MODULES_DESKTOP_CAPTURE_LINUX_SCREEN_CAPTURER_PIPEWIRE_H_ -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/screencast_portal.cc b/third_party/libwebrtc/modules/desktop_capture/linux/screencast_portal.cc -new file mode 100644 -index 0000000..306e984 ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/screencast_portal.cc -@@ -0,0 +1,532 @@ -+/* -+ * Copyright 2022 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#include "modules/desktop_capture/linux/screencast_portal.h" -+ -+#include -+#include -+ -+#include "modules/desktop_capture/linux/scoped_glib.h" -+#include "rtc_base/checks.h" -+#include "rtc_base/logging.h" -+ -+namespace webrtc { -+ -+const char kDesktopBusName[] = "org.freedesktop.portal.Desktop"; -+const char kDesktopObjectPath[] = "/org/freedesktop/portal/desktop"; -+const char kDesktopRequestObjectPath[] = -+ "/org/freedesktop/portal/desktop/request"; -+const char kSessionInterfaceName[] = "org.freedesktop.portal.Session"; -+const char kRequestInterfaceName[] = "org.freedesktop.portal.Request"; -+const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast"; -+ -+ScreenCastPortal::ScreenCastPortal(CaptureSourceType source_type, -+ PortalNotifier* notifier) -+ : notifier_(notifier), capture_source_type_(source_type) {} -+ -+ScreenCastPortal::~ScreenCastPortal() { -+ if (start_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_); -+ } -+ if (sources_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(connection_, -+ sources_request_signal_id_); -+ } -+ if (session_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(connection_, -+ session_request_signal_id_); -+ } -+ -+ if (!session_handle_.empty()) { -+ Scoped message( -+ g_dbus_message_new_method_call(kDesktopBusName, session_handle_.c_str(), -+ kSessionInterfaceName, "Close")); -+ if (message.get()) { -+ Scoped error; -+ g_dbus_connection_send_message(connection_, message.get(), -+ G_DBUS_SEND_MESSAGE_FLAGS_NONE, -+ /*out_serial=*/nullptr, error.receive()); -+ if (error.get()) { -+ RTC_LOG(LS_ERROR) << "Failed to close the session: " << error->message; -+ } -+ } -+ } -+ -+ if (cancellable_) { -+ g_cancellable_cancel(cancellable_); -+ g_object_unref(cancellable_); -+ cancellable_ = nullptr; -+ } -+ -+ if (proxy_) { -+ g_object_unref(proxy_); -+ proxy_ = nullptr; -+ } -+ -+ if (pw_fd_ != -1) { -+ close(pw_fd_); -+ } -+} -+ -+void ScreenCastPortal::Start() { -+ cancellable_ = g_cancellable_new(); -+ g_dbus_proxy_new_for_bus( -+ G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, /*info=*/nullptr, -+ kDesktopBusName, kDesktopObjectPath, kScreenCastInterfaceName, -+ cancellable_, reinterpret_cast(OnProxyRequested), -+ this); -+} -+ -+void ScreenCastPortal::PortalFailed(RequestResponse result) { -+ notifier_->OnScreenCastRequestResult(result, pw_stream_node_id_, pw_fd_); -+} -+ -+uint32_t ScreenCastPortal::SetupRequestResponseSignal( -+ const char* object_path, -+ GDBusSignalCallback callback) { -+ return g_dbus_connection_signal_subscribe( -+ connection_, kDesktopBusName, kRequestInterfaceName, "Response", -+ object_path, /*arg0=*/nullptr, G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE, -+ callback, this, /*user_data_free_func=*/nullptr); -+} -+ -+// static -+void ScreenCastPortal::OnProxyRequested(GObject* /*object*/, -+ GAsyncResult* result, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ GDBusProxy* proxy = g_dbus_proxy_new_finish(result, error.receive()); -+ if (!proxy) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to create a proxy for the screen cast portal: " -+ << error->message; -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ that->proxy_ = proxy; -+ that->connection_ = g_dbus_proxy_get_connection(that->proxy_); -+ -+ RTC_LOG(LS_INFO) << "Created proxy for the screen cast portal."; -+ -+ that->SessionRequest(); -+} -+ -+// static -+std::string ScreenCastPortal::PrepareSignalHandle(GDBusConnection* connection, -+ const char* token) { -+ Scoped sender( -+ g_strdup(g_dbus_connection_get_unique_name(connection) + 1)); -+ for (int i = 0; sender.get()[i]; ++i) { -+ if (sender.get()[i] == '.') { -+ sender.get()[i] = '_'; -+ } -+ } -+ -+ const char* handle = g_strconcat(kDesktopRequestObjectPath, "/", sender.get(), -+ "/", token, /*end of varargs*/ nullptr); -+ -+ return handle; -+} -+ -+void ScreenCastPortal::SessionRequest() { -+ GVariantBuilder builder; -+ Scoped variant_string; -+ -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ variant_string = -+ g_strdup_printf("webrtc_session%d", g_random_int_range(0, G_MAXINT)); -+ g_variant_builder_add(&builder, "{sv}", "session_handle_token", -+ g_variant_new_string(variant_string.get())); -+ variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); -+ g_variant_builder_add(&builder, "{sv}", "handle_token", -+ g_variant_new_string(variant_string.get())); -+ -+ portal_handle_ = PrepareSignalHandle(connection_, variant_string.get()); -+ session_request_signal_id_ = SetupRequestResponseSignal( -+ portal_handle_.c_str(), OnSessionRequestResponseSignal); -+ -+ RTC_LOG(LS_INFO) << "Screen cast session requested."; -+ g_dbus_proxy_call(proxy_, "CreateSession", g_variant_new("(a{sv})", &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, -+ reinterpret_cast(OnSessionRequested), -+ this); -+} -+ -+// static -+void ScreenCastPortal::OnSessionRequested(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped variant( -+ g_dbus_proxy_call_finish(proxy, result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to create a screen cast session: " -+ << error->message; -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ RTC_LOG(LS_INFO) << "Initializing the screen cast session."; -+ -+ Scoped handle; -+ g_variant_get_child(variant.get(), 0, "o", &handle); -+ if (!handle) { -+ RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session."; -+ if (that->session_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->session_request_signal_id_); -+ that->session_request_signal_id_ = 0; -+ } -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ RTC_LOG(LS_INFO) << "Subscribing to the screen cast session."; -+} -+ -+// static -+void ScreenCastPortal::OnSessionRequestResponseSignal( -+ GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ RTC_LOG(LS_INFO) -+ << "Received response for the screen cast session subscription."; -+ -+ uint32_t portal_response; -+ Scoped response_data; -+ g_variant_get(parameters, "(u@a{sv})", &portal_response, -+ response_data.receive()); -+ Scoped session_handle( -+ g_variant_lookup_value(response_data.get(), "session_handle", nullptr)); -+ that->session_handle_ = g_variant_dup_string(session_handle.get(), nullptr); -+ -+ if (that->session_handle_.empty() || portal_response) { -+ RTC_LOG(LS_ERROR) -+ << "Failed to request the screen cast session subscription."; -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ that->session_closed_signal_id_ = g_dbus_connection_signal_subscribe( -+ that->connection_, kDesktopBusName, kSessionInterfaceName, "Closed", -+ that->session_handle_.c_str(), /*arg0=*/nullptr, G_DBUS_SIGNAL_FLAGS_NONE, -+ OnSessionClosedSignal, that, /*user_data_free_func=*/nullptr); -+ -+ that->SourcesRequest(); -+} -+ -+// static -+void ScreenCastPortal::OnSessionClosedSignal(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ RTC_LOG(LS_INFO) << "Received closed signal from session."; -+ -+ that->notifier_->OnScreenCastSessionClosed(); -+ -+ // Unsubscribe from the signal and free the session handle to avoid calling -+ // Session::Close from the destructor since it's already closed -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->session_closed_signal_id_); -+} -+ -+void ScreenCastPortal::SourcesRequest() { -+ GVariantBuilder builder; -+ Scoped variant_string; -+ -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ // We want to record monitor content. -+ g_variant_builder_add( -+ &builder, "{sv}", "types", -+ g_variant_new_uint32(static_cast(capture_source_type_))); -+ // We don't want to allow selection of multiple sources. -+ g_variant_builder_add(&builder, "{sv}", "multiple", -+ g_variant_new_boolean(false)); -+ -+ Scoped variant( -+ g_dbus_proxy_get_cached_property(proxy_, "AvailableCursorModes")); -+ if (variant.get()) { -+ uint32_t modes = 0; -+ g_variant_get(variant.get(), "u", &modes); -+ // Make request only if this mode is advertised by the portal -+ // implementation. -+ if (modes & static_cast(cursor_mode_)) { -+ g_variant_builder_add( -+ &builder, "{sv}", "cursor_mode", -+ g_variant_new_uint32(static_cast(cursor_mode_))); -+ } -+ } -+ -+ variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); -+ g_variant_builder_add(&builder, "{sv}", "handle_token", -+ g_variant_new_string(variant_string.get())); -+ -+ sources_handle_ = PrepareSignalHandle(connection_, variant_string.get()); -+ sources_request_signal_id_ = SetupRequestResponseSignal( -+ sources_handle_.c_str(), OnSourcesRequestResponseSignal); -+ -+ RTC_LOG(LS_INFO) << "Requesting sources from the screen cast session."; -+ g_dbus_proxy_call( -+ proxy_, "SelectSources", -+ g_variant_new("(oa{sv})", session_handle_.c_str(), &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, -+ reinterpret_cast(OnSourcesRequested), this); -+} -+ -+// static -+void ScreenCastPortal::OnSourcesRequested(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped variant( -+ g_dbus_proxy_call_finish(proxy, result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to request the sources: " << error->message; -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ RTC_LOG(LS_INFO) << "Sources requested from the screen cast session."; -+ -+ Scoped handle; -+ g_variant_get_child(variant.get(), 0, "o", handle.receive()); -+ if (!handle) { -+ RTC_LOG(LS_ERROR) << "Failed to initialize the screen cast session."; -+ if (that->sources_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->sources_request_signal_id_); -+ that->sources_request_signal_id_ = 0; -+ } -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ RTC_LOG(LS_INFO) << "Subscribed to sources signal."; -+} -+ -+// static -+void ScreenCastPortal::OnSourcesRequestResponseSignal( -+ GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ RTC_LOG(LS_INFO) << "Received sources signal from session."; -+ -+ uint32_t portal_response; -+ g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); -+ if (portal_response) { -+ RTC_LOG(LS_ERROR) -+ << "Failed to select sources for the screen cast session."; -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ that->StartRequest(); -+} -+ -+void ScreenCastPortal::StartRequest() { -+ GVariantBuilder builder; -+ Scoped variant_string; -+ -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ variant_string = g_strdup_printf("webrtc%d", g_random_int_range(0, G_MAXINT)); -+ g_variant_builder_add(&builder, "{sv}", "handle_token", -+ g_variant_new_string(variant_string.get())); -+ -+ start_handle_ = PrepareSignalHandle(connection_, variant_string.get()); -+ start_request_signal_id_ = SetupRequestResponseSignal( -+ start_handle_.c_str(), OnStartRequestResponseSignal); -+ -+ // "Identifier for the application window", this is Wayland, so not "x11:...". -+ const char parent_window[] = ""; -+ -+ RTC_LOG(LS_INFO) << "Starting the screen cast session."; -+ g_dbus_proxy_call(proxy_, "Start", -+ g_variant_new("(osa{sv})", session_handle_.c_str(), -+ parent_window, &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, cancellable_, -+ reinterpret_cast(OnStartRequested), -+ this); -+} -+ -+// static -+void ScreenCastPortal::OnStartRequested(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped variant( -+ g_dbus_proxy_call_finish(proxy, result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to start the screen cast session: " -+ << error->message; -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ RTC_LOG(LS_INFO) << "Initializing the start of the screen cast session."; -+ -+ Scoped handle; -+ g_variant_get_child(variant.get(), 0, "o", handle.receive()); -+ if (!handle) { -+ RTC_LOG(LS_ERROR) -+ << "Failed to initialize the start of the screen cast session."; -+ if (that->start_request_signal_id_) { -+ g_dbus_connection_signal_unsubscribe(that->connection_, -+ that->start_request_signal_id_); -+ that->start_request_signal_id_ = 0; -+ } -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ RTC_LOG(LS_INFO) << "Subscribed to the start signal."; -+} -+ -+// static -+void ScreenCastPortal::OnStartRequestResponseSignal(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ RTC_LOG(LS_INFO) << "Start signal received."; -+ uint32_t portal_response; -+ Scoped response_data; -+ Scoped iter; -+ g_variant_get(parameters, "(u@a{sv})", &portal_response, -+ response_data.receive()); -+ if (portal_response || !response_data) { -+ RTC_LOG(LS_ERROR) << "Failed to start the screen cast session."; -+ that->PortalFailed(static_cast(portal_response)); -+ return; -+ } -+ -+ // Array of PipeWire streams. See -+ // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml -+ // documentation for . -+ if (g_variant_lookup(response_data.get(), "streams", "a(ua{sv})", -+ iter.receive())) { -+ Scoped variant; -+ -+ while (g_variant_iter_next(iter.get(), "@(ua{sv})", variant.receive())) { -+ uint32_t stream_id; -+ uint32_t type; -+ Scoped options; -+ -+ g_variant_get(variant.get(), "(u@a{sv})", &stream_id, options.receive()); -+ RTC_DCHECK(options.get()); -+ -+ if (g_variant_lookup(options.get(), "source_type", "u", &type)) { -+ that->capture_source_type_ = -+ static_cast(type); -+ } -+ -+ that->pw_stream_node_id_ = stream_id; -+ -+ break; -+ } -+ } -+ -+ that->OpenPipeWireRemote(); -+} -+ -+void ScreenCastPortal::OpenPipeWireRemote() { -+ GVariantBuilder builder; -+ g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); -+ -+ RTC_LOG(LS_INFO) << "Opening the PipeWire remote."; -+ -+ g_dbus_proxy_call_with_unix_fd_list( -+ proxy_, "OpenPipeWireRemote", -+ g_variant_new("(oa{sv})", session_handle_.c_str(), &builder), -+ G_DBUS_CALL_FLAGS_NONE, /*timeout=*/-1, /*fd_list=*/nullptr, cancellable_, -+ reinterpret_cast(OnOpenPipeWireRemoteRequested), -+ this); -+} -+ -+// static -+void ScreenCastPortal::OnOpenPipeWireRemoteRequested(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data) { -+ ScreenCastPortal* that = static_cast(user_data); -+ RTC_DCHECK(that); -+ -+ Scoped error; -+ Scoped outlist; -+ Scoped variant(g_dbus_proxy_call_with_unix_fd_list_finish( -+ proxy, outlist.receive(), result, error.receive())); -+ if (!variant) { -+ if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) -+ return; -+ RTC_LOG(LS_ERROR) << "Failed to open the PipeWire remote: " -+ << error->message; -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ int32_t index; -+ g_variant_get(variant.get(), "(h)", &index); -+ -+ that->pw_fd_ = g_unix_fd_list_get(outlist.get(), index, error.receive()); -+ -+ if (that->pw_fd_ == -1) { -+ RTC_LOG(LS_ERROR) << "Failed to get file descriptor from the list: " -+ << error->message; -+ that->PortalFailed(RequestResponse::kError); -+ return; -+ } -+ -+ that->notifier_->OnScreenCastRequestResult( -+ ScreenCastPortal::RequestResponse::kSuccess, that->pw_stream_node_id_, -+ that->pw_fd_); -+} -+ -+} // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/screencast_portal.h b/third_party/libwebrtc/modules/desktop_capture/linux/screencast_portal.h -new file mode 100644 -index 0000000..7da218e ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/screencast_portal.h -@@ -0,0 +1,169 @@ -+/* -+ * Copyright 2022 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SCREENCAST_PORTAL_H_ -+#define MODULES_DESKTOP_CAPTURE_LINUX_SCREENCAST_PORTAL_H_ -+ -+#include -+ -+#include -+ -+#include "absl/types/optional.h" -+ -+namespace webrtc { -+ -+class ScreenCastPortal { -+ public: -+ // Values are set based on source type property in -+ // xdg-desktop-portal/screencast -+ // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml -+ enum class CaptureSourceType : uint32_t { -+ kScreen = 0b01, -+ kWindow = 0b10, -+ kAnyScreenContent = kScreen | kWindow -+ }; -+ -+ // Values are set based on cursor mode property in -+ // xdg-desktop-portal/screencast -+ // https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml -+ enum class CursorMode : uint32_t { -+ // Mouse cursor will not be included in any form -+ kHidden = 0b01, -+ // Mouse cursor will be part of the screen content -+ kEmbedded = 0b10, -+ // Mouse cursor information will be send separately in form of metadata -+ kMetadata = 0b100 -+ }; -+ -+ // Interface that must be implemented by the ScreenCastPortal consumers. -+ enum class RequestResponse { -+ // Success, the request is carried out. -+ kSuccess, -+ // The user cancelled the interaction. -+ kUserCancelled, -+ // The user interaction was ended in some other way. -+ kError, -+ -+ kMaxValue = kError -+ }; -+ -+ class PortalNotifier { -+ public: -+ virtual void OnScreenCastRequestResult(RequestResponse result, -+ uint32_t stream_node_id, -+ int fd) = 0; -+ virtual void OnScreenCastSessionClosed() = 0; -+ -+ protected: -+ PortalNotifier() = default; -+ virtual ~PortalNotifier() = default; -+ }; -+ -+ explicit ScreenCastPortal(CaptureSourceType source_type, -+ PortalNotifier* notifier); -+ ~ScreenCastPortal(); -+ -+ // Initialize ScreenCastPortal with series of DBus calls where we try to -+ // obtain all the required information, like PipeWire file descriptor and -+ // PipeWire stream node ID. -+ // -+ // The observer will return whether the communication with xdg-desktop-portal -+ // was successful and only then you will be able to get all the required -+ // information in order to continue working with PipeWire. -+ void Start(); -+ -+ private: -+ PortalNotifier* notifier_; -+ -+ // A PipeWire stream ID of stream we will be connecting to -+ uint32_t pw_stream_node_id_ = 0; -+ // A file descriptor of PipeWire socket -+ int pw_fd_ = -1; -+ -+ CaptureSourceType capture_source_type_ = -+ ScreenCastPortal::CaptureSourceType::kScreen; -+ -+ CursorMode cursor_mode_ = ScreenCastPortal::CursorMode::kMetadata; -+ -+ GDBusConnection* connection_ = nullptr; -+ GDBusProxy* proxy_ = nullptr; -+ GCancellable* cancellable_ = nullptr; -+ std::string portal_handle_; -+ std::string session_handle_; -+ std::string sources_handle_; -+ std::string start_handle_; -+ guint session_request_signal_id_ = 0; -+ guint sources_request_signal_id_ = 0; -+ guint start_request_signal_id_ = 0; -+ guint session_closed_signal_id_ = 0; -+ -+ void PortalFailed(RequestResponse result); -+ -+ uint32_t SetupRequestResponseSignal(const char* object_path, -+ GDBusSignalCallback callback); -+ -+ static void OnProxyRequested(GObject* object, -+ GAsyncResult* result, -+ gpointer user_data); -+ -+ static std::string PrepareSignalHandle(GDBusConnection* connection, -+ const char* token); -+ -+ void SessionRequest(); -+ static void OnSessionRequested(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ static void OnSessionRequestResponseSignal(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data); -+ static void OnSessionClosedSignal(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data); -+ void SourcesRequest(); -+ static void OnSourcesRequested(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ static void OnSourcesRequestResponseSignal(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data); -+ -+ void StartRequest(); -+ static void OnStartRequested(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+ static void OnStartRequestResponseSignal(GDBusConnection* connection, -+ const char* sender_name, -+ const char* object_path, -+ const char* interface_name, -+ const char* signal_name, -+ GVariant* parameters, -+ gpointer user_data); -+ -+ void OpenPipeWireRemote(); -+ static void OnOpenPipeWireRemoteRequested(GDBusProxy* proxy, -+ GAsyncResult* result, -+ gpointer user_data); -+}; -+ -+} // namespace webrtc -+ -+#endif // MODULES_DESKTOP_CAPTURE_LINUX_SCREENCAST_PORTAL_H_ -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/shared_screencast_stream.cc b/third_party/libwebrtc/modules/desktop_capture/linux/shared_screencast_stream.cc -new file mode 100644 -index 0000000..c6ba661 ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/shared_screencast_stream.cc -@@ -0,0 +1,872 @@ -+/* -+ * Copyright 2022 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#include "modules/desktop_capture/linux/shared_screencast_stream.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "absl/memory/memory.h" -+#include "modules/desktop_capture/linux/egl_dmabuf.h" -+#include "modules/desktop_capture/screen_capture_frame_queue.h" -+#include "rtc_base/checks.h" -+#include "rtc_base/logging.h" -+#include "rtc_base/sanitizer.h" -+#include "rtc_base/string_encode.h" -+#include "rtc_base/string_to_number.h" -+#include "rtc_base/synchronization/mutex.h" -+ -+#if defined(WEBRTC_DLOPEN_PIPEWIRE) -+#include "modules/desktop_capture/linux/pipewire_stubs.h" -+using modules_desktop_capture_linux_wayland::InitializeStubs; -+using modules_desktop_capture_linux_wayland::kModuleDrm; -+using modules_desktop_capture_linux_wayland::kModulePipewire; -+using modules_desktop_capture_linux_wayland::StubPathMap; -+#endif // defined(WEBRTC_DLOPEN_PIPEWIRE) -+ -+namespace webrtc { -+ -+const int kBytesPerPixel = 4; -+ -+#if defined(WEBRTC_DLOPEN_PIPEWIRE) -+const char kPipeWireLib[] = "libpipewire-0.3.so.0"; -+const char kDrmLib[] = "libdrm.so.2"; -+#endif -+ -+#if !PW_CHECK_VERSION(0, 3, 29) -+#define SPA_POD_PROP_FLAG_MANDATORY (1u << 3) -+#endif -+#if !PW_CHECK_VERSION(0, 3, 33) -+#define SPA_POD_PROP_FLAG_DONT_FIXATE (1u << 4) -+#endif -+ -+constexpr int kCursorBpp = 4; -+constexpr int CursorMetaSize(int w, int h) { -+ return (sizeof(struct spa_meta_cursor) + sizeof(struct spa_meta_bitmap) + -+ w * h * kCursorBpp); -+} -+ -+struct PipeWireVersion { -+ int major = 0; -+ int minor = 0; -+ int micro = 0; -+}; -+ -+constexpr PipeWireVersion kDmaBufMinVersion = {0, 3, 24}; -+constexpr PipeWireVersion kDmaBufModifierMinVersion = {0, 3, 33}; -+constexpr PipeWireVersion kDropSingleModifierMinVersion = {0, 3, 40}; -+ -+PipeWireVersion ParsePipeWireVersion(const char* version) { -+ std::vector parsed_version; -+ rtc::split(version, '.', &parsed_version); -+ -+ if (parsed_version.size() != 3) { -+ return {}; -+ } -+ -+ absl::optional major = rtc::StringToNumber(parsed_version.at(0)); -+ absl::optional minor = rtc::StringToNumber(parsed_version.at(1)); -+ absl::optional micro = rtc::StringToNumber(parsed_version.at(2)); -+ -+ // Return invalid version if we failed to parse it -+ if (!major || !minor || !micro) { -+ return {0, 0, 0}; -+ } -+ -+ return {major.value(), micro.value(), micro.value()}; -+} -+ -+spa_pod* BuildFormat(spa_pod_builder* builder, -+ uint32_t format, -+ const std::vector& modifiers) { -+ bool first = true; -+ spa_pod_frame frames[2]; -+ spa_rectangle pw_min_screen_bounds = spa_rectangle{1, 1}; -+ spa_rectangle pw_max_screen_bounds = spa_rectangle{UINT32_MAX, UINT32_MAX}; -+ -+ spa_pod_builder_push_object(builder, &frames[0], SPA_TYPE_OBJECT_Format, -+ SPA_PARAM_EnumFormat); -+ spa_pod_builder_add(builder, SPA_FORMAT_mediaType, -+ SPA_POD_Id(SPA_MEDIA_TYPE_video), 0); -+ spa_pod_builder_add(builder, SPA_FORMAT_mediaSubtype, -+ SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), 0); -+ spa_pod_builder_add(builder, SPA_FORMAT_VIDEO_format, SPA_POD_Id(format), 0); -+ -+ if (modifiers.size()) { -+ if (modifiers.size() == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID) { -+ spa_pod_builder_prop(builder, SPA_FORMAT_VIDEO_modifier, -+ SPA_POD_PROP_FLAG_MANDATORY); -+ spa_pod_builder_long(builder, modifiers[0]); -+ } else { -+ spa_pod_builder_prop( -+ builder, SPA_FORMAT_VIDEO_modifier, -+ SPA_POD_PROP_FLAG_MANDATORY | SPA_POD_PROP_FLAG_DONT_FIXATE); -+ spa_pod_builder_push_choice(builder, &frames[1], SPA_CHOICE_Enum, 0); -+ -+ // modifiers from the array -+ for (int64_t val : modifiers) { -+ spa_pod_builder_long(builder, val); -+ // Add the first modifier twice as the very first value is the default -+ // option -+ if (first) { -+ spa_pod_builder_long(builder, val); -+ first = false; -+ } -+ } -+ spa_pod_builder_pop(builder, &frames[1]); -+ } -+ } -+ -+ spa_pod_builder_add( -+ builder, SPA_FORMAT_VIDEO_size, -+ SPA_POD_CHOICE_RANGE_Rectangle( -+ &pw_min_screen_bounds, &pw_min_screen_bounds, &pw_max_screen_bounds), -+ 0); -+ -+ return static_cast(spa_pod_builder_pop(builder, &frames[0])); -+} -+ -+class PipeWireThreadLoopLock { -+ public: -+ explicit PipeWireThreadLoopLock(pw_thread_loop* loop) : loop_(loop) { -+ pw_thread_loop_lock(loop_); -+ } -+ ~PipeWireThreadLoopLock() { pw_thread_loop_unlock(loop_); } -+ -+ private: -+ pw_thread_loop* const loop_; -+}; -+ -+class ScopedBuf { -+ public: -+ ScopedBuf() {} -+ ScopedBuf(uint8_t* map, int map_size, int fd) -+ : map_(map), map_size_(map_size), fd_(fd) {} -+ ~ScopedBuf() { -+ if (map_ != MAP_FAILED) { -+ munmap(map_, map_size_); -+ } -+ } -+ -+ explicit operator bool() { return map_ != MAP_FAILED; } -+ -+ void initialize(uint8_t* map, int map_size, int fd) { -+ map_ = map; -+ map_size_ = map_size; -+ fd_ = fd; -+ } -+ -+ uint8_t* get() { return map_; } -+ -+ protected: -+ uint8_t* map_ = static_cast(MAP_FAILED); -+ int map_size_; -+ int fd_; -+}; -+ -+class SharedScreenCastStreamPrivate { -+ public: -+ SharedScreenCastStreamPrivate(); -+ ~SharedScreenCastStreamPrivate(); -+ -+ bool StartScreenCastStream(uint32_t stream_node_id, int fd); -+ void StopScreenCastStream(); -+ std::unique_ptr CaptureFrame(); -+ std::unique_ptr CaptureCursor(); -+ DesktopVector CaptureCursorPosition(); -+ -+ private: -+ uint32_t pw_stream_node_id_ = 0; -+ int pw_fd_ = -1; -+ -+ DesktopSize desktop_size_ = {}; -+ DesktopSize video_size_; -+ -+ webrtc::Mutex queue_lock_; -+ ScreenCaptureFrameQueue queue_ -+ RTC_GUARDED_BY(&queue_lock_); -+ std::unique_ptr mouse_cursor_; -+ DesktopVector mouse_cursor_position_ = DesktopVector(-1, -1); -+ -+ int64_t modifier_; -+ std::unique_ptr egl_dmabuf_; -+ // List of modifiers we query as supported by the graphics card/driver -+ std::vector modifiers_; -+ -+ // PipeWire types -+ struct pw_context* pw_context_ = nullptr; -+ struct pw_core* pw_core_ = nullptr; -+ struct pw_stream* pw_stream_ = nullptr; -+ struct pw_thread_loop* pw_main_loop_ = nullptr; -+ struct spa_source* renegotiate_ = nullptr; -+ -+ spa_hook spa_core_listener_; -+ spa_hook spa_stream_listener_; -+ -+ // A number used to verify all previous methods and the resulting -+ // events have been handled. -+ int server_version_sync_ = 0; -+ // Version of the running PipeWire server we communicate with -+ PipeWireVersion pw_server_version_; -+ // Version of the library used to run our code -+ PipeWireVersion pw_client_version_; -+ -+ // event handlers -+ pw_core_events pw_core_events_ = {}; -+ pw_stream_events pw_stream_events_ = {}; -+ -+ struct spa_video_info_raw spa_video_format_; -+ -+ void ProcessBuffer(pw_buffer* buffer); -+ void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size); -+ -+ // PipeWire callbacks -+ static void OnCoreError(void* data, -+ uint32_t id, -+ int seq, -+ int res, -+ const char* message); -+ static void OnCoreDone(void* user_data, uint32_t id, int seq); -+ static void OnCoreInfo(void* user_data, const pw_core_info* info); -+ static void OnStreamParamChanged(void* data, -+ uint32_t id, -+ const struct spa_pod* format); -+ static void OnStreamStateChanged(void* data, -+ pw_stream_state old_state, -+ pw_stream_state state, -+ const char* error_message); -+ static void OnStreamProcess(void* data); -+ // This will be invoked in case we fail to process DMA-BUF PW buffer using -+ // negotiated stream parameters (modifier). We will drop the modifier we -+ // failed to use and try to use a different one or fallback to shared memory -+ // buffers. -+ static void OnRenegotiateFormat(void* data, uint64_t); -+}; -+ -+bool operator>=(const PipeWireVersion& current_pw_version, -+ const PipeWireVersion& required_pw_version) { -+ if (!current_pw_version.major && !current_pw_version.minor && -+ !current_pw_version.micro) { -+ return false; -+ } -+ -+ return std::tie(current_pw_version.major, current_pw_version.minor, -+ current_pw_version.micro) >= -+ std::tie(required_pw_version.major, required_pw_version.minor, -+ required_pw_version.micro); -+} -+ -+bool operator<=(const PipeWireVersion& current_pw_version, -+ const PipeWireVersion& required_pw_version) { -+ if (!current_pw_version.major && !current_pw_version.minor && -+ !current_pw_version.micro) { -+ return false; -+ } -+ -+ return std::tie(current_pw_version.major, current_pw_version.minor, -+ current_pw_version.micro) <= -+ std::tie(required_pw_version.major, required_pw_version.minor, -+ required_pw_version.micro); -+} -+ -+void SharedScreenCastStreamPrivate::OnCoreError(void* data, -+ uint32_t id, -+ int seq, -+ int res, -+ const char* message) { -+ SharedScreenCastStreamPrivate* that = -+ static_cast(data); -+ RTC_DCHECK(that); -+ -+ RTC_LOG(LS_ERROR) << "PipeWire remote error: " << message; -+} -+ -+void SharedScreenCastStreamPrivate::OnCoreInfo(void* data, -+ const pw_core_info* info) { -+ SharedScreenCastStreamPrivate* stream = -+ static_cast(data); -+ RTC_DCHECK(stream); -+ -+ stream->pw_server_version_ = ParsePipeWireVersion(info->version); -+} -+ -+void SharedScreenCastStreamPrivate::OnCoreDone(void* data, -+ uint32_t id, -+ int seq) { -+ const SharedScreenCastStreamPrivate* stream = -+ static_cast(data); -+ RTC_DCHECK(stream); -+ -+ if (id == PW_ID_CORE && stream->server_version_sync_ == seq) { -+ pw_thread_loop_signal(stream->pw_main_loop_, false); -+ } -+} -+ -+// static -+void SharedScreenCastStreamPrivate::OnStreamStateChanged( -+ void* data, -+ pw_stream_state old_state, -+ pw_stream_state state, -+ const char* error_message) { -+ SharedScreenCastStreamPrivate* that = -+ static_cast(data); -+ RTC_DCHECK(that); -+ -+ switch (state) { -+ case PW_STREAM_STATE_ERROR: -+ RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message; -+ break; -+ case PW_STREAM_STATE_PAUSED: -+ case PW_STREAM_STATE_STREAMING: -+ case PW_STREAM_STATE_UNCONNECTED: -+ case PW_STREAM_STATE_CONNECTING: -+ break; -+ } -+} -+ -+// static -+void SharedScreenCastStreamPrivate::OnStreamParamChanged( -+ void* data, -+ uint32_t id, -+ const struct spa_pod* format) { -+ SharedScreenCastStreamPrivate* that = -+ static_cast(data); -+ RTC_DCHECK(that); -+ -+ RTC_LOG(LS_INFO) << "PipeWire stream format changed."; -+ if (!format || id != SPA_PARAM_Format) { -+ return; -+ } -+ -+ spa_format_video_raw_parse(format, &that->spa_video_format_); -+ -+ auto width = that->spa_video_format_.size.width; -+ auto height = that->spa_video_format_.size.height; -+ auto stride = SPA_ROUND_UP_N(width * kBytesPerPixel, 4); -+ auto size = height * stride; -+ -+ that->desktop_size_ = DesktopSize(width, height); -+ -+ uint8_t buffer[1024] = {}; -+ auto builder = spa_pod_builder{buffer, sizeof(buffer)}; -+ -+ // Setup buffers and meta header for new format. -+ -+ // When SPA_FORMAT_VIDEO_modifier is present we can use DMA-BUFs as -+ // the server announces support for it. -+ // See https://github.com/PipeWire/pipewire/blob/master/doc/dma-buf.dox -+ const bool has_modifier = -+ spa_pod_find_prop(format, nullptr, SPA_FORMAT_VIDEO_modifier); -+ that->modifier_ = -+ has_modifier ? that->spa_video_format_.modifier : DRM_FORMAT_MOD_INVALID; -+ std::vector params; -+ const int buffer_types = -+ has_modifier || (that->pw_server_version_ >= kDmaBufMinVersion) -+ ? (1 << SPA_DATA_DmaBuf) | (1 << SPA_DATA_MemFd) | -+ (1 << SPA_DATA_MemPtr) -+ : (1 << SPA_DATA_MemFd) | (1 << SPA_DATA_MemPtr); -+ -+ params.push_back(reinterpret_cast(spa_pod_builder_add_object( -+ &builder, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, -+ SPA_PARAM_BUFFERS_size, SPA_POD_Int(size), SPA_PARAM_BUFFERS_stride, -+ SPA_POD_Int(stride), SPA_PARAM_BUFFERS_buffers, -+ SPA_POD_CHOICE_RANGE_Int(8, 1, 32), SPA_PARAM_BUFFERS_dataType, -+ SPA_POD_CHOICE_FLAGS_Int(buffer_types)))); -+ params.push_back(reinterpret_cast(spa_pod_builder_add_object( -+ &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type, -+ SPA_POD_Id(SPA_META_Header), SPA_PARAM_META_size, -+ SPA_POD_Int(sizeof(struct spa_meta_header))))); -+ params.push_back(reinterpret_cast(spa_pod_builder_add_object( -+ &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type, -+ SPA_POD_Id(SPA_META_VideoCrop), SPA_PARAM_META_size, -+ SPA_POD_Int(sizeof(struct spa_meta_region))))); -+ params.push_back(reinterpret_cast(spa_pod_builder_add_object( -+ &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type, -+ SPA_POD_Id(SPA_META_Cursor), SPA_PARAM_META_size, -+ SPA_POD_CHOICE_RANGE_Int(CursorMetaSize(64, 64), CursorMetaSize(1, 1), -+ CursorMetaSize(384, 384))))); -+ params.push_back(reinterpret_cast(spa_pod_builder_add_object( -+ &builder, SPA_TYPE_OBJECT_ParamMeta, SPA_PARAM_Meta, SPA_PARAM_META_type, -+ SPA_POD_Id(SPA_META_VideoDamage), SPA_PARAM_META_size, -+ SPA_POD_CHOICE_RANGE_Int(sizeof(struct spa_meta_region) * 16, -+ sizeof(struct spa_meta_region) * 1, -+ sizeof(struct spa_meta_region) * 16)))); -+ -+ pw_stream_update_params(that->pw_stream_, params.data(), params.size()); -+} -+ -+// static -+void SharedScreenCastStreamPrivate::OnStreamProcess(void* data) { -+ SharedScreenCastStreamPrivate* that = -+ static_cast(data); -+ RTC_DCHECK(that); -+ -+ struct pw_buffer* next_buffer; -+ struct pw_buffer* buffer = nullptr; -+ -+ next_buffer = pw_stream_dequeue_buffer(that->pw_stream_); -+ while (next_buffer) { -+ buffer = next_buffer; -+ next_buffer = pw_stream_dequeue_buffer(that->pw_stream_); -+ -+ if (next_buffer) { -+ pw_stream_queue_buffer(that->pw_stream_, buffer); -+ } -+ } -+ -+ if (!buffer) { -+ return; -+ } -+ -+ that->ProcessBuffer(buffer); -+ -+ pw_stream_queue_buffer(that->pw_stream_, buffer); -+} -+ -+void SharedScreenCastStreamPrivate::OnRenegotiateFormat(void* data, uint64_t) { -+ SharedScreenCastStreamPrivate* that = -+ static_cast(data); -+ RTC_DCHECK(that); -+ -+ { -+ PipeWireThreadLoopLock thread_loop_lock(that->pw_main_loop_); -+ -+ uint8_t buffer[2048] = {}; -+ -+ spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)}; -+ -+ std::vector params; -+ -+ for (uint32_t format : {SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_RGBA, -+ SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx}) { -+ if (!that->modifiers_.empty()) { -+ params.push_back(BuildFormat(&builder, format, that->modifiers_)); -+ } -+ params.push_back(BuildFormat(&builder, format, /*modifiers=*/{})); -+ } -+ -+ pw_stream_update_params(that->pw_stream_, params.data(), params.size()); -+ } -+} -+ -+SharedScreenCastStreamPrivate::SharedScreenCastStreamPrivate() {} -+ -+SharedScreenCastStreamPrivate::~SharedScreenCastStreamPrivate() { -+ if (pw_main_loop_) { -+ pw_thread_loop_stop(pw_main_loop_); -+ } -+ -+ if (pw_stream_) { -+ pw_stream_destroy(pw_stream_); -+ } -+ -+ if (pw_core_) { -+ pw_core_disconnect(pw_core_); -+ } -+ -+ if (pw_context_) { -+ pw_context_destroy(pw_context_); -+ } -+ -+ if (pw_main_loop_) { -+ pw_thread_loop_destroy(pw_main_loop_); -+ } -+} -+ -+bool SharedScreenCastStreamPrivate::StartScreenCastStream( -+ uint32_t stream_node_id, -+ int fd) { -+#if defined(WEBRTC_DLOPEN_PIPEWIRE) -+ StubPathMap paths; -+ -+ // Check if the PipeWire and DRM libraries are available. -+ paths[kModulePipewire].push_back(kPipeWireLib); -+ paths[kModuleDrm].push_back(kDrmLib); -+ -+ if (!InitializeStubs(paths)) { -+ RTC_LOG(LS_ERROR) -+ << "One of following libraries is missing on your system:\n" -+ << " - PipeWire (" << kPipeWireLib << ")\n" -+ << " - drm (" << kDrmLib << ")"; -+ return false; -+ } -+#endif // defined(WEBRTC_DLOPEN_PIPEWIRE) -+ egl_dmabuf_ = std::make_unique(); -+ -+ pw_stream_node_id_ = stream_node_id; -+ pw_fd_ = fd; -+ -+ pw_init(/*argc=*/nullptr, /*argc=*/nullptr); -+ -+ pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr); -+ -+ pw_context_ = -+ pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), nullptr, 0); -+ if (!pw_context_) { -+ RTC_LOG(LS_ERROR) << "Failed to create PipeWire context"; -+ return false; -+ } -+ -+ if (pw_thread_loop_start(pw_main_loop_) < 0) { -+ RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop"; -+ return false; -+ } -+ -+ pw_client_version_ = ParsePipeWireVersion(pw_get_library_version()); -+ -+ // Initialize event handlers, remote end and stream-related. -+ pw_core_events_.version = PW_VERSION_CORE_EVENTS; -+ pw_core_events_.info = &OnCoreInfo; -+ pw_core_events_.done = &OnCoreDone; -+ pw_core_events_.error = &OnCoreError; -+ -+ pw_stream_events_.version = PW_VERSION_STREAM_EVENTS; -+ pw_stream_events_.state_changed = &OnStreamStateChanged; -+ pw_stream_events_.param_changed = &OnStreamParamChanged; -+ pw_stream_events_.process = &OnStreamProcess; -+ -+ { -+ PipeWireThreadLoopLock thread_loop_lock(pw_main_loop_); -+ -+ pw_core_ = pw_context_connect_fd(pw_context_, pw_fd_, nullptr, 0); -+ if (!pw_core_) { -+ RTC_LOG(LS_ERROR) << "Failed to connect PipeWire context"; -+ return false; -+ } -+ -+ pw_core_add_listener(pw_core_, &spa_core_listener_, &pw_core_events_, this); -+ -+ // Add an event that can be later invoked by pw_loop_signal_event() -+ renegotiate_ = pw_loop_add_event(pw_thread_loop_get_loop(pw_main_loop_), -+ OnRenegotiateFormat, this); -+ -+ server_version_sync_ = -+ pw_core_sync(pw_core_, PW_ID_CORE, server_version_sync_); -+ -+ pw_thread_loop_wait(pw_main_loop_); -+ -+ pw_properties* reuseProps = -+ pw_properties_new_string("pipewire.client.reuse=1"); -+ pw_stream_ = pw_stream_new(pw_core_, "webrtc-consume-stream", reuseProps); -+ -+ if (!pw_stream_) { -+ RTC_LOG(LS_ERROR) << "Failed to create PipeWire stream"; -+ return false; -+ } -+ -+ pw_stream_add_listener(pw_stream_, &spa_stream_listener_, -+ &pw_stream_events_, this); -+ uint8_t buffer[2048] = {}; -+ -+ spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)}; -+ -+ std::vector params; -+ const bool has_required_pw_client_version = -+ pw_client_version_ >= kDmaBufModifierMinVersion; -+ const bool has_required_pw_server_version = -+ pw_server_version_ >= kDmaBufModifierMinVersion; -+ for (uint32_t format : {SPA_VIDEO_FORMAT_BGRA, SPA_VIDEO_FORMAT_RGBA, -+ SPA_VIDEO_FORMAT_BGRx, SPA_VIDEO_FORMAT_RGBx}) { -+ // Modifiers can be used with PipeWire >= 0.3.33 -+ if (has_required_pw_client_version && has_required_pw_server_version) { -+ modifiers_ = egl_dmabuf_->QueryDmaBufModifiers(format); -+ -+ if (!modifiers_.empty()) { -+ params.push_back(BuildFormat(&builder, format, modifiers_)); -+ } -+ } -+ -+ params.push_back(BuildFormat(&builder, format, /*modifiers=*/{})); -+ } -+ -+ if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, pw_stream_node_id_, -+ PW_STREAM_FLAG_AUTOCONNECT, params.data(), -+ params.size()) != 0) { -+ RTC_LOG(LS_ERROR) << "Could not connect receiving stream."; -+ return false; -+ } -+ -+ RTC_LOG(LS_INFO) << "PipeWire remote opened."; -+ } -+ return true; -+} -+ -+void SharedScreenCastStreamPrivate::StopScreenCastStream() { -+ if (pw_stream_) { -+ pw_stream_disconnect(pw_stream_); -+ } -+} -+ -+std::unique_ptr SharedScreenCastStreamPrivate::CaptureFrame() { -+ webrtc::MutexLock lock(&queue_lock_); -+ -+ if (!queue_.current_frame()) { -+ return std::unique_ptr{}; -+ } -+ -+ std::unique_ptr frame = queue_.current_frame()->Share(); -+ return std::move(frame); -+} -+ -+std::unique_ptr SharedScreenCastStreamPrivate::CaptureCursor() { -+ if (!mouse_cursor_) { -+ return nullptr; -+ } -+ -+ return std::move(mouse_cursor_); -+} -+ -+DesktopVector SharedScreenCastStreamPrivate::CaptureCursorPosition() { -+ return mouse_cursor_position_; -+} -+ -+void SharedScreenCastStreamPrivate::ProcessBuffer(pw_buffer* buffer) { -+ spa_buffer* spa_buffer = buffer->buffer; -+ ScopedBuf map; -+ std::unique_ptr src_unique_ptr; -+ uint8_t* src = nullptr; -+ -+ // Try to update the mouse cursor first, because it can be the only -+ // information carried by the buffer -+ { -+ const struct spa_meta_cursor* cursor = -+ static_cast(spa_buffer_find_meta_data( -+ spa_buffer, SPA_META_Cursor, sizeof(*cursor))); -+ if (cursor && spa_meta_cursor_is_valid(cursor)) { -+ struct spa_meta_bitmap* bitmap = nullptr; -+ -+ if (cursor->bitmap_offset) -+ bitmap = -+ SPA_MEMBER(cursor, cursor->bitmap_offset, struct spa_meta_bitmap); -+ -+ if (bitmap && bitmap->size.width > 0 && bitmap->size.height > 0) { -+ const uint8_t* bitmap_data = -+ SPA_MEMBER(bitmap, bitmap->offset, uint8_t); -+ BasicDesktopFrame* mouse_frame = new BasicDesktopFrame( -+ DesktopSize(bitmap->size.width, bitmap->size.height)); -+ mouse_frame->CopyPixelsFrom( -+ bitmap_data, bitmap->stride, -+ DesktopRect::MakeWH(bitmap->size.width, bitmap->size.height)); -+ mouse_cursor_ = std::make_unique( -+ mouse_frame, DesktopVector(cursor->hotspot.x, cursor->hotspot.y)); -+ } -+ mouse_cursor_position_.set(cursor->position.x, cursor->position.y); -+ } -+ } -+ -+ if (spa_buffer->datas[0].chunk->size == 0) { -+ return; -+ } -+ -+ if (spa_buffer->datas[0].type == SPA_DATA_MemFd) { -+ map.initialize( -+ static_cast( -+ mmap(nullptr, -+ spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset, -+ PROT_READ, MAP_PRIVATE, spa_buffer->datas[0].fd, 0)), -+ spa_buffer->datas[0].maxsize + spa_buffer->datas[0].mapoffset, -+ spa_buffer->datas[0].fd); -+ -+ if (!map) { -+ RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " -+ << std::strerror(errno); -+ return; -+ } -+ -+ src = SPA_MEMBER(map.get(), spa_buffer->datas[0].mapoffset, uint8_t); -+ } else if (spa_buffer->datas[0].type == SPA_DATA_DmaBuf) { -+ const uint n_planes = spa_buffer->n_datas; -+ -+ if (!n_planes) { -+ return; -+ } -+ -+ std::vector plane_datas; -+ for (uint32_t i = 0; i < n_planes; ++i) { -+ EglDmaBuf::PlaneData data = { -+ static_cast(spa_buffer->datas[i].fd), -+ static_cast(spa_buffer->datas[i].chunk->stride), -+ static_cast(spa_buffer->datas[i].chunk->offset)}; -+ plane_datas.push_back(data); -+ } -+ -+ src_unique_ptr = egl_dmabuf_->ImageFromDmaBuf( -+ desktop_size_, spa_video_format_.format, plane_datas, modifier_); -+ if (src_unique_ptr) { -+ src = src_unique_ptr.get(); -+ } else { -+ RTC_LOG(LS_ERROR) << "Dropping DMA-BUF modifier: " << modifier_ -+ << " and trying to renegotiate stream parameters"; -+ -+ if (pw_client_version_ >= kDropSingleModifierMinVersion) { -+ modifiers_.erase( -+ std::remove(modifiers_.begin(), modifiers_.end(), modifier_), -+ modifiers_.end()); -+ } else { -+ modifiers_.clear(); -+ } -+ -+ pw_loop_signal_event(pw_thread_loop_get_loop(pw_main_loop_), -+ renegotiate_); -+ return; -+ } -+ } else if (spa_buffer->datas[0].type == SPA_DATA_MemPtr) { -+ src = static_cast(spa_buffer->datas[0].data); -+ } -+ -+ if (!src) { -+ return; -+ } -+ struct spa_meta_region* video_metadata = -+ static_cast(spa_buffer_find_meta_data( -+ spa_buffer, SPA_META_VideoCrop, sizeof(*video_metadata))); -+ -+ // Video size from metadata is bigger than an actual video stream size. -+ // The metadata are wrong or we should up-scale the video...in both cases -+ // just quit now. -+ if (video_metadata && (video_metadata->region.size.width > -+ static_cast(desktop_size_.width()) || -+ video_metadata->region.size.height > -+ static_cast(desktop_size_.height()))) { -+ RTC_LOG(LS_ERROR) << "Stream metadata sizes are wrong!"; -+ return; -+ } -+ -+ // Use video metadata when video size from metadata is set and smaller than -+ // video stream size, so we need to adjust it. -+ bool video_metadata_use = false; -+ const struct spa_rectangle* video_metadata_size = -+ video_metadata ? &video_metadata->region.size : nullptr; -+ -+ if (video_metadata_size && video_metadata_size->width != 0 && -+ video_metadata_size->height != 0 && -+ (static_cast(video_metadata_size->width) < desktop_size_.width() || -+ static_cast(video_metadata_size->height) < -+ desktop_size_.height())) { -+ video_metadata_use = true; -+ } -+ -+ if (video_metadata_use) { -+ video_size_ = -+ DesktopSize(video_metadata_size->width, video_metadata_size->height); -+ } else { -+ video_size_ = desktop_size_; -+ } -+ -+ uint32_t y_offset = video_metadata_use && (video_metadata->region.position.y + -+ video_size_.height() <= -+ desktop_size_.height()) -+ ? video_metadata->region.position.y -+ : 0; -+ uint32_t x_offset = video_metadata_use && (video_metadata->region.position.x + -+ video_size_.width() <= -+ desktop_size_.width()) -+ ? video_metadata->region.position.x -+ : 0; -+ -+ uint8_t* updated_src = src + (spa_buffer->datas[0].chunk->stride * y_offset) + -+ (kBytesPerPixel * x_offset); -+ -+ webrtc::MutexLock lock(&queue_lock_); -+ -+ // Move to the next frame if the current one is being used and shared -+ if (queue_.current_frame() && queue_.current_frame()->IsShared()) { -+ queue_.MoveToNextFrame(); -+ if (queue_.current_frame() && queue_.current_frame()->IsShared()) { -+ RTC_LOG(LS_WARNING) -+ << "Failed to process PipeWire buffer: no available frame"; -+ return; -+ } -+ } -+ -+ if (!queue_.current_frame() || -+ !queue_.current_frame()->size().equals(video_size_)) { -+ std::unique_ptr frame(new BasicDesktopFrame( -+ DesktopSize(video_size_.width(), video_size_.height()))); -+ queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame))); -+ } -+ -+ queue_.current_frame()->CopyPixelsFrom( -+ updated_src, -+ (spa_buffer->datas[0].chunk->stride - (kBytesPerPixel * x_offset)), -+ DesktopRect::MakeWH(video_size_.width(), video_size_.height())); -+ -+ if (spa_video_format_.format == SPA_VIDEO_FORMAT_RGBx || -+ spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) { -+ uint8_t* tmp_src = queue_.current_frame()->data(); -+ for (int i = 0; i < video_size_.height(); ++i) { -+ // If both sides decided to go with the RGBx format we need to convert -+ // it to BGRx to match color format expected by WebRTC. -+ ConvertRGBxToBGRx(tmp_src, queue_.current_frame()->stride()); -+ tmp_src += queue_.current_frame()->stride(); -+ } -+ } -+} -+ -+void SharedScreenCastStreamPrivate::ConvertRGBxToBGRx(uint8_t* frame, -+ uint32_t size) { -+ for (uint32_t i = 0; i < size; i += 4) { -+ uint8_t tempR = frame[i]; -+ uint8_t tempB = frame[i + 2]; -+ frame[i] = tempB; -+ frame[i + 2] = tempR; -+ } -+} -+ -+SharedScreenCastStream::SharedScreenCastStream() -+ : private_(std::make_unique()) {} -+ -+SharedScreenCastStream::~SharedScreenCastStream() {} -+ -+rtc::scoped_refptr -+SharedScreenCastStream::CreateDefault() { -+ // Explicit new, to access non-public constructor. -+ return rtc::scoped_refptr(new SharedScreenCastStream()); -+} -+ -+bool SharedScreenCastStream::StartScreenCastStream(uint32_t stream_node_id, -+ int fd) { -+ return private_->StartScreenCastStream(stream_node_id, fd); -+} -+ -+void SharedScreenCastStream::StopScreenCastStream() { -+ private_->StopScreenCastStream(); -+} -+ -+std::unique_ptr SharedScreenCastStream::CaptureFrame() { -+ return private_->CaptureFrame(); -+} -+ -+std::unique_ptr SharedScreenCastStream::CaptureCursor() { -+ return private_->CaptureCursor(); -+} -+ -+absl::optional SharedScreenCastStream::CaptureCursorPosition() { -+ DesktopVector position = private_->CaptureCursorPosition(); -+ -+ // Consider only (x >= 0 and y >= 0) a valid position -+ if (position.x() < 0 || position.y() < 0) { -+ return absl::nullopt; -+ } -+ -+ return position; -+} -+ -+} // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/shared_screencast_stream.h b/third_party/libwebrtc/modules/desktop_capture/linux/shared_screencast_stream.h -new file mode 100644 -index 0000000..72411e5 ---- /dev/null -+++ b/third_party/libwebrtc/modules/desktop_capture/linux/shared_screencast_stream.h -@@ -0,0 +1,71 @@ -+/* -+ * Copyright 2022 The WebRTC project authors. All Rights Reserved. -+ * -+ * Use of this source code is governed by a BSD-style license -+ * that can be found in the LICENSE file in the root of the source -+ * tree. An additional intellectual property rights grant can be found -+ * in the file PATENTS. All contributing project authors may -+ * be found in the AUTHORS file in the root of the source tree. -+ */ -+ -+#ifndef MODULES_DESKTOP_CAPTURE_LINUX_SHARED_SCREENCAST_STREAM_H_ -+#define MODULES_DESKTOP_CAPTURE_LINUX_SHARED_SCREENCAST_STREAM_H_ -+ -+#include -+ -+#include "absl/types/optional.h" -+#include "api/ref_counted_base.h" -+#include "api/scoped_refptr.h" -+#include "modules/desktop_capture/desktop_frame.h" -+#include "modules/desktop_capture/mouse_cursor.h" -+#include "rtc_base/system/rtc_export.h" -+ -+namespace webrtc { -+ -+class SharedScreenCastStreamPrivate; -+ -+class RTC_EXPORT SharedScreenCastStream -+ : public rtc::RefCountedBase { -+ public: -+ static rtc::scoped_refptr CreateDefault(); -+ -+ bool StartScreenCastStream(uint32_t stream_node_id, int fd); -+ void StopScreenCastStream(); -+ -+ // Below functions return the most recent information we get from a -+ // PipeWire buffer on each Process() callback. This assumes that we -+ // managed to successfuly connect to a PipeWire stream provided by the -+ // compositor (based on stream parameters). The cursor data are obtained -+ // from spa_meta_cursor stream metadata and therefore the cursor is not -+ // part of actual screen/window frame. -+ -+ // Returns the most recent screen/window frame we obtained from PipeWire -+ // buffer. Will return an empty frame in case we didn't manage to get a frame -+ // from PipeWire buffer. -+ std::unique_ptr CaptureFrame(); -+ -+ // Returns the most recent mouse cursor image. Will return an nullptr cursor -+ // in case we didn't manage to get a cursor from PipeWire buffer. NOTE: the -+ // cursor image might not be updated on every cursor location change, but -+ // actually only when its shape changes. -+ std::unique_ptr CaptureCursor(); -+ -+ // Returns the most recent mouse cursor position. Will not return a value in -+ // case we didn't manage to get it from PipeWire buffer. -+ absl::optional CaptureCursorPosition(); -+ -+ ~SharedScreenCastStream(); -+ -+ protected: -+ SharedScreenCastStream(); -+ -+ private: -+ SharedScreenCastStream(const SharedScreenCastStream&) = delete; -+ SharedScreenCastStream& operator=(const SharedScreenCastStream&) = delete; -+ -+ std::unique_ptr private_; -+}; -+ -+} // namespace webrtc -+ -+#endif // MODULES_DESKTOP_CAPTURE_LINUX_SHARED_SCREENCAST_STREAM_H_ -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc b/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc -deleted file mode 100644 -index c43a1f1..0000000 ---- a/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc -+++ /dev/null -@@ -1,28 +0,0 @@ --/* -- * Copyright 2018 The WebRTC project authors. All Rights Reserved. -- * -- * Use of this source code is governed by a BSD-style license -- * that can be found in the LICENSE file in the root of the source -- * tree. An additional intellectual property rights grant can be found -- * in the file PATENTS. All contributing project authors may -- * be found in the AUTHORS file in the root of the source tree. -- */ -- --#include "modules/desktop_capture/linux/window_capturer_pipewire.h" -- --#include -- --namespace webrtc { -- --WindowCapturerPipeWire::WindowCapturerPipeWire() -- : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::kWindow) {} --WindowCapturerPipeWire::~WindowCapturerPipeWire() {} -- --// static --std::unique_ptr --WindowCapturerPipeWire::CreateRawWindowCapturer( -- const DesktopCaptureOptions& options) { -- return std::make_unique(); --} -- --} // namespace webrtc -diff --git a/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_pipewire.h b/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_pipewire.h -deleted file mode 100644 -index 7f184ef..0000000 ---- a/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_pipewire.h -+++ /dev/null -@@ -1,33 +0,0 @@ --/* -- * Copyright 2018 The WebRTC project authors. All Rights Reserved. -- * -- * Use of this source code is governed by a BSD-style license -- * that can be found in the LICENSE file in the root of the source -- * tree. An additional intellectual property rights grant can be found -- * in the file PATENTS. All contributing project authors may -- * be found in the AUTHORS file in the root of the source tree. -- */ -- --#ifndef MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_ --#define MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_ -- --#include -- --#include "modules/desktop_capture/linux/base_capturer_pipewire.h" -- --namespace webrtc { -- --class WindowCapturerPipeWire : public BaseCapturerPipeWire { -- public: -- WindowCapturerPipeWire(); -- ~WindowCapturerPipeWire() override; -- -- static std::unique_ptr CreateRawWindowCapturer( -- const DesktopCaptureOptions& options); -- -- RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerPipeWire); --}; -- --} // namespace webrtc -- --#endif // MODULES_DESKTOP_CAPTURE_LINUX_WINDOW_CAPTURER_PIPEWIRE_H_ -diff --git a/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc b/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc -index e569f6e..3bb51e8 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc -+++ b/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc -@@ -17,6 +17,10 @@ - #include "modules/desktop_capture/linux/mouse_cursor_monitor_x11.h" - #endif // defined(WEBRTC_USE_X11) - -+#if defined(WEBRTC_USE_PIPEWIRE) -+#include "modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.h" -+#endif // defined(WEBRTC_USE_PIPEWIRE) -+ - namespace webrtc { - - // static -@@ -44,6 +48,13 @@ MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( - // static - std::unique_ptr MouseCursorMonitor::Create( - const DesktopCaptureOptions& options) { -+#if defined(WEBRTC_USE_PIPEWIRE) -+ if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland() && -+ options.screencast_stream()) { -+ return std::make_unique(options); -+ } -+#endif // defined(WEBRTC_USE_PIPEWIRE) -+ - #if defined(WEBRTC_USE_X11) - return MouseCursorMonitorX11::Create(options); - #else -diff --git a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_linux.cc b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_linux.cc -index 57a2002..b44ae35 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/screen_capturer_linux.cc -+++ b/third_party/libwebrtc/modules/desktop_capture/screen_capturer_linux.cc -@@ -14,7 +14,7 @@ - #include "modules/desktop_capture/desktop_capturer.h" - - #if defined(WEBRTC_USE_PIPEWIRE) --#include "modules/desktop_capture/linux/screen_capturer_pipewire.h" -+#include "modules/desktop_capture/linux/base_capturer_pipewire.h" - #endif // defined(WEBRTC_USE_PIPEWIRE) - - #if defined(WEBRTC_USE_X11) -@@ -28,7 +28,7 @@ std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( - const DesktopCaptureOptions& options) { - #if defined(WEBRTC_USE_PIPEWIRE) - if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { -- return BaseCapturerPipeWire::CreateRawScreenCapturer(options); -+ return std::make_unique(options); - } - #endif // defined(WEBRTC_USE_PIPEWIRE) - -diff --git a/third_party/libwebrtc/modules/desktop_capture/window_capturer_linux.cc b/third_party/libwebrtc/modules/desktop_capture/window_capturer_linux.cc -index ed03ba0..3bc6577 100644 ---- a/third_party/libwebrtc/modules/desktop_capture/window_capturer_linux.cc -+++ b/third_party/libwebrtc/modules/desktop_capture/window_capturer_linux.cc -@@ -14,7 +14,7 @@ - #include "modules/desktop_capture/desktop_capturer.h" - - #if defined(WEBRTC_USE_PIPEWIRE) --#include "modules/desktop_capture/linux/window_capturer_pipewire.h" -+#include "modules/desktop_capture/linux/base_capturer_pipewire.h" - #endif // defined(WEBRTC_USE_PIPEWIRE) - - #if defined(WEBRTC_USE_X11) -@@ -28,7 +28,7 @@ std::unique_ptr DesktopCapturer::CreateRawWindowCapturer( - const DesktopCaptureOptions& options) { - #if defined(WEBRTC_USE_PIPEWIRE) - if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { -- return BaseCapturerPipeWire::CreateRawWindowCapturer(options); -+ return std::make_unique(options); - } - #endif // defined(WEBRTC_USE_PIPEWIRE) - -diff --git a/third_party/moz.build b/third_party/moz.build -index 1941c11..f804531 100644 ---- a/third_party/moz.build -+++ b/third_party/moz.build -@@ -49,6 +49,12 @@ with Files("libwebrtc/**"): - with Files("pipewire/**"): - BUG_COMPONENT = ("Core", "WebRTC") - -+with Files("drm/**"): -+ BUG_COMPONENT = ("Core", "WebRTC") -+ -+with Files("gbm/**"): -+ BUG_COMPONENT = ("Core", "WebRTC") -+ - with Files('rlbox_wasm2c_sandbox/**'): - BUG_COMPONENT = ('Firefox Build System', 'General') - -diff --git a/third_party/pipewire/libpipewire/mozpipewire.cpp b/third_party/pipewire/libpipewire/mozpipewire.cpp -index 1ecfc31..fbeeb8e 100644 ---- a/third_party/pipewire/libpipewire/mozpipewire.cpp -+++ b/third_party/pipewire/libpipewire/mozpipewire.cpp -@@ -69,11 +69,13 @@ static int (*pw_stream_connect_fn)(struct pw_stream *stream, - enum pw_stream_flags flags, - const struct spa_pod **params, - uint32_t n_params); -+static int (*pw_stream_disconnect_fn)(struct pw_stream *stream); - static struct pw_buffer* (*pw_stream_dequeue_buffer_fn)(struct pw_stream *stream); - static void (*pw_stream_destroy_fn)(struct pw_stream *stream); - static struct pw_stream* (*pw_stream_new_fn)(struct pw_core *core, - const char *name, - struct pw_properties *props); -+ - static int (*pw_stream_queue_buffer_fn)(struct pw_stream *stream, - struct pw_buffer *buffer); - static int (*pw_stream_update_params_fn)(struct pw_stream *stream, -@@ -87,7 +89,10 @@ static int (*pw_thread_loop_start_fn)(struct pw_thread_loop *loop); - static void (*pw_thread_loop_stop_fn)(struct pw_thread_loop *loop); - static void (*pw_thread_loop_lock_fn)(struct pw_thread_loop *loop); - static void (*pw_thread_loop_unlock_fn)(struct pw_thread_loop *loop); -+static void (*pw_thread_loop_wait_fn)(struct pw_thread_loop *loop); -+static void (*pw_thread_loop_signal_fn)(struct pw_thread_loop *loop, bool wait_for_accept); - static struct pw_properties* (*pw_properties_new_string_fn)(const char *str); -+static const char* (*pw_get_library_version_fn)(); - - bool IsPwLibraryLoaded() { - static bool isLoaded = -@@ -99,6 +104,7 @@ bool IsPwLibraryLoaded() { - IS_FUNC_LOADED(pw_init_fn) && - IS_FUNC_LOADED(pw_stream_add_listener_fn) && - IS_FUNC_LOADED(pw_stream_connect_fn) && -+ IS_FUNC_LOADED(pw_stream_disconnect_fn) && - IS_FUNC_LOADED(pw_stream_dequeue_buffer_fn) && - IS_FUNC_LOADED(pw_stream_destroy_fn) && - IS_FUNC_LOADED(pw_stream_new_fn) && -@@ -111,7 +117,10 @@ bool IsPwLibraryLoaded() { - IS_FUNC_LOADED(pw_thread_loop_stop_fn) && - IS_FUNC_LOADED(pw_thread_loop_lock_fn) && - IS_FUNC_LOADED(pw_thread_loop_unlock_fn) && -- IS_FUNC_LOADED(pw_properties_new_string_fn)); -+ IS_FUNC_LOADED(pw_thread_loop_signal_fn) && -+ IS_FUNC_LOADED(pw_thread_loop_wait_fn) && -+ IS_FUNC_LOADED(pw_properties_new_string_fn) && -+ IS_FUNC_LOADED(pw_get_library_version_fn)); - - return isLoaded; - } -@@ -136,6 +145,7 @@ bool LoadPWLibrary() { - GET_FUNC(pw_init, pwLib); - GET_FUNC(pw_stream_add_listener, pwLib); - GET_FUNC(pw_stream_connect, pwLib); -+ GET_FUNC(pw_stream_disconnect, pwLib); - GET_FUNC(pw_stream_dequeue_buffer, pwLib); - GET_FUNC(pw_stream_destroy, pwLib); - GET_FUNC(pw_stream_new, pwLib); -@@ -148,7 +158,10 @@ bool LoadPWLibrary() { - GET_FUNC(pw_thread_loop_stop, pwLib); - GET_FUNC(pw_thread_loop_lock, pwLib); - GET_FUNC(pw_thread_loop_unlock, pwLib); -+ GET_FUNC(pw_thread_loop_signal, pwLib); -+ GET_FUNC(pw_thread_loop_wait, pwLib); - GET_FUNC(pw_properties_new_string, pwLib); -+ GET_FUNC(pw_get_library_version, pwLib); - } - - return IsPwLibraryLoaded(); -@@ -242,6 +255,15 @@ pw_stream_connect(struct pw_stream *stream, - params, n_params); - } - -+int -+pw_stream_disconnect(struct pw_stream *stream) -+{ -+ if (!LoadPWLibrary()) { -+ return 0; -+ } -+ return pw_stream_disconnect_fn(stream); -+} -+ - struct pw_buffer * - pw_stream_dequeue_buffer(struct pw_stream *stream) - { -@@ -356,6 +378,23 @@ pw_thread_loop_unlock(struct pw_thread_loop *loop) - return pw_thread_loop_unlock_fn(loop); - } - -+void -+pw_thread_loop_signal(struct pw_thread_loop *loop, bool wait_for_accept) -+{ -+ if (!LoadPWLibrary()) { -+ return; -+ } -+ return pw_thread_loop_signal_fn(loop, wait_for_accept); -+} -+ -+void -+pw_thread_loop_wait(struct pw_thread_loop *loop) -+{ -+ if (!LoadPWLibrary()) { -+ return; -+ } -+ return pw_thread_loop_wait_fn(loop); -+} - - struct pw_properties * - pw_properties_new_string(const char *str) -@@ -366,3 +405,12 @@ pw_properties_new_string(const char *str) - return pw_properties_new_string_fn(str); - } - -+const char* -+pw_get_library_version() -+{ -+ if (!LoadPWLibrary()) { -+ return nullptr; -+ } -+ return pw_get_library_version_fn(); -+} -+ -diff -up firefox-101.0/third_party/libwebrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build.libwebrtc-screen-cast-sync firefox-101.0/third_party/libwebrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build ---- firefox-101.0/third_party/libwebrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build.libwebrtc-screen-cast-sync 2022-05-27 01:17:03.000000000 +0200 -+++ firefox-101.0/third_party/libwebrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build 2022-06-02 12:48:28.316640076 +0200 -@@ -76,6 +76,8 @@ if CONFIG["OS_TARGET"] == "Darwin": - LOCAL_INCLUDES += [ - "/media/libyuv/libyuv/include/", - "/media/libyuv/libyuv/include/", -+ "/third_party/drm/", -+ "/third_party/gbm/", - "/third_party/pipewire/" - ] - -@@ -105,7 +107,8 @@ if CONFIG["OS_TARGET"] == "Linux": - LOCAL_INCLUDES += [ - "/media/libyuv/libyuv/include/", - "/media/libyuv/libyuv/include/", -- "/third_party/pipewire/", -+ "/third_party/drm/", -+ "/third_party/gbm/", - "/third_party/pipewire/" - ] - -@@ -115,12 +118,16 @@ if CONFIG["OS_TARGET"] == "Linux": - ] - - SOURCES += [ -- "/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc" -+ "/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/egl_dmabuf.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/scoped_glib.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/screencast_portal.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/shared_screencast_stream.cc" -+ - ] - - UNIFIED_SOURCES += [ -- "/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc", -- "/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc", - "/third_party/libwebrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc", - "/third_party/libwebrtc/modules/desktop_capture/screen_capturer_linux.cc", - "/third_party/libwebrtc/modules/desktop_capture/window_capturer_linux.cc" -@@ -156,15 +163,18 @@ if CONFIG["OS_TARGET"] == "OpenBSD": - ] - - SOURCES += [ -- "/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc" -+ "/third_party/libwebrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/egl_dmabuf.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_pipewire.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/scoped_glib.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/screencast_portal.cc", -+ "/third_party/libwebrtc/modules/desktop_capture/linux/shared_screencast_stream.cc" - ] - - UNIFIED_SOURCES += [ - "/third_party/libwebrtc/modules/desktop_capture/linux/mouse_cursor_monitor_x11.cc", -- "/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc", - "/third_party/libwebrtc/modules/desktop_capture/linux/screen_capturer_x11.cc", - "/third_party/libwebrtc/modules/desktop_capture/linux/shared_x_display.cc", -- "/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc", - "/third_party/libwebrtc/modules/desktop_capture/linux/window_capturer_x11.cc", - "/third_party/libwebrtc/modules/desktop_capture/linux/window_finder_x11.cc", - "/third_party/libwebrtc/modules/desktop_capture/linux/window_list_utils.cc", -@@ -206,6 +216,7 @@ if CONFIG["OS_TARGET"] == "WINNT": - LOCAL_INCLUDES += [ - "/media/libyuv/libyuv/include/", - "/media/libyuv/libyuv/include/", -+ "/third_party/drm/" - "/third_party/pipewire/" - ] - diff --git a/mozilla-1170092.patch b/mozilla-1170092.patch deleted file mode 100644 index d130dff..0000000 --- a/mozilla-1170092.patch +++ /dev/null @@ -1,99 +0,0 @@ -diff -up firefox-87.0/extensions/pref/autoconfig/src/nsReadConfig.cpp.1170092 firefox-87.0/extensions/pref/autoconfig/src/nsReadConfig.cpp ---- firefox-87.0/extensions/pref/autoconfig/src/nsReadConfig.cpp.1170092 2021-03-18 14:48:36.000000000 +0100 -+++ firefox-87.0/extensions/pref/autoconfig/src/nsReadConfig.cpp 2021-03-22 19:20:02.429310184 +0100 -@@ -249,8 +249,20 @@ nsresult nsReadConfig::openAndEvaluateJS - if (NS_FAILED(rv)) return rv; - - rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile); -- if (NS_FAILED(rv)) return rv; -+ if (NS_FAILED(rv)) { -+ // Look for cfg file in /etc//pref -+ rv = NS_GetSpecialDirectory(NS_APP_PREFS_SYSTEM_CONFIG_DIR, -+ getter_AddRefs(jsFile)); -+ NS_ENSURE_SUCCESS(rv, rv); -+ -+ rv = jsFile->AppendNative(nsLiteralCString("pref")); -+ NS_ENSURE_SUCCESS(rv, rv); -+ rv = jsFile->AppendNative(nsDependentCString(aFileName)); -+ NS_ENSURE_SUCCESS(rv, rv); - -+ rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile); -+ NS_ENSURE_SUCCESS(rv, rv); -+ } - } else { - nsAutoCString location("resource://gre/defaults/autoconfig/"); - location += aFileName; -diff -up firefox-87.0/modules/libpref/Preferences.cpp.1170092 firefox-87.0/modules/libpref/Preferences.cpp ---- firefox-87.0/modules/libpref/Preferences.cpp.1170092 2021-03-18 14:48:54.000000000 +0100 -+++ firefox-87.0/modules/libpref/Preferences.cpp 2021-03-22 19:20:02.429310184 +0100 -@@ -4499,6 +4499,9 @@ nsresult Preferences::InitInitialObjects - // - // Thus, in the omni.jar case, we always load app-specific default - // preferences from omni.jar, whether or not `$app == $gre`. -+ // -+ // At very end load configuration from system config location: -+ // - /etc/firefox/pref/*.js - - nsresult rv = NS_ERROR_FAILURE; - UniquePtr find; -diff -up firefox-87.0/toolkit/xre/nsXREDirProvider.cpp.1170092 firefox-87.0/toolkit/xre/nsXREDirProvider.cpp ---- firefox-87.0/toolkit/xre/nsXREDirProvider.cpp.1170092 2021-03-18 14:52:00.000000000 +0100 -+++ firefox-87.0/toolkit/xre/nsXREDirProvider.cpp 2021-03-22 19:37:56.574480347 +0100 -@@ -65,6 +65,7 @@ - #endif - #ifdef XP_UNIX - # include -+# include "nsIXULAppInfo.h" - #endif - #ifdef XP_IOS - # include "UIKitDirProvider.h" -@@ -552,6 +553,21 @@ nsXREDirProvider::GetFile(const char* aP - } - } - } -+ -+#if defined(XP_UNIX) -+ if (!strcmp(aProperty, NS_APP_PREFS_SYSTEM_CONFIG_DIR)) { -+ nsCString sysConfigDir = nsLiteralCString("/etc/"); -+ nsCOMPtr appInfo = do_GetService("@mozilla.org/xre/app-info;1"); -+ if (!appInfo) -+ return NS_ERROR_NOT_AVAILABLE; -+ nsCString appName; -+ appInfo->GetName(appName); -+ ToLowerCase(appName); -+ sysConfigDir.Append(appName); -+ return NS_NewNativeLocalFile(sysConfigDir, false, aFile); -+ } -+#endif -+ - if (NS_FAILED(rv) || !file) return NS_ERROR_FAILURE; - - if (ensureFilePermissions) { -@@ -874,6 +890,16 @@ nsresult nsXREDirProvider::GetFilesInter - } - #endif - -+ // Add /etc//pref/ directory if it exists -+ nsCOMPtr systemPrefDir; -+ rv = NS_GetSpecialDirectory(NS_APP_PREFS_SYSTEM_CONFIG_DIR, -+ getter_AddRefs(systemPrefDir)); -+ if (NS_SUCCEEDED(rv)) { -+ rv = systemPrefDir->AppendNative(nsLiteralCString("pref")); -+ if (NS_SUCCEEDED(rv)) -+ directories.AppendObject(systemPrefDir); -+ } -+ - rv = NS_NewArrayEnumerator(aResult, directories, NS_GET_IID(nsIFile)); - } else if (!strcmp(aProperty, NS_APP_CHROME_DIR_LIST)) { - // NS_APP_CHROME_DIR_LIST is only used to get default (native) icons -diff -up firefox-87.0/xpcom/io/nsAppDirectoryServiceDefs.h.1170092 firefox-87.0/xpcom/io/nsAppDirectoryServiceDefs.h ---- firefox-87.0/xpcom/io/nsAppDirectoryServiceDefs.h.1170092 2021-03-18 14:51:58.000000000 +0100 -+++ firefox-87.0/xpcom/io/nsAppDirectoryServiceDefs.h 2021-03-22 19:20:02.430310213 +0100 -@@ -59,6 +59,7 @@ - #define NS_APP_PREFS_DEFAULTS_DIR_LIST "PrefDL" - #define NS_APP_PREFS_OVERRIDE_DIR \ - "PrefDOverride" // Directory for per-profile defaults -+#define NS_APP_PREFS_SYSTEM_CONFIG_DIR "PrefSysConf" // Directory with system-wide configuration - - #define NS_APP_USER_PROFILE_50_DIR "ProfD" - #define NS_APP_USER_PROFILE_LOCAL_50_DIR "ProfLD" diff --git a/mozilla-1196777.patch b/mozilla-1196777.patch index 864741e..ac405c6 100644 --- a/mozilla-1196777.patch +++ b/mozilla-1196777.patch @@ -1,13 +1,12 @@ -diff -up firefox-100.0/widget/gtk/nsWindow.cpp.1196777 firefox-100.0/widget/gtk/nsWindow.cpp ---- firefox-100.0/widget/gtk/nsWindow.cpp.1196777 2022-05-02 11:29:06.763325015 +0200 -+++ firefox-100.0/widget/gtk/nsWindow.cpp 2022-05-02 11:30:49.100717334 +0200 -@@ -163,7 +163,8 @@ const gint kEvents = GDK_TOUCHPAD_GESTUR - GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - GDK_SMOOTH_SCROLL_MASK | GDK_TOUCH_MASK | GDK_SCROLL_MASK | -- GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK; -+ GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK | -+ GDK_FOCUS_CHANGE_MASK; +diff -up firefox-133.0/widget/gtk/nsWindow.cpp.1196777 firefox-133.0/widget/gtk/nsWindow.cpp +--- firefox-133.0/widget/gtk/nsWindow.cpp.1196777 2024-11-22 09:32:52.293470407 +0100 ++++ firefox-133.0/widget/gtk/nsWindow.cpp 2024-11-22 10:21:54.996441520 +0100 +@@ -191,7 +191,7 @@ constexpr gint kEvents = + GDK_VISIBILITY_NOTIFY_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_SMOOTH_SCROLL_MASK | + GDK_TOUCH_MASK | GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | +- GDK_PROPERTY_CHANGE_MASK; ++ GDK_PROPERTY_CHANGE_MASK | GDK_FOCUS_CHANGE_MASK; /* utility functions */ static bool is_mouse_in_window(GdkWindow* aWindow, gdouble aMouseX, diff --git a/mozilla-1516803.patch b/mozilla-1516803.patch index 5053e51..30d1fdf 100644 --- a/mozilla-1516803.patch +++ b/mozilla-1516803.patch @@ -1,6 +1,6 @@ diff -up firefox-84.0/security/sandbox/linux/moz.build.1516803 firefox-84.0/security/sandbox/linux/moz.build ---- firefox-84.0/security/sandbox/linux/moz.build.1516803 2020-12-10 16:17:55.425139545 +0100 -+++ firefox-84.0/security/sandbox/linux/moz.build 2020-12-10 16:29:21.945860841 +0100 +--- firefox-84.0/security/sandbox/linux/moz.build.1516803 2020-12-10 16:17:55.425139545 +0100 ++++ firefox-84.0/security/sandbox/linux/moz.build 2020-12-10 16:29:21.945860841 +0100 @@ -114,9 +114,8 @@ if CONFIG["CC_TYPE"] in ("clang", "gcc") # gcc lto likes to put the top level asm in syscall.cc in a different partition # from the function using it which breaks the build. Work around that by diff --git a/mozilla-1640982.patch b/mozilla-1640982.patch deleted file mode 100644 index b63ba3b..0000000 --- a/mozilla-1640982.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/config/makefiles/rust.mk b/config/makefiles/rust.mk ---- a/config/makefiles/rust.mk -+++ b/config/makefiles/rust.mk -@@ -61,7 +61,11 @@ - # Enable link-time optimization for release builds, but not when linking - # gkrust_gtest. - ifeq (,$(findstring gkrust_gtest,$(RUST_LIBRARY_FILE))) -+# Pass -Clto for older versions of rust, and CARGO_PROFILE_RELEASE_LTO=true -+# for newer ones that support it. Combining the latter with -Clto works, so -+# set both everywhere. - cargo_rustc_flags += -Clto -+export CARGO_PROFILE_RELEASE_LTO=true - endif - endif - endif - diff --git a/mozilla-1663844.patch b/mozilla-1663844.patch deleted file mode 100644 index d356425..0000000 --- a/mozilla-1663844.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff -up firefox-101.0/dom/media/gmp/GMPSharedMemManager.h.1663844 firefox-101.0/dom/media/gmp/GMPSharedMemManager.h ---- firefox-101.0/dom/media/gmp/GMPSharedMemManager.h.1663844 2022-05-27 01:16:53.000000000 +0200 -+++ firefox-101.0/dom/media/gmp/GMPSharedMemManager.h 2022-05-30 21:15:20.989993419 +0200 -@@ -27,7 +27,7 @@ class GMPSharedMem { - // returned to the parent pool (which is not included). If more than - // this are needed, we presume the client has either crashed or hung - // (perhaps temporarily). -- static const uint32_t kGMPBufLimit = 20; -+ static const uint32_t kGMPBufLimit = 40; - - GMPSharedMem() { - for (size_t i = 0; i < sizeof(mGmpAllocated) / sizeof(mGmpAllocated[0]); -diff -up firefox-101.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp.1663844 firefox-101.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp ---- firefox-101.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp.1663844 2022-05-30 21:15:20.989993419 +0200 -+++ firefox-101.0/dom/media/platforms/agnostic/gmp/GMPDecoderModule.cpp 2022-05-30 21:24:16.615282035 +0200 -@@ -66,6 +66,7 @@ media::DecodeSupportSet GMPDecoderModule - - nsCString api = nsLiteralCString(CHROMIUM_CDM_API); - -+ // TODO: Do we enable it here? - if (MP4Decoder::IsH264(aMimeType)) { - isSupported = HaveGMPFor(api, {"h264"_ns, aGMP.value()}); - } else if (VPXDecoder::IsVP9(aMimeType)) { -diff -up firefox-101.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp.1663844 firefox-101.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp ---- firefox-101.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp.1663844 2022-05-27 01:16:53.000000000 +0200 -+++ firefox-101.0/dom/media/platforms/agnostic/gmp/GMPVideoDecoder.cpp 2022-05-30 21:15:20.989993419 +0200 -@@ -70,6 +70,8 @@ void GMPVideoDecoder::Decoded(GMPVideoi4 - RefPtr self = this; - if (v) { - mDecodedData.AppendElement(std::move(v)); -+ mDecodePromise.ResolveIfExists(std::move(mDecodedData), __func__); -+ mDecodedData = DecodedData(); - } else { - mDecodedData.Clear(); - mDecodePromise.RejectIfExists( diff --git a/mozilla-1667096.patch b/mozilla-1667096.patch index d2f2bf7..d26be4d 100644 --- a/mozilla-1667096.patch +++ b/mozilla-1667096.patch @@ -1,7 +1,7 @@ -diff -up firefox-98.0/media/ffvpx/libavcodec/codec_list.c.1667096 firefox-98.0/media/ffvpx/libavcodec/codec_list.c ---- firefox-98.0/media/ffvpx/libavcodec/codec_list.c.1667096 2022-03-01 11:15:54.962398882 +0100 -+++ firefox-98.0/media/ffvpx/libavcodec/codec_list.c 2022-03-01 11:17:46.605000755 +0100 -@@ -11,6 +11,9 @@ static const AVCodec * const codec_list[ +diff -up firefox-127.0/media/ffvpx/libavcodec/codec_list.c.1667096 firefox-127.0/media/ffvpx/libavcodec/codec_list.c +--- firefox-127.0/media/ffvpx/libavcodec/codec_list.c.1667096 2024-06-06 23:33:57.000000000 +0200 ++++ firefox-127.0/media/ffvpx/libavcodec/codec_list.c 2024-06-10 12:42:39.353913204 +0200 +@@ -11,6 +11,9 @@ static const FFCodec * const codec_list[ #if CONFIG_MP3_DECODER &ff_mp3_decoder, #endif @@ -11,10 +11,10 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/codec_list.c.1667096 firefox-98.0/m #if CONFIG_LIBDAV1D &ff_libdav1d_decoder, #endif -diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c ---- firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 2022-03-01 11:15:54.963398914 +0100 -+++ firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c 2022-03-01 11:15:54.963398914 +0100 -@@ -0,0 +1,409 @@ +diff -up firefox-127.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-127.0/media/ffvpx/libavcodec/libfdk-aacdec.c +--- firefox-127.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 2024-06-10 12:42:39.354913201 +0200 ++++ firefox-127.0/media/ffvpx/libavcodec/libfdk-aacdec.c 2024-06-10 16:28:30.332367814 +0200 +@@ -0,0 +1,498 @@ +/* + * AAC decoder wrapper + * Copyright (c) 2012 Martin Storsjo @@ -39,8 +39,10 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. +#include "libavutil/channel_layout.h" +#include "libavutil/common.h" +#include "libavutil/opt.h" ++#include "libavutil/mem.h" +#include "avcodec.h" -+#include "internal.h" ++#include "codec_internal.h" ++#include "decode.h" + +#ifdef AACDECODER_LIB_VL0 +#define FDKDEC_VER_AT_LEAST(vl0, vl1) \ @@ -73,7 +75,14 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + int drc_heavy; + int drc_effect; + int drc_cut; ++ int album_mode; + int level_limit; ++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 ++ int output_delay_set; ++ int flush_samples; ++ int delay_samples; ++#endif ++ AVChannelLayout downmix_layout; +} FDKAACDecContext; + + @@ -92,17 +101,23 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + OFFSET(drc_boost), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL }, + { "drc_cut", "Dynamic Range Control: attenuation factor, where [0] is none and [127] is max compression", + OFFSET(drc_cut), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL }, -+ { "drc_level", "Dynamic Range Control: reference level, quantized to 0.25dB steps where [0] is 0dB and [127] is -31.75dB", -+ OFFSET(drc_level), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 127, AD, NULL }, ++ { "drc_level", "Dynamic Range Control: reference level, quantized to 0.25dB steps where [0] is 0dB and [127] is -31.75dB, -1 for auto, and -2 for disabled", ++ OFFSET(drc_level), AV_OPT_TYPE_INT, { .i64 = -1}, -2, 127, AD, NULL }, + { "drc_heavy", "Dynamic Range Control: heavy compression, where [1] is on (RF mode) and [0] is off", + OFFSET(drc_heavy), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, AD, NULL }, +#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 -+ { "level_limit", "Signal level limiting", OFFSET(level_limit), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 1, AD }, ++ { "level_limit", "Signal level limiting", ++ OFFSET(level_limit), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, AD }, +#endif +#if FDKDEC_VER_AT_LEAST(3, 0) // 3.0.0 + { "drc_effect","Dynamic Range Control: effect type, where e.g. [0] is none and [6] is general", + OFFSET(drc_effect), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 8, AD, NULL }, +#endif ++#if FDKDEC_VER_AT_LEAST(3, 1) // 3.1.0 ++ { "album_mode","Dynamic Range Control: album mode, where [0] is off and [1] is on", ++ OFFSET(album_mode), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, AD, NULL }, ++#endif ++ { "downmix", "Request a specific channel layout from the decoder", OFFSET(downmix_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, .flags = AD }, + { NULL } +}; + @@ -132,6 +147,14 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + } + avctx->sample_rate = info->sampleRate; + avctx->frame_size = info->frameSize; ++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 ++ if (!s->output_delay_set && info->outputDelay) { ++ // Set this only once. ++ s->flush_samples = info->outputDelay; ++ s->delay_samples = info->outputDelay; ++ s->output_delay_set = 1; ++ } ++#endif + + for (i = 0; i < info->numChannels; i++) { + AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i]; @@ -209,17 +232,15 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + ch_error = 1; + } + } -+ if (!ch_error && -+ av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) { ++ ++ av_channel_layout_uninit(&avctx->ch_layout); ++ av_channel_layout_from_mask(&avctx->ch_layout, ch_layout); ++ if (!ch_error && avctx->ch_layout.nb_channels != info->numChannels) { + av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n"); + ch_error = 1; + } + if (ch_error) -+ avctx->channel_layout = 0; -+ else -+ avctx->channel_layout = ch_layout; -+ -+ avctx->channels = info->numChannels; ++ avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + + return 0; +} @@ -261,11 +282,19 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + return AVERROR_UNKNOWN; + } + -+ if (avctx->request_channel_layout > 0 && -+ avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) { ++#if FF_API_OLD_CHANNEL_LAYOUT ++FF_DISABLE_DEPRECATION_WARNINGS ++ if (avctx->request_channel_layout) { ++ av_channel_layout_uninit(&s->downmix_layout); ++ av_channel_layout_from_mask(&s->downmix_layout, avctx->request_channel_layout); ++ } ++FF_ENABLE_DEPRECATION_WARNINGS ++#endif ++ if (s->downmix_layout.nb_channels > 0 && ++ s->downmix_layout.order != AV_CHANNEL_ORDER_NATIVE) { + int downmix_channels = -1; + -+ switch (avctx->request_channel_layout) { ++ switch (s->downmix_layout.u.mask) { + case AV_CH_LAYOUT_STEREO: + case AV_CH_LAYOUT_STEREO_DOWNMIX: + downmix_channels = 2; @@ -274,7 +303,7 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + downmix_channels = 1; + break; + default: -+ av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n"); ++ av_log(avctx, AV_LOG_WARNING, "Invalid downmix option\n"); + break; + } + @@ -311,6 +340,12 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + } + + if (s->drc_level != -1) { ++ // This option defaults to -1, i.e. not calling ++ // aacDecoder_SetParam(AAC_DRC_REFERENCE_LEVEL) at all, which defaults ++ // to the level from DRC metadata, if available. The user can set ++ // -drc_level -2, which calls aacDecoder_SetParam( ++ // AAC_DRC_REFERENCE_LEVEL) with a negative value, which then ++ // explicitly disables the feature. + if (aacDecoder_SetParam(s->handle, AAC_DRC_REFERENCE_LEVEL, s->drc_level) != AAC_DEC_OK) { + av_log(avctx, AV_LOG_ERROR, "Unable to set DRC reference level in the decoder\n"); + return AVERROR_UNKNOWN; @@ -325,6 +360,7 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + } + +#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 ++ // Setting this parameter to -1 enables the auto behaviour in the library. + if (aacDecoder_SetParam(s->handle, AAC_PCM_LIMITER_ENABLE, s->level_limit) != AAC_DEC_OK) { + av_log(avctx, AV_LOG_ERROR, "Unable to set in signal level limiting in the decoder\n"); + return AVERROR_UNKNOWN; @@ -340,6 +376,15 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + } +#endif + ++#if FDKDEC_VER_AT_LEAST(3, 1) // 3.1.0 ++ if (s->album_mode != -1) { ++ if (aacDecoder_SetParam(s->handle, AAC_UNIDRC_ALBUM_MODE, s->album_mode) != AAC_DEC_OK) { ++ av_log(avctx, AV_LOG_ERROR, "Unable to set album mode in the decoder\n"); ++ return AVERROR_UNKNOWN; ++ } ++ } ++#endif ++ + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + s->decoder_buffer_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS; @@ -350,22 +395,38 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + return 0; +} + -+static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data, ++static int fdk_aac_decode_frame(AVCodecContext *avctx, AVFrame *frame, + int *got_frame_ptr, AVPacket *avpkt) +{ + FDKAACDecContext *s = avctx->priv_data; -+ AVFrame *frame = data; + int ret; + AAC_DECODER_ERROR err; + UINT valid = avpkt->size; ++ UINT flags = 0; ++ int input_offset = 0; + -+ err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid); -+ if (err != AAC_DEC_OK) { -+ av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err); -+ return AVERROR_INVALIDDATA; ++ if (avpkt->size) { ++ err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid); ++ if (err != AAC_DEC_OK) { ++ av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err); ++ return AVERROR_INVALIDDATA; ++ } ++ } else { ++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 ++ /* Handle decoder draining */ ++ if (s->flush_samples > 0) { ++ flags |= AACDEC_FLUSH; ++ } else { ++ return AVERROR_EOF; ++ } ++#else ++ return AVERROR_EOF; ++#endif + } + -+ err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, s->decoder_buffer_size / sizeof(INT_PCM), 0); ++ err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, ++ s->decoder_buffer_size / sizeof(INT_PCM), ++ flags); + if (err == AAC_DEC_NOT_ENOUGH_BITS) { + ret = avpkt->size - valid; + goto end; @@ -381,11 +442,36 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + goto end; + frame->nb_samples = avctx->frame_size; + ++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 ++ if (flags & AACDEC_FLUSH) { ++ // Only return the right amount of samples at the end; if calling the ++ // decoder with AACDEC_FLUSH, it will keep returning frames indefinitely. ++ frame->nb_samples = FFMIN(s->flush_samples, frame->nb_samples); ++ av_log(s, AV_LOG_DEBUG, "Returning %d/%d delayed samples.\n", ++ frame->nb_samples, s->flush_samples); ++ s->flush_samples -= frame->nb_samples; ++ } else { ++ // Trim off samples from the start to compensate for extra decoder ++ // delay. We could also just adjust the pts, but this avoids ++ // including the extra samples in the output altogether. ++ if (s->delay_samples) { ++ int drop_samples = FFMIN(s->delay_samples, frame->nb_samples); ++ av_log(s, AV_LOG_DEBUG, "Dropping %d/%d delayed samples.\n", ++ drop_samples, s->delay_samples); ++ s->delay_samples -= drop_samples; ++ frame->nb_samples -= drop_samples; ++ input_offset = drop_samples * avctx->ch_layout.nb_channels; ++ if (frame->nb_samples <= 0) ++ return 0; ++ } ++ } ++#endif ++ + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + goto end; + -+ memcpy(frame->extended_data[0], s->decoder_buffer, -+ avctx->channels * avctx->frame_size * ++ memcpy(frame->extended_data[0], s->decoder_buffer + input_offset, ++ avctx->ch_layout.nb_channels * frame->nb_samples * + av_get_bytes_per_sample(avctx->sample_fmt)); + + *got_frame_ptr = 1; @@ -408,28 +494,31 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/libfdk-aacdec.c.1667096 firefox-98. + av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n"); +} + -+AVCodec ff_libfdk_aac_decoder = { -+ .name = "libfdk_aac", -+ .long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"), -+ .type = AVMEDIA_TYPE_AUDIO, -+ .id = AV_CODEC_ID_AAC, ++const FFCodec ff_libfdk_aac_decoder = { ++ .p.name = "libfdk_aac", ++ CODEC_LONG_NAME("Fraunhofer FDK AAC"), ++ .p.type = AVMEDIA_TYPE_AUDIO, ++ .p.id = AV_CODEC_ID_AAC, + .priv_data_size = sizeof(FDKAACDecContext), + .init = fdk_aac_decode_init, -+ .decode = fdk_aac_decode_frame, ++ FF_CODEC_DECODE_CB(fdk_aac_decode_frame), + .close = fdk_aac_decode_close, + .flush = fdk_aac_decode_flush, -+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF, -+ .priv_class = &fdk_aac_dec_class, -+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | -+ FF_CODEC_CAP_INIT_CLEANUP, -+ .wrapper_name = "libfdk", ++ .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF ++#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 ++ | AV_CODEC_CAP_DELAY ++#endif ++ , ++ .p.priv_class = &fdk_aac_dec_class, ++ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, ++ .p.wrapper_name = "libfdk", +}; -diff -up firefox-98.0/media/ffvpx/libavcodec/moz.build.1667096 firefox-98.0/media/ffvpx/libavcodec/moz.build ---- firefox-98.0/media/ffvpx/libavcodec/moz.build.1667096 2022-03-01 11:15:54.963398914 +0100 -+++ firefox-98.0/media/ffvpx/libavcodec/moz.build 2022-03-01 11:18:00.646453768 +0100 -@@ -123,6 +123,12 @@ if CONFIG['MOZ_LIBAV_FFT']: - 'avfft.c', - ] +diff -up firefox-127.0/media/ffvpx/libavcodec/moz.build.1667096 firefox-127.0/media/ffvpx/libavcodec/moz.build +--- firefox-127.0/media/ffvpx/libavcodec/moz.build.1667096 2024-06-06 23:33:58.000000000 +0200 ++++ firefox-127.0/media/ffvpx/libavcodec/moz.build 2024-06-10 12:42:39.354913201 +0200 +@@ -151,6 +151,12 @@ else: + CXXFLAGS += CONFIG["MOZ_LIBVPX_CFLAGS"] + OS_LIBS += CONFIG["MOZ_LIBVPX_LIBS"] +if CONFIG['MOZ_FDK_AAC']: + SOURCES += [ @@ -440,10 +529,10 @@ diff -up firefox-98.0/media/ffvpx/libavcodec/moz.build.1667096 firefox-98.0/medi SYMBOLS_FILE = 'avcodec.symbols' NoVisibilityFlags() -diff -up firefox-98.0/toolkit/moz.configure.1667096 firefox-98.0/toolkit/moz.configure ---- firefox-98.0/toolkit/moz.configure.1667096 2022-03-01 11:15:54.881396269 +0100 -+++ firefox-98.0/toolkit/moz.configure 2022-03-01 11:15:54.963398914 +0100 -@@ -1950,6 +1950,15 @@ with only_when(compile_environment): +diff -up firefox-127.0/toolkit/moz.configure.1667096 firefox-127.0/toolkit/moz.configure +--- firefox-127.0/toolkit/moz.configure.1667096 2024-06-10 12:42:39.312913316 +0200 ++++ firefox-127.0/toolkit/moz.configure 2024-06-10 12:42:39.355913199 +0200 +@@ -2412,6 +2412,15 @@ with only_when(compile_environment): set_config("MOZ_SYSTEM_PNG", True, when="--with-system-png") diff --git a/mozilla-1669639.patch b/mozilla-1669639.patch deleted file mode 100644 index cd04aab..0000000 --- a/mozilla-1669639.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- firefox-81.0.1/build/mach_initialize.py.old 2020-10-06 14:16:06.212974910 +0200 -+++ firefox-81.0.1/build/mach_initialize.py 2020-10-06 14:19:03.313179557 +0200 -@@ -507,7 +507,10 @@ class ImportHook(object): - # doesn't happen or because it doesn't matter). - if not os.path.exists(module.__file__[:-1]): - if os.path.exists(module.__file__): -- os.remove(module.__file__) -+ try: -+ os.remove(module.__file__) -+ except: -+ pass - del sys.modules[module.__name__] - module = self(name, globals, locals, fromlist, level) - diff --git a/mozilla-1670333.patch b/mozilla-1670333.patch deleted file mode 100644 index 1c5c476..0000000 --- a/mozilla-1670333.patch +++ /dev/null @@ -1,68 +0,0 @@ -diff -up firefox-99.0/dom/media/mp4/MP4Demuxer.cpp.1670333 firefox-99.0/dom/media/mp4/MP4Demuxer.cpp ---- firefox-99.0/dom/media/mp4/MP4Demuxer.cpp.1670333 2022-03-31 01:24:44.000000000 +0200 -+++ firefox-99.0/dom/media/mp4/MP4Demuxer.cpp 2022-04-04 09:58:35.606351546 +0200 -@@ -31,6 +31,8 @@ mozilla::LogModule* GetDemuxerLog() { re - DDMOZ_LOG(gMediaDemuxerLog, mozilla::LogLevel::Debug, "::%s: " arg, \ - __func__, ##__VA_ARGS__) - -+extern bool gUseKeyframeFromContainer; -+ - namespace mozilla { - - DDLoggedTypeDeclNameAndBase(MP4TrackDemuxer, MediaTrackDemuxer); -@@ -394,6 +396,12 @@ already_AddRefed MP4TrackD - [[fallthrough]]; - case H264::FrameType::OTHER: { - bool keyframe = type == H264::FrameType::I_FRAME; -+ if (gUseKeyframeFromContainer) { -+ if (sample->mKeyframe && sample->mKeyframe != keyframe) { -+ sample->mKeyframe = keyframe; -+ } -+ break; -+ } - if (sample->mKeyframe != keyframe) { - NS_WARNING(nsPrintfCString("Frame incorrectly marked as %skeyframe " - "@ pts:%" PRId64 " dur:%" PRId64 -diff -up firefox-99.0/dom/media/platforms/PDMFactory.cpp.1670333 firefox-99.0/dom/media/platforms/PDMFactory.cpp ---- firefox-99.0/dom/media/platforms/PDMFactory.cpp.1670333 2022-03-31 01:24:44.000000000 +0200 -+++ firefox-99.0/dom/media/platforms/PDMFactory.cpp 2022-04-04 10:09:57.383419125 +0200 -@@ -58,6 +58,8 @@ - - #include - -+bool gUseKeyframeFromContainer = false; -+ - namespace mozilla { - - #define PDM_INIT_LOG(msg, ...) \ -@@ -495,7 +497,7 @@ void PDMFactory::CreateRddPDMs() { - #ifdef MOZ_FFMPEG - if (StaticPrefs::media_ffmpeg_enabled() && - StaticPrefs::media_rdd_ffmpeg_enabled() && -- !CreateAndStartupPDM()) { -+ !(mFFmpegUsed = CreateAndStartupPDM())) { - mFailureFlags += GetFailureFlagBasedOnFFmpegStatus( - FFmpegRuntimeLinker::LinkStatusCode()); - } -@@ -602,8 +604,9 @@ void PDMFactory::CreateDefaultPDMs() { - - CreateAndStartupPDM(); - -- if (StaticPrefs::media_gmp_decoder_enabled() && -+ if (StaticPrefs::media_gmp_decoder_enabled() && !mFFmpegUsed && - !CreateAndStartupPDM()) { -+ gUseKeyframeFromContainer = true; - mFailureFlags += DecoderDoctorDiagnostics::Flags::GMPPDMFailedToStartup; - } - } -diff -up firefox-99.0/dom/media/platforms/PDMFactory.h.1670333 firefox-99.0/dom/media/platforms/PDMFactory.h ---- firefox-99.0/dom/media/platforms/PDMFactory.h.1670333 2022-03-31 01:24:44.000000000 +0200 -+++ firefox-99.0/dom/media/platforms/PDMFactory.h 2022-04-04 09:58:35.606351546 +0200 -@@ -121,6 +121,7 @@ class PDMFactory final { - RefPtr mNullPDM; - - DecoderDoctorDiagnostics::FlagsSet mFailureFlags; -+ bool mFFmpegUsed = false; - - friend class RemoteVideoDecoderParent; - static void EnsureInit(); diff --git a/mozilla-1672139.patch b/mozilla-1672139.patch deleted file mode 100644 index efd40cb..0000000 --- a/mozilla-1672139.patch +++ /dev/null @@ -1,91 +0,0 @@ -diff --git a/gfx/layers/ipc/CompositorBridgeParent.cpp b/gfx/layers/ipc/CompositorBridgeParent.cpp ---- a/gfx/layers/ipc/CompositorBridgeParent.cpp -+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp -@@ -2376,30 +2376,28 @@ - if (mWrBridge->PipelineId() == aPipelineId) { - mWrBridge->RemoveEpochDataPriorTo(aEpoch); - -- if (!mPaused) { -- if (mIsForcedFirstPaint) { -- uiController->NotifyFirstPaint(); -- mIsForcedFirstPaint = false; -- } -- -- std::pair key(aPipelineId, aEpoch); -- nsTArray payload = -- mWrBridge->TakePendingScrollPayload(key); -- if (!payload.IsEmpty()) { -- RecordCompositionPayloadsPresented(payload); -- } -- -- TransactionId transactionId = mWrBridge->FlushTransactionIdsForEpoch( -- aEpoch, aCompositeStartId, aCompositeStart, aRenderStart, -- aCompositeEnd, uiController); -- Unused << SendDidComposite(LayersId{0}, transactionId, aCompositeStart, -- aCompositeEnd); -- -- nsTArray notifications; -- mWrBridge->ExtractImageCompositeNotifications(¬ifications); -- if (!notifications.IsEmpty()) { -- Unused << ImageBridgeParent::NotifyImageComposites(notifications); -- } -+ if (mIsForcedFirstPaint) { -+ uiController->NotifyFirstPaint(); -+ mIsForcedFirstPaint = false; -+ } -+ -+ std::pair key(aPipelineId, aEpoch); -+ nsTArray payload = -+ mWrBridge->TakePendingScrollPayload(key); -+ if (!payload.IsEmpty()) { -+ RecordCompositionPayloadsPresented(payload); -+ } -+ -+ TransactionId transactionId = mWrBridge->FlushTransactionIdsForEpoch( -+ aEpoch, aCompositeStartId, aCompositeStart, aRenderStart, aCompositeEnd, -+ uiController); -+ Unused << SendDidComposite(LayersId{0}, transactionId, aCompositeStart, -+ aCompositeEnd); -+ -+ nsTArray notifications; -+ mWrBridge->ExtractImageCompositeNotifications(¬ifications); -+ if (!notifications.IsEmpty()) { -+ Unused << ImageBridgeParent::NotifyImageComposites(notifications); - } - return; - } -@@ -2408,21 +2406,19 @@ - if (wrBridge && wrBridge->GetCompositorBridge()) { - MOZ_ASSERT(!wrBridge->IsRootWebRenderBridgeParent()); - wrBridge->RemoveEpochDataPriorTo(aEpoch); -- if (!mPaused) { -- std::pair key(aPipelineId, aEpoch); -- nsTArray payload = -- wrBridge->TakePendingScrollPayload(key); -- if (!payload.IsEmpty()) { -- RecordCompositionPayloadsPresented(payload); -- } -- -- TransactionId transactionId = wrBridge->FlushTransactionIdsForEpoch( -- aEpoch, aCompositeStartId, aCompositeStart, aRenderStart, -- aCompositeEnd, uiController, aStats, &stats); -- Unused << wrBridge->GetCompositorBridge()->SendDidComposite( -- wrBridge->GetLayersId(), transactionId, aCompositeStart, -- aCompositeEnd); -+ -+ std::pair key(aPipelineId, aEpoch); -+ nsTArray payload = -+ wrBridge->TakePendingScrollPayload(key); -+ if (!payload.IsEmpty()) { -+ RecordCompositionPayloadsPresented(payload); - } -+ -+ TransactionId transactionId = wrBridge->FlushTransactionIdsForEpoch( -+ aEpoch, aCompositeStartId, aCompositeStart, aRenderStart, aCompositeEnd, -+ uiController, aStats, &stats); -+ Unused << wrBridge->GetCompositorBridge()->SendDidComposite( -+ wrBridge->GetLayersId(), transactionId, aCompositeStart, aCompositeEnd); - } - - if (!stats.IsEmpty()) { - diff --git a/mozilla-1673313.patch b/mozilla-1673313.patch deleted file mode 100644 index 549243b..0000000 --- a/mozilla-1673313.patch +++ /dev/null @@ -1,351 +0,0 @@ -changeset: 556172:143b4ca96ec9 -tag: tip -parent: 556169:61c35792ca70 -user: stransky -date: Mon Oct 26 12:15:49 2020 +0100 -files: widget/gtk/WindowSurfaceWayland.cpp widget/gtk/WindowSurfaceWayland.h -description: -Bug 1673313 [Wayland] Don't fail when Shm allocation fails, r?jhorak - -- Make WaylandAllocateShmMemory() fallible. -- Implement WaylandReAllocateShmMemory() to re-allocate Shm pool. -- Remove WaylandShmPool::Resize() and use WaylandShmPool::Create() only. -- Implement and use WaylandShmPool::Release(). -- Make WindowSurfaceWayland::CreateWaylandBuffer() as fallible. - -Differential Revision: https://phabricator.services.mozilla.com/D94735 - - -diff --git a/widget/gtk/WindowSurfaceWayland.cpp b/widget/gtk/WindowSurfaceWayland.cpp ---- a/widget/gtk/WindowSurfaceWayland.cpp -+++ b/widget/gtk/WindowSurfaceWayland.cpp -@@ -209,14 +209,23 @@ RefPtr WindowBackBuffe - } - - static int WaylandAllocateShmMemory(int aSize) { -- static int counter = 0; -- nsPrintfCString shmName("/wayland.mozilla.ipc.%d", counter++); -- int fd = shm_open(shmName.get(), O_CREAT | O_RDWR | O_EXCL, 0600); -- if (fd >= 0) { -- shm_unlink(shmName.get()); -- } else { -- printf_stderr("Unable to SHM memory segment\n"); -- MOZ_CRASH(); -+ int fd = -1; -+ do { -+ static int counter = 0; -+ nsPrintfCString shmName("/wayland.mozilla.ipc.%d", counter++); -+ fd = shm_open(shmName.get(), O_CREAT | O_RDWR | O_EXCL, 0600); -+ if (fd >= 0) { -+ // We don't want to use leaked file -+ if (shm_unlink(shmName.get()) != 0) { -+ NS_WARNING("shm_unlink failed"); -+ return -1; -+ } -+ } -+ } while (fd < 0 && errno == EEXIST); -+ -+ if (fd < 0) { -+ NS_WARNING(nsPrintfCString("shm_open failed: %s", strerror(errno)).get()); -+ return -1; - } - - int ret = 0; -@@ -225,59 +234,103 @@ static int WaylandAllocateShmMemory(int - ret = posix_fallocate(fd, 0, aSize); - } while (ret == EINTR); - if (ret != 0) { -+ NS_WARNING( -+ nsPrintfCString("posix_fallocate() fails to allocate shm memory: %s", -+ strerror(ret)) -+ .get()); - close(fd); -- MOZ_CRASH("posix_fallocate() fails to allocate shm memory"); -+ return -1; - } - #else - do { - ret = ftruncate(fd, aSize); - } while (ret < 0 && errno == EINTR); - if (ret < 0) { -+ NS_WARNING(nsPrintfCString("ftruncate() fails to allocate shm memory: %s", -+ strerror(ret)) -+ .get()); - close(fd); -- MOZ_CRASH("ftruncate() fails to allocate shm memory"); -+ fd = -1; - } - #endif - - return fd; - } - --WaylandShmPool::WaylandShmPool(RefPtr aWaylandDisplay, -- int aSize) -- : mAllocatedSize(aSize) { -- mShmPoolFd = WaylandAllocateShmMemory(mAllocatedSize); -- mImageData = mmap(nullptr, mAllocatedSize, PROT_READ | PROT_WRITE, MAP_SHARED, -- mShmPoolFd, 0); -- MOZ_RELEASE_ASSERT(mImageData != MAP_FAILED, -- "Unable to map drawing surface!"); -+static bool WaylandReAllocateShmMemory(int aFd, int aSize) { -+ if (ftruncate(aFd, aSize) < 0) { -+ return false; -+ } -+#ifdef HAVE_POSIX_FALLOCATE -+ do { -+ errno = posix_fallocate(aFd, 0, aSize); -+ } while (errno == EINTR); -+ if (errno != 0) { -+ return false; -+ } -+#endif -+ return true; -+} - -- mShmPool = -- wl_shm_create_pool(aWaylandDisplay->GetShm(), mShmPoolFd, mAllocatedSize); -+WaylandShmPool::WaylandShmPool() -+ : mShmPool(nullptr), -+ mShmPoolFd(-1), -+ mAllocatedSize(0), -+ mImageData(MAP_FAILED){}; - -- // We set our queue to get mShmPool events at compositor thread. -- wl_proxy_set_queue((struct wl_proxy*)mShmPool, -- aWaylandDisplay->GetEventQueue()); -+void WaylandShmPool::Release() { -+ if (mImageData != MAP_FAILED) { -+ munmap(mImageData, mAllocatedSize); -+ mImageData = MAP_FAILED; -+ } -+ if (mShmPool) { -+ wl_shm_pool_destroy(mShmPool); -+ mShmPool = 0; -+ } -+ if (mShmPoolFd >= 0) { -+ close(mShmPoolFd); -+ mShmPoolFd = -1; -+ } - } - --bool WaylandShmPool::Resize(int aSize) { -+bool WaylandShmPool::Create(RefPtr aWaylandDisplay, -+ int aSize) { - // We do size increase only -- if (aSize <= mAllocatedSize) return true; -- -- if (ftruncate(mShmPoolFd, aSize) < 0) return false; -+ if (aSize <= mAllocatedSize) { -+ return true; -+ } - --#ifdef HAVE_POSIX_FALLOCATE -- do { -- errno = posix_fallocate(mShmPoolFd, 0, aSize); -- } while (errno == EINTR); -- if (errno != 0) return false; --#endif -+ if (mShmPoolFd < 0) { -+ mShmPoolFd = WaylandAllocateShmMemory(aSize); -+ if (mShmPoolFd < 0) { -+ return false; -+ } -+ } else { -+ if (!WaylandReAllocateShmMemory(mShmPoolFd, aSize)) { -+ Release(); -+ return false; -+ } -+ } - -- wl_shm_pool_resize(mShmPool, aSize); -- -- munmap(mImageData, mAllocatedSize); -- -+ if (mImageData != MAP_FAILED) { -+ munmap(mImageData, mAllocatedSize); -+ } - mImageData = - mmap(nullptr, aSize, PROT_READ | PROT_WRITE, MAP_SHARED, mShmPoolFd, 0); -- if (mImageData == MAP_FAILED) return false; -+ if (mImageData == MAP_FAILED) { -+ NS_WARNING("Unable to map drawing surface!"); -+ Release(); -+ return false; -+ } -+ -+ if (mShmPool) { -+ wl_shm_pool_resize(mShmPool, aSize); -+ } else { -+ mShmPool = wl_shm_create_pool(aWaylandDisplay->GetShm(), mShmPoolFd, aSize); -+ // We set our queue to get mShmPool events at compositor thread. -+ wl_proxy_set_queue((struct wl_proxy*)mShmPool, -+ aWaylandDisplay->GetEventQueue()); -+ } - - mAllocatedSize = aSize; - return true; -@@ -289,11 +342,7 @@ void WaylandShmPool::SetImageDataFromPoo - memcpy(mImageData, aSourcePool->GetImageData(), aImageDataSize); - } - --WaylandShmPool::~WaylandShmPool() { -- munmap(mImageData, mAllocatedSize); -- wl_shm_pool_destroy(mShmPool); -- close(mShmPoolFd); --} -+WaylandShmPool::~WaylandShmPool() { Release(); } - - static void buffer_release(void* data, wl_buffer* buffer) { - auto surface = reinterpret_cast(data); -@@ -302,14 +351,14 @@ static void buffer_release(void* data, w - - static const struct wl_buffer_listener buffer_listener = {buffer_release}; - --void WindowBackBufferShm::Create(int aWidth, int aHeight) { -+bool WindowBackBufferShm::Create(int aWidth, int aHeight) { - MOZ_ASSERT(!IsAttached(), "We can't create attached buffers."); -- MOZ_ASSERT(!mWLBuffer, "there is wl_buffer already!"); - -- int newBufferSize = aWidth * aHeight * BUFFER_BPP; -- if (!mShmPool.Resize(newBufferSize)) { -- mWLBuffer = nullptr; -- return; -+ ReleaseShmSurface(); -+ -+ int size = aWidth * aHeight * BUFFER_BPP; -+ if (!mShmPool.Create(GetWaylandDisplay(), size)) { -+ return false; - } - - mWLBuffer = -@@ -325,14 +374,16 @@ void WindowBackBufferShm::Create(int aWi - LOGWAYLAND(("WindowBackBufferShm::Create [%p] wl_buffer %p ID %d\n", - (void*)this, (void*)mWLBuffer, - mWLBuffer ? wl_proxy_get_id((struct wl_proxy*)mWLBuffer) : -1)); -+ return true; - } - - void WindowBackBufferShm::ReleaseShmSurface() { - LOGWAYLAND(("WindowBackBufferShm::Release [%p]\n", (void*)this)); -- -- wl_buffer_destroy(mWLBuffer); -+ if (mWLBuffer) { -+ wl_buffer_destroy(mWLBuffer); -+ mWLBuffer = nullptr; -+ } - mWidth = mHeight = 0; -- mWLBuffer = nullptr; - } - - void WindowBackBufferShm::Clear() { -@@ -340,16 +391,13 @@ void WindowBackBufferShm::Clear() { - } - - WindowBackBufferShm::WindowBackBufferShm( -- WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth, int aHeight) -+ WindowSurfaceWayland* aWindowSurfaceWayland) - : WindowBackBuffer(aWindowSurfaceWayland), -- mShmPool(aWindowSurfaceWayland->GetWaylandDisplay(), -- aWidth * aHeight * BUFFER_BPP), -+ mShmPool(), - mWLBuffer(nullptr), -- mWidth(aWidth), -- mHeight(aHeight), -- mAttached(false) { -- Create(aWidth, aHeight); --} -+ mWidth(0), -+ mHeight(0), -+ mAttached(false) {} - - WindowBackBufferShm::~WindowBackBufferShm() { ReleaseShmSurface(); } - -@@ -357,13 +405,9 @@ bool WindowBackBufferShm::Resize(int aWi - if (aWidth == mWidth && aHeight == mHeight) { - return true; - } -- - LOGWAYLAND(("WindowBackBufferShm::Resize [%p] %d %d\n", (void*)this, aWidth, - aHeight)); -- -- ReleaseShmSurface(); - Create(aWidth, aHeight); -- - return (mWLBuffer != nullptr); - } - -@@ -488,11 +532,13 @@ WindowBackBuffer* WindowSurfaceWayland:: - return nullptr; - } - -- WindowBackBuffer* buffer = new WindowBackBufferShm(this, aWidth, aHeight); -- if (buffer) { -- mShmBackupBuffer[availableBuffer] = buffer; -+ WindowBackBuffer* buffer = new WindowBackBufferShm(this); -+ if (!buffer->Create(aWidth, aHeight)) { -+ delete buffer; -+ return nullptr; - } - -+ mShmBackupBuffer[availableBuffer] = buffer; - return buffer; - } - -diff --git a/widget/gtk/WindowSurfaceWayland.h b/widget/gtk/WindowSurfaceWayland.h ---- a/widget/gtk/WindowSurfaceWayland.h -+++ b/widget/gtk/WindowSurfaceWayland.h -@@ -25,14 +25,14 @@ class WindowSurfaceWayland; - // Allocates and owns shared memory for Wayland drawing surface - class WaylandShmPool { - public: -- WaylandShmPool(RefPtr aDisplay, int aSize); -- ~WaylandShmPool(); -- -- bool Resize(int aSize); -+ bool Create(RefPtr aWaylandDisplay, int aSize); -+ void Release(); - wl_shm_pool* GetShmPool() { return mShmPool; }; - void* GetImageData() { return mImageData; }; - void SetImageDataFromPool(class WaylandShmPool* aSourcePool, - int aImageDataSize); -+ WaylandShmPool(); -+ ~WaylandShmPool(); - - private: - wl_shm_pool* mShmPool; -@@ -53,6 +53,7 @@ class WindowBackBuffer { - virtual bool IsAttached() = 0; - - virtual void Clear() = 0; -+ virtual bool Create(int aWidth, int aHeight) = 0; - virtual bool Resize(int aWidth, int aHeight) = 0; - - virtual int GetWidth() = 0; -@@ -87,8 +88,7 @@ class WindowBackBuffer { - - class WindowBackBufferShm : public WindowBackBuffer { - public: -- WindowBackBufferShm(WindowSurfaceWayland* aWindowSurfaceWayland, int aWidth, -- int aHeight); -+ WindowBackBufferShm(WindowSurfaceWayland* aWindowSurfaceWayland); - ~WindowBackBufferShm(); - - already_AddRefed Lock(); -@@ -100,6 +100,7 @@ class WindowBackBufferShm : public Windo - void SetAttached() { mAttached = true; }; - - void Clear(); -+ bool Create(int aWidth, int aHeight); - bool Resize(int aWidth, int aHeight); - bool SetImageDataFromBuffer(class WindowBackBuffer* aSourceBuffer); - -@@ -109,7 +110,6 @@ class WindowBackBufferShm : public Windo - wl_buffer* GetWlBuffer() { return mWLBuffer; }; - - private: -- void Create(int aWidth, int aHeight); - void ReleaseShmSurface(); - - // WaylandShmPool provides actual shared memory we draw into - diff --git a/mozilla-1700520.patch b/mozilla-1700520.patch deleted file mode 100644 index c93cbe2..0000000 --- a/mozilla-1700520.patch +++ /dev/null @@ -1,51 +0,0 @@ -diff --git a/gfx/wr/swgl/src/blend.h b/gfx/wr/swgl/src/blend.h ---- a/gfx/wr/swgl/src/blend.h -+++ b/gfx/wr/swgl/src/blend.h -@@ -405,7 +405,7 @@ - blend_key = BlendKey(AA_BLEND_KEY_NONE + blend_key); - } - --static ALWAYS_INLINE WideRGBA8 blend_pixels(uint32_t* buf, PackedRGBA8 pdst, -+static PREFER_INLINE WideRGBA8 blend_pixels(uint32_t* buf, PackedRGBA8 pdst, - WideRGBA8 src, int span = 4) { - WideRGBA8 dst = unpack(pdst); - const WideRGBA8 RGB_MASK = {0xFFFF, 0xFFFF, 0xFFFF, 0, 0xFFFF, 0xFFFF, -@@ -686,7 +686,7 @@ - // clang-format on - } - --static ALWAYS_INLINE WideR8 blend_pixels(uint8_t* buf, WideR8 dst, WideR8 src, -+static PREFER_INLINE WideR8 blend_pixels(uint8_t* buf, WideR8 dst, WideR8 src, - int span = 4) { - // clang-format off - #define BLEND_CASE_KEY(key) \ -diff --git a/gfx/wr/swgl/src/gl.cc b/gfx/wr/swgl/src/gl.cc ---- a/gfx/wr/swgl/src/gl.cc -+++ b/gfx/wr/swgl/src/gl.cc -@@ -58,10 +58,24 @@ - } - - #else --# define ALWAYS_INLINE __attribute__((always_inline)) inline -+// GCC is slower when dealing with always_inline, especially in debug builds. -+// When using Clang, use always_inline more aggressively. -+# if defined(__clang__) || defined(NDEBUG) -+# define ALWAYS_INLINE __attribute__((always_inline)) inline -+# else -+# define ALWAYS_INLINE inline -+# endif - # define NO_INLINE __attribute__((noinline)) - #endif - -+// Some functions may cause excessive binary bloat if inlined in debug or with -+// GCC builds, so use PREFER_INLINE on these instead of ALWAYS_INLINE. -+#if defined(__clang__) && defined(NDEBUG) -+# define PREFER_INLINE ALWAYS_INLINE -+#else -+# define PREFER_INLINE inline -+#endif -+ - #define UNREACHABLE __builtin_unreachable() - - #define UNUSED [[maybe_unused]] - diff --git a/mozilla-1701089.patch b/mozilla-1701089.patch deleted file mode 100644 index af431f2..0000000 --- a/mozilla-1701089.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff --git a/dom/media/gmp/GMPParent.cpp b/dom/media/gmp/GMPParent.cpp ---- a/dom/media/gmp/GMPParent.cpp -+++ b/dom/media/gmp/GMPParent.cpp -@@ -884,7 +884,7 @@ - // - // Google's code to parse manifests can be used as a reference for strings - // the manifest may contain -- // https://cs.chromium.org/chromium/src/chrome/common/media/cdm_manifest.cc?l=73&rcl=393e60bfc2299449db7ef374c0ef1c324716e562 -+ // https://source.chromium.org/chromium/chromium/src/+/master:components/cdm/common/cdm_manifest.cc;l=74;drc=775880ced8a989191281e93854c7f2201f25068f - // - // Gecko's internal strings can be found at - // https://searchfox.org/mozilla-central/rev/ea63a0888d406fae720cf24f4727d87569a8cab5/dom/media/eme/MediaKeySystemAccess.cpp#149-155 -@@ -892,7 +892,8 @@ - nsCString codec; - if (chromiumCodec.EqualsASCII("vp8")) { - codec = "vp8"_ns; -- } else if (chromiumCodec.EqualsASCII("vp9.0")) { -+ } else if (chromiumCodec.EqualsASCII("vp9.0") || // Legacy string. -+ chromiumCodec.EqualsASCII("vp09")) { - codec = "vp9"_ns; - } else if (chromiumCodec.EqualsASCII("avc1")) { - codec = "h264"_ns; - diff --git a/mozilla-1753402.patch b/mozilla-1753402.patch deleted file mode 100644 index e53e73b..0000000 --- a/mozilla-1753402.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/tools/profiler/rust-api/build.rs b/tools/profiler/rust-api/build.rs ---- a/tools/profiler/rust-api/build.rs -+++ b/tools/profiler/rust-api/build.rs -@@ -61,6 +61,7 @@ - let mut builder = Builder::default() - .enable_cxx_namespaces() - .with_codegen_config(CodegenConfig::TYPES | CodegenConfig::VARS | CodegenConfig::FUNCTIONS) -+ .disable_untagged_union() - .size_t_is_usize(true); - - for dir in SEARCH_PATHS.iter() { - diff --git a/mozilla-1767946-profilemanagersize.patch b/mozilla-1767946-profilemanagersize.patch deleted file mode 100644 index 4469934..0000000 --- a/mozilla-1767946-profilemanagersize.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp ---- a/widget/gtk/nsWindow.cpp -+++ b/widget/gtk/nsWindow.cpp -@@ -3787,11 +3787,12 @@ - mPendingConfigures--; - } - - // Don't fire configure event for scale changes, we handle that - // OnScaleChanged event. Skip that for toplevel windows only. -- if (mWindowType == eWindowType_toplevel) { -+ if (mWindowType == eWindowType_toplevel || -+ mWindowType == eWindowType_dialog) { - MOZ_DIAGNOSTIC_ASSERT(mGdkWindow, - "Getting configure for invisible window?"); - if (mWindowScaleFactor != gdk_window_get_scale_factor(mGdkWindow)) { - LOG(" scale factor changed to %d,return early", - gdk_window_get_scale_factor(mGdkWindow)); -@@ -4864,10 +4865,11 @@ - // Force scale factor recalculation - if (!mGdkWindow) { - mWindowScaleFactorChanged = true; - return; - } -+ LOG("OnScaleChanged -> %d\n", gdk_window_get_scale_factor(mGdkWindow)); - - // Gtk supply us sometimes with doubled events so stay calm in such case. - if (gdk_window_get_scale_factor(mGdkWindow) == mWindowScaleFactor) { - return; - } - diff --git a/mozilla-1885133.patch b/mozilla-1885133.patch deleted file mode 100644 index a73503a..0000000 --- a/mozilla-1885133.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/browser/components/shell/nsGNOMEShellDBusHelper.cpp b/browser/components/shell/nsGNOMEShellDBusHelper.cpp ---- a/browser/components/shell/nsGNOMEShellDBusHelper.cpp -+++ b/browser/components/shell/nsGNOMEShellDBusHelper.cpp -@@ -29,7 +29,7 @@ static bool GetGnomeSearchTitle(const ch - } - - AutoTArray formatStrings; -- CopyASCIItoUTF16(nsCString(aSearchedTerm), *formatStrings.AppendElement()); -+ CopyUTF8toUTF16(nsCString(aSearchedTerm), *formatStrings.AppendElement()); - - nsAutoString gnomeSearchTitle; - bundle->FormatStringFromName("gnomeSearchProviderSearch", formatStrings, -@@ -41,7 +41,7 @@ static bool GetGnomeSearchTitle(const ch - static const char* introspect_template = - "\n" -+ "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" - "\n" - " \n" - " \n" diff --git a/mozilla-440908.patch b/mozilla-440908.patch deleted file mode 100644 index cce5248..0000000 --- a/mozilla-440908.patch +++ /dev/null @@ -1,111 +0,0 @@ -diff -up firefox-56.0/modules/libpref/prefapi.cpp.440908 firefox-56.0/modules/libpref/prefapi.cpp ---- firefox-56.0/modules/libpref/prefapi.cpp.440908 2017-09-14 22:15:52.000000000 +0200 -+++ firefox-56.0/modules/libpref/prefapi.cpp 2017-09-25 10:39:39.266572792 +0200 -@@ -1036,8 +1036,8 @@ void PREF_ReaderCallback(void *clo - PrefValue value, - PrefType type, - bool isDefault, -- bool isStickyDefault) -- -+ bool isStickyDefault, -+ bool isLocked) - { - uint32_t flags = 0; - if (isDefault) { -@@ -1049,4 +1049,6 @@ void PREF_ReaderCallback(void *clo - flags |= kPrefForceSet; - } - pref_HashPref(pref, value, type, flags); -+ if (isLocked) -+ PREF_LockPref(pref, true); - } -diff -up firefox-56.0/modules/libpref/prefapi.h.440908 firefox-56.0/modules/libpref/prefapi.h ---- firefox-56.0/modules/libpref/prefapi.h.440908 2017-07-31 18:20:51.000000000 +0200 -+++ firefox-56.0/modules/libpref/prefapi.h 2017-09-25 10:39:39.267572789 +0200 -@@ -246,8 +246,8 @@ void PREF_ReaderCallback( void *closure, - PrefValue value, - PrefType type, - bool isDefault, -- bool isStickyDefault); -- -+ bool isStickyDefault, -+ bool isLocked); - - /* - * Callback whenever we change a preference -diff -up firefox-56.0/modules/libpref/prefread.cpp.440908 firefox-56.0/modules/libpref/prefread.cpp ---- firefox-56.0/modules/libpref/prefread.cpp.440908 2017-09-14 22:15:52.000000000 +0200 -+++ firefox-56.0/modules/libpref/prefread.cpp 2017-09-25 10:39:39.267572789 +0200 -@@ -43,6 +43,7 @@ enum { - #define BITS_PER_HEX_DIGIT 4 - - static const char kUserPref[] = "user_pref"; -+static const char kLockPref[] = "lockPref"; - static const char kPref[] = "pref"; - static const char kPrefSticky[] = "sticky_pref"; - static const char kTrue[] = "true"; -@@ -146,7 +147,7 @@ pref_DoCallback(PrefParseState *ps) - break; - } - (*ps->reader)(ps->closure, ps->lb, value, ps->vtype, ps->fdefault, -- ps->fstickydefault); -+ ps->fstickydefault, ps->flock); - return true; - } - -@@ -215,6 +216,7 @@ PREF_ParseBuf(PrefParseState *ps, const - ps->vtype = PrefType::Invalid; - ps->fdefault = false; - ps->fstickydefault = false; -+ ps->flock = false; - } - switch (c) { - case '/': /* begin comment block or line? */ -@@ -225,11 +227,14 @@ PREF_ParseBuf(PrefParseState *ps, const - break; - case 'u': /* indicating user_pref */ - case 's': /* indicating sticky_pref */ -+ case 'l': /* indicating lockPref */ - case 'p': /* indicating pref */ - if (c == 'u') { - ps->smatch = kUserPref; - } else if (c == 's') { - ps->smatch = kPrefSticky; -+ } else if (c == 'l') { -+ ps->smatch = kLockPref; - } else { - ps->smatch = kPref; - } -@@ -277,8 +282,10 @@ PREF_ParseBuf(PrefParseState *ps, const - /* name parsing */ - case PREF_PARSE_UNTIL_NAME: - if (c == '\"' || c == '\'') { -- ps->fdefault = (ps->smatch == kPref || ps->smatch == kPrefSticky); -+ ps->fdefault = (ps->smatch == kPref || ps->smatch == kPrefSticky -+ || ps->smatch == kLockPref); - ps->fstickydefault = (ps->smatch == kPrefSticky); -+ ps->flock = (ps->smatch == kLockPref); - ps->quotechar = c; - ps->nextstate = PREF_PARSE_UNTIL_COMMA; /* return here when done */ - state = PREF_PARSE_QUOTED_STRING; -diff -up firefox-56.0/modules/libpref/prefread.h.440908 firefox-56.0/modules/libpref/prefread.h ---- firefox-56.0/modules/libpref/prefread.h.440908 2017-09-14 22:15:52.000000000 +0200 -+++ firefox-56.0/modules/libpref/prefread.h 2017-09-25 10:39:39.267572789 +0200 -@@ -34,7 +34,8 @@ typedef void (*PrefReader)(void *c - PrefValue val, - PrefType type, - bool defPref, -- bool stickyPref); -+ bool stickyPref, -+ bool lockPref); - - /** - * Report any errors or warnings we encounter during parsing. -@@ -62,6 +63,7 @@ typedef struct PrefParseState { - PrefType vtype; /* PREF_STRING,INT,BOOL */ - bool fdefault; /* true if (default) pref */ - bool fstickydefault; /* true if (sticky) pref */ -+ bool flock; /* true if pref to be locked */ - } PrefParseState; - - /** diff --git a/mozilla-build-arm.patch b/mozilla-build-arm.patch deleted file mode 100644 index e390a28..0000000 --- a/mozilla-build-arm.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up firefox-52.0/gfx/skia/skia/include/core/SkPreConfig.h.arm firefox-52.0/gfx/skia/skia/include/core/SkPreConfig.h ---- firefox-52.0/gfx/skia/skia/include/core/SkPreConfig.h.arm 2017-03-03 13:53:52.480754536 +0100 -+++ firefox-52.0/gfx/skia/skia/include/core/SkPreConfig.h 2017-03-03 13:56:01.476018102 +0100 -@@ -203,6 +203,10 @@ - #define SK_ARM_HAS_CRC32 - #endif - -+#if defined(__aarch64__) -+ #undef SK_ARM_HAS_NEON -+#endif -+ - ////////////////////////////////////////////////////////////////////// - - #if !defined(SKIA_IMPLEMENTATION) diff --git a/org.mozilla.firefox.SearchProvider.service b/org.mozilla.firefox.SearchProvider.service new file mode 100644 index 0000000..6b2bd1b --- /dev/null +++ b/org.mozilla.firefox.SearchProvider.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.mozilla.firefox.SearchProvider +Exec=/usr/lib64/firefox/firefox --dbus-service /usr/bin/firefox diff --git a/org.mozilla.firefox.appdata.xml.in b/org.mozilla.firefox.appdata.xml.in new file mode 100644 index 0000000..3c086a1 --- /dev/null +++ b/org.mozilla.firefox.appdata.xml.in @@ -0,0 +1,61 @@ + + + + org.mozilla.firefox + CC0-1.0 + Firefox + Web Browser + Navegador web + Webový prohlížeč + Navegador web + مرورگر اینترنتی + WWW-selain + Navigateur Web + Webböngésző + Browser Web + ウェブ・ブラウザ + 웹 브라우저 + Nettleser + Webbrowser + Nettlesar + Nettleser + Przeglądarka WWW + Navegador Web + Navegador Web + Internetový prehliadač + Webbläsare + +

+ Bringing together all kinds of awesomeness to make browsing better for you. + Get to your favorite sites quickly – even if you don’t remember the URLs. + Type your term into the location bar (aka the Awesome Bar) and the autocomplete + function will include possible matches from your browsing history, bookmarked + sites and open tabs. +

+
+ https://www.mozilla.org + stransky@redhat.com + + ModernToolkit + SearchProvider + + Mozilla + GPL-3.0+ + Mozilla Corporation + https://bugzilla.mozilla.org/ + https://support.mozilla.org/ + firefox + org.mozilla.firefox.desktop + + firefox.desktop + + + https://raw.githubusercontent.com/hughsie/fedora-appstream/master/screenshots-extra/firefox/a.png + https://raw.githubusercontent.com/hughsie/fedora-appstream/master/screenshots-extra/firefox/b.png + https://raw.githubusercontent.com/hughsie/fedora-appstream/master/screenshots-extra/firefox/c.png + + + + + +
diff --git a/org.mozilla.firefox.desktop b/org.mozilla.firefox.desktop new file mode 100644 index 0000000..02e156d --- /dev/null +++ b/org.mozilla.firefox.desktop @@ -0,0 +1,276 @@ +[Desktop Entry] +Version=1.0 +Name=Firefox +GenericName=Web Browser +GenericName[ca]=Navegador web +GenericName[cs]=Webový prohlížeč +GenericName[es]=Navegador web +GenericName[fa]=مرورگر اینترنتی +GenericName[fi]=WWW-selain +GenericName[fr]=Navigateur Web +GenericName[hu]=Webböngésző +GenericName[it]=Browser Web +GenericName[ja]=ウェブ・ブラウザ +GenericName[ko]=웹 브라우저 +GenericName[nb]=Nettleser +GenericName[nl]=Webbrowser +GenericName[nn]=Nettlesar +GenericName[no]=Nettleser +GenericName[pl]=Przeglądarka WWW +GenericName[pt]=Navegador Web +GenericName[pt_BR]=Navegador Web +GenericName[sk]=Internetový prehliadač +GenericName[sv]=Webbläsare +Comment=Browse the Web +Comment[ca]=Navegueu per el web +Comment[cs]=Prohlížení stránek World Wide Webu +Comment[de]=Im Internet surfen +Comment[es]=Navegue por la web +Comment[fa]=صفحات شبکه جهانی اینترنت را مرور نمایید +Comment[fi]=Selaa Internetin WWW-sivuja +Comment[fr]=Navigue sur Internet +Comment[hu]=A világháló böngészése +Comment[it]=Esplora il web +Comment[ja]=ウェブを閲覧します +Comment[ko]=웹을 돌아 다닙니다 +Comment[nb]=Surf på nettet +Comment[nl]=Verken het internet +Comment[nn]=Surf på nettet +Comment[no]=Surf på nettet +Comment[pl]=Przeglądanie stron WWW +Comment[pt]=Navegue na Internet +Comment[pt_BR]=Navegue na Internet +Comment[sk]=Prehliadanie internetu +Comment[sv]=Surfa på webben +Exec=firefox %u +Icon=firefox +Terminal=false +Type=Application +MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml;x-scheme-handler/http;x-scheme-handler/https; +StartupNotify=true +Categories=Network;WebBrowser; +Keywords=web;browser;internet; +Actions=new-window;new-private-window;profile-manager-window; + +[Desktop Action new-window] +Name=Open a New Window +Name[ach]=Dirica manyen +Name[af]=Nuwe venster +Name[an]=Nueva finestra +Name[ar]=نافذة جديدة +Name[as]=নতুন উইন্ডো +Name[ast]=Ventana nueva +Name[az]=Yeni Pəncərə +Name[be]=Новае акно +Name[bg]=Нов прозорец +Name[bn_BD]=নতুন উইন্ডো (N) +Name[bn_IN]=নতুন উইন্ডো +Name[br]=Prenestr nevez +Name[brx]=गोदान उइन्ड'(N) +Name[bs]=Novi prozor +Name[ca]=Finestra nova +Name[cak]=K'ak'a' tzuwäch +Name[cs]=Nové okno +Name[cy]=Ffenestr Newydd +Name[da]=Nyt vindue +Name[de]=Neues Fenster +Name[dsb]=Nowe wokno +Name[el]=Νέο παράθυρο +Name[en_GB]=New Window +Name[en_US]=New Window +Name[en_ZA]=New Window +Name[eo]=Nova fenestro +Name[es_AR]=Nueva ventana +Name[es_CL]=Nueva ventana +Name[es_ES]=Nueva ventana +Name[es_MX]=Nueva ventana +Name[et]=Uus aken +Name[eu]=Leiho berria +Name[fa]=پنجره جدید‌ +Name[ff]=Henorde Hesere +Name[fi]=Uusi ikkuna +Name[fr]=Nouvelle fenêtre +Name[fy_NL]=Nij finster +Name[ga_IE]=Fuinneog Nua +Name[gd]=Uinneag ùr +Name[gl]=Nova xanela +Name[gn]=Ovetã pyahu +Name[gu_IN]=નવી વિન્ડો +Name[he]=חלון חדש +Name[hi_IN]=नया विंडो +Name[hr]=Novi prozor +Name[hsb]=Nowe wokno +Name[hu]=Új ablak +Name[hy_AM]=Նոր Պատուհան +Name[id]=Jendela Baru +Name[is]=Nýr gluggi +Name[it]=Nuova finestra +Name[ja]=新しいウィンドウ +Name[ja_JP-mac]=新規ウインドウ +Name[ka]=ახალი ფანჯარა +Name[kk]=Жаңа терезе +Name[km]=បង្អួច​​​ថ្មី +Name[kn]=ಹೊಸ ಕಿಟಕಿ +Name[ko]=새 창 +Name[kok]=नवें जनेल +Name[ks]=نئئ وِنڈو +Name[lij]=Neuvo barcon +Name[lo]=ຫນ້າຕ່າງໃຫມ່ +Name[lt]=Naujas langas +Name[ltg]=Jauns lūgs +Name[lv]=Jauns logs +Name[mai]=नव विंडो +Name[mk]=Нов прозорец +Name[ml]=പുതിയ ജാലകം +Name[mr]=नवीन पटल +Name[ms]=Tetingkap Baru +Name[my]=ဝင်းဒိုးအသစ် +Name[nb_NO]=Nytt vindu +Name[ne_NP]=नयाँ सञ्झ्याल +Name[nl]=Nieuw venster +Name[nn_NO]=Nytt vindauge +Name[or]=ନୂତନ ୱିଣ୍ଡୋ +Name[pa_IN]=ਨਵੀਂ ਵਿੰਡੋ +Name[pl]=Nowe okno +Name[pt_BR]=Nova janela +Name[pt_PT]=Nova janela +Name[rm]=Nova fanestra +Name[ro]=Fereastră nouă +Name[ru]=Новое окно +Name[sat]=नावा विंडो (N) +Name[si]=නව කවුළුවක් +Name[sk]=Nové okno +Name[sl]=Novo okno +Name[son]=Zanfun taaga +Name[sq]=Dritare e Re +Name[sr]=Нови прозор +Name[sv_SE]=Nytt fönster +Name[ta]=புதிய சாளரம் +Name[te]=కొత్త విండో +Name[th]=หน้าต่างใหม่ +Name[tr]=Yeni pencere +Name[tsz]=Eraatarakua jimpani +Name[uk]=Нове вікно +Name[ur]=نیا دریچہ +Name[uz]=Yangi oyna +Name[vi]=Cửa sổ mới +Name[wo]=Palanteer bu bees +Name[xh]=Ifestile entsha +Name[zh_CN]=新建窗口 +Name[zh_TW]=開新視窗 +Exec=firefox --new-window %u + +[Desktop Action new-private-window] +Name=Open a New Private Window +Name[ach]=Dirica manyen me mung +Name[af]=Nuwe privaatvenster +Name[an]=Nueva finestra privada +Name[ar]=نافذة خاصة جديدة +Name[as]=নতুন ব্যক্তিগত উইন্ডো +Name[ast]=Ventana privada nueva +Name[az]=Yeni Məxfi Pəncərə +Name[be]=Новае акно адасаблення +Name[bg]=Нов прозорец за поверително сърфиране +Name[bn_BD]=নতুন ব্যক্তিগত উইন্ডো +Name[bn_IN]=নতুন ব্যক্তিগত উইন্ডো +Name[br]=Prenestr merdeiñ prevez nevez +Name[brx]=गोदान प्राइभेट उइन्ड' +Name[bs]=Novi privatni prozor +Name[ca]=Finestra privada nova +Name[cak]=K'ak'a' ichinan tzuwäch +Name[cs]=Nové anonymní okno +Name[cy]=Ffenestr Breifat Newydd +Name[da]=Nyt privat vindue +Name[de]=Neues privates Fenster +Name[dsb]=Nowe priwatne wokno +Name[el]=Νέο παράθυρο ιδιωτικής περιήγησης +Name[en_GB]=New Private Window +Name[en_US]=New Private Window +Name[en_ZA]=New Private Window +Name[eo]=Nova privata fenestro +Name[es_AR]=Nueva ventana privada +Name[es_CL]=Nueva ventana privada +Name[es_ES]=Nueva ventana privada +Name[es_MX]=Nueva ventana privada +Name[et]=Uus privaatne aken +Name[eu]=Leiho pribatu berria +Name[fa]=پنجره ناشناس جدید +Name[ff]=Henorde Suturo Hesere +Name[fi]=Uusi yksityinen ikkuna +Name[fr]=Nouvelle fenêtre de navigation privée +Name[fy_NL]=Nij priveefinster +Name[ga_IE]=Fuinneog Nua Phríobháideach +Name[gd]=Uinneag phrìobhaideach ùr +Name[gl]=Nova xanela privada +Name[gn]=Ovetã ñemi pyahu +Name[gu_IN]=નવી ખાનગી વિન્ડો +Name[he]=חלון פרטי חדש +Name[hi_IN]=नयी निजी विंडो +Name[hr]=Novi privatni prozor +Name[hsb]=Nowe priwatne wokno +Name[hu]=Új privát ablak +Name[hy_AM]=Սկսել Գաղտնի դիտարկում +Name[id]=Jendela Mode Pribadi Baru +Name[is]=Nýr huliðsgluggi +Name[it]=Nuova finestra anonima +Name[ja]=新しいプライベートウィンドウ +Name[ja_JP-mac]=新規プライベートウインドウ +Name[ka]=ახალი პირადი ფანჯარა +Name[kk]=Жаңа жекелік терезе +Name[km]=បង្អួច​ឯកជន​ថ្មី +Name[kn]=ಹೊಸ ಖಾಸಗಿ ಕಿಟಕಿ +Name[ko]=새 사생활 보호 모드 +Name[kok]=नवो खाजगी विंडो +Name[ks]=نْو پرایوٹ وینڈو& +Name[lij]=Neuvo barcon privou +Name[lo]=ເປີດຫນ້າຕ່າງສວນຕົວຂື້ນມາໃຫມ່ +Name[lt]=Naujas privataus naršymo langas +Name[ltg]=Jauns privatais lūgs +Name[lv]=Jauns privātais logs +Name[mai]=नया निज विंडो (W) +Name[mk]=Нов приватен прозорец +Name[ml]=പുതിയ സ്വകാര്യ ജാലകം +Name[mr]=नवीन वैयक्तिक पटल +Name[ms]=Tetingkap Persendirian Baharu +Name[my]=New Private Window +Name[nb_NO]=Nytt privat vindu +Name[ne_NP]=नयाँ निजी सञ्झ्याल +Name[nl]=Nieuw privévenster +Name[nn_NO]=Nytt privat vindauge +Name[or]=ନୂତନ ବ୍ୟକ୍ତିଗତ ୱିଣ୍ଡୋ +Name[pa_IN]=ਨਵੀਂ ਪ੍ਰਾਈਵੇਟ ਵਿੰਡੋ +Name[pl]=Nowe okno prywatne +Name[pt_BR]=Nova janela privativa +Name[pt_PT]=Nova janela privada +Name[rm]=Nova fanestra privata +Name[ro]=Fereastră privată nouă +Name[ru]=Новое приватное окно +Name[sat]=नावा निजेराक् विंडो (W ) +Name[si]=නව පුද්ගලික කවුළුව (W) +Name[sk]=Nové okno v režime Súkromné prehliadanie +Name[sl]=Novo zasebno okno +Name[son]=Sutura zanfun taaga +Name[sq]=Dritare e Re Private +Name[sr]=Нови приватан прозор +Name[sv_SE]=Nytt privat fönster +Name[ta]=புதிய தனிப்பட்ட சாளரம் +Name[te]=కొత్త ఆంతరంగిక విండో +Name[th]=หน้าต่างส่วนตัวใหม่ +Name[tr]=Yeni gizli pencere +Name[tsz]=Juchiiti eraatarakua jimpani +Name[uk]=Приватне вікно +Name[ur]=نیا نجی دریچہ +Name[uz]=Yangi maxfiy oyna +Name[vi]=Cửa sổ riêng tư mới +Name[wo]=Panlanteeru biir bu bees +Name[xh]=Ifestile yangasese entsha +Name[zh_CN]=新建隐私浏览窗口 +Name[zh_TW]=新增隱私視窗 +Exec=firefox --private-window %u + +[Desktop Action profile-manager-window] +Name=Open the Profile Manager +Name[cs]=Správa profilů +Name[de]=Profilverwaltung öffnen +Name[fr]=Ouvrir le gestionnaire de profils +Exec=firefox --ProfileManager diff --git a/org.mozilla.firefox.search-provider.ini b/org.mozilla.firefox.search-provider.ini new file mode 100644 index 0000000..0211665 --- /dev/null +++ b/org.mozilla.firefox.search-provider.ini @@ -0,0 +1,5 @@ +[Shell Search Provider] +DesktopId=org.mozilla.firefox.desktop +BusName=org.mozilla.firefox.SearchProvider +ObjectPath=/org/mozilla/firefox/SearchProvider +Version=2 diff --git a/pgo.patch b/pgo.patch index eec103c..c1ae97d 100644 --- a/pgo.patch +++ b/pgo.patch @@ -1,39 +1,46 @@ -diff -up firefox-99.0/build/moz.configure/lto-pgo.configure.pgo firefox-99.0/build/moz.configure/lto-pgo.configure ---- firefox-99.0/build/moz.configure/lto-pgo.configure.pgo 2022-03-31 01:24:38.000000000 +0200 -+++ firefox-99.0/build/moz.configure/lto-pgo.configure 2022-04-04 10:15:45.387694143 +0200 -@@ -247,8 +247,8 @@ def lto( - cflags.append("-flto") - ldflags.append("-flto") - else: -- cflags.append("-flto=thin") -- ldflags.append("-flto=thin") -+ cflags.append("-flto") -+ ldflags.append("-flto") +diff -up firefox-145.0/build/moz.configure/lto-pgo.configure.pgo firefox-145.0/build/moz.configure/lto-pgo.configure +--- firefox-145.0/build/moz.configure/lto-pgo.configure.pgo 2025-11-03 16:56:55.000000000 +0100 ++++ firefox-145.0/build/moz.configure/lto-pgo.configure 2025-11-05 13:59:53.477443914 +0100 +@@ -96,12 +96,16 @@ set_config("PGO_PROFILE_PATH", pgo_profi - if target.os == "Android" and value == "cross": - # Work around https://github.com/rust-lang/rust/issues/90088 -@@ -264,7 +264,7 @@ def lto( - if value == "full": - cflags.append("-flto") - else: -- cflags.append("-flto=thin") -+ cflags.append("-flto") - # With clang-cl, -flto can only be used with -c or -fuse-ld=lld. - # AC_TRY_LINKs during configure don't have -c, so pass -fuse-ld=lld. - cflags.append("-fuse-ld=lld") -diff -up firefox-99.0/build/pgo/profileserver.py.pgo firefox-99.0/build/pgo/profileserver.py ---- firefox-99.0/build/pgo/profileserver.py.pgo 2022-03-31 01:24:38.000000000 +0200 -+++ firefox-99.0/build/pgo/profileserver.py 2022-04-04 10:15:45.387694143 +0200 -@@ -11,7 +11,7 @@ import glob - import subprocess + @depends( + "--enable-profile-use", ++ c_compiler, + pgo_profile_path, + llvm_profdata, + llvm_profdata_order, + build_environment, + ) +-def orderfile_path(profile_use, path, profdata, profdata_order, build_env): ++def orderfile_path(profile_use, compiler, path, profdata, profdata_order, build_env): ++ if compiler.type == "gcc": ++ return None ++ + if not profile_use: + return None + +@@ -145,7 +149,7 @@ def pgo_flags( + return namespace( + gen_cflags=["-fprofile-generate"], + gen_ldflags=["-fprofile-generate"], +- use_cflags=["-fprofile-use", "-fprofile-correction", "-Wcoverage-mismatch"], ++ use_cflags=["-fprofile-use", "-fprofile-correction", "-Wno-coverage-mismatch"], + use_ldflags=["-fprofile-use"], + ) + +diff -up firefox-145.0/build/pgo/profileserver.py.pgo firefox-145.0/build/pgo/profileserver.py +--- firefox-145.0/build/pgo/profileserver.py.pgo 2025-11-03 16:56:55.000000000 +0100 ++++ firefox-145.0/build/pgo/profileserver.py 2025-11-05 13:59:53.477602066 +0100 +@@ -10,7 +10,7 @@ import subprocess + import sys import mozcrash --from mozbuild.base import MozbuildObject, BinaryNotFoundException -+from mozbuild.base import MozbuildObject, BinaryNotFoundException, BuildEnvironmentNotFoundException - from mozfile import TemporaryDirectory +-from mozbuild.base import BinaryNotFoundException, MozbuildObject ++from mozbuild.base import BinaryNotFoundException, MozbuildObject, BuildEnvironmentNotFoundException + from mozfile import TemporaryDirectory, json from mozhttpd import MozHttpd from mozprofile import FirefoxProfile, Preferences -@@ -87,9 +87,22 @@ if __name__ == "__main__": +@@ -96,9 +96,22 @@ if __name__ == "__main__": locations = ServerLocations() locations.add_host(host="127.0.0.1", port=PORT, options="primary,privileged") @@ -59,49 +66,55 @@ diff -up firefox-99.0/build/pgo/profileserver.py.pgo firefox-99.0/build/pgo/prof with TemporaryDirectory() as profilePath: # TODO: refactor this into mozprofile -@@ -212,6 +225,10 @@ if __name__ == "__main__": - print("Firefox exited successfully, but produced a crashreport") - sys.exit(1) +diff -up firefox-145.0/gfx/2d/moz.build.pgo firefox-145.0/gfx/2d/moz.build +--- firefox-145.0/gfx/2d/moz.build.pgo 2025-11-03 16:56:57.000000000 +0100 ++++ firefox-145.0/gfx/2d/moz.build 2025-11-05 14:21:20.485610837 +0100 +@@ -137,11 +137,11 @@ if CONFIG["INTEL_ARCHITECTURE"]: + DEFINES["USE_SSE2"] = True + # The file uses SSE2 intrinsics, so it needs special compile flags on some + # compilers. +- SOURCES["ConvolutionFilterAVX2.cpp"].flags += ["-mavx2"] ++ SOURCES["ConvolutionFilterAVX2.cpp"].flags += ["-mavx2", "-fno-lto"] + SOURCES["ConvolutionFilterSSE2.cpp"].flags += CONFIG["SSE2_FLAGS"] + SOURCES["FilterProcessingSSE2.cpp"].flags += CONFIG["SSE2_FLAGS"] + SOURCES["ImageScalingSSE2.cpp"].flags += CONFIG["SSE2_FLAGS"] +- SOURCES["SwizzleAVX2.cpp"].flags += ["-mavx2"] ++ SOURCES["SwizzleAVX2.cpp"].flags += ["-mavx2", "-fno-lto"] + SOURCES["SwizzleSSE2.cpp"].flags += CONFIG["SSE2_FLAGS"] + SOURCES["SwizzleSSSE3.cpp"].flags += CONFIG["SSSE3_FLAGS"] -+ print('Copying profile data....') -+ os.system('pwd'); -+ os.system('tar cf profdata.tar.gz `find . -name "*.gcda"`; cd ..; tar xf instrumented/profdata.tar.gz;'); -+ - llvm_profdata = env.get("LLVM_PROFDATA") - if llvm_profdata: - profraw_files = glob.glob("*.profraw") -diff -up firefox-99.0/build/unix/mozconfig.unix.pgo firefox-99.0/build/unix/mozconfig.unix ---- firefox-99.0/build/unix/mozconfig.unix.pgo 2022-03-31 01:24:38.000000000 +0200 -+++ firefox-99.0/build/unix/mozconfig.unix 2022-04-04 10:15:45.387694143 +0200 -@@ -4,6 +4,15 @@ if [ -n "$FORCE_GCC" ]; then - CC="$MOZ_FETCHES_DIR/gcc/bin/gcc" - CXX="$MOZ_FETCHES_DIR/gcc/bin/g++" - -+ if [ -n "$MOZ_PGO" ]; then -+ if [ -z "$USE_ARTIFACT" ]; then -+ ac_add_options --enable-lto -+ fi -+ export AR="$topsrcdir/gcc/bin/gcc-ar" -+ export NM="$topsrcdir/gcc/bin/gcc-nm" -+ export RANLIB="$topsrcdir/gcc/bin/gcc-ranlib" -+ fi -+ - # We want to make sure we use binutils and other binaries in the tooltool - # package. - mk_add_options "export PATH=$MOZ_FETCHES_DIR/gcc/bin:$PATH" -diff -up firefox-99.0/extensions/spellcheck/src/moz.build.pgo firefox-99.0/extensions/spellcheck/src/moz.build ---- firefox-99.0/extensions/spellcheck/src/moz.build.pgo 2022-03-31 01:24:50.000000000 +0200 -+++ firefox-99.0/extensions/spellcheck/src/moz.build 2022-04-04 10:15:45.387694143 +0200 -@@ -28,3 +28,5 @@ EXPORTS.mozilla += [ - "mozInlineSpellChecker.h", - "mozSpellChecker.h", - ] -+ -+CXXFLAGS += ['-fno-devirtualize'] -diff -up firefox-99.0/toolkit/components/terminator/nsTerminator.cpp.pgo firefox-99.0/toolkit/components/terminator/nsTerminator.cpp ---- firefox-99.0/toolkit/components/terminator/nsTerminator.cpp.pgo 2022-04-04 10:15:45.387694143 +0200 -+++ firefox-99.0/toolkit/components/terminator/nsTerminator.cpp 2022-04-04 10:19:07.022239556 +0200 -@@ -466,6 +466,11 @@ void nsTerminator::StartWatchdog() { +diff -up firefox-145.0/gfx/skia/generate_mozbuild.py.pgo firefox-145.0/gfx/skia/generate_mozbuild.py +--- firefox-145.0/gfx/skia/generate_mozbuild.py.pgo 2025-11-03 16:56:57.000000000 +0100 ++++ firefox-145.0/gfx/skia/generate_mozbuild.py 2025-11-05 13:59:53.477947055 +0100 +@@ -50,8 +50,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind + if CONFIG['INTEL_ARCHITECTURE']: + SOURCES['skia/modules/skcms/skcms.cc'].flags += ['-DSKCMS_DISABLE_SKX'] + skia_ssse3_flags = ['-Dskvx=skvx_ssse3', '-mssse3'] +- skia_avx_flags = ['-Dskvx=skvx_avx', '-mavx'] +- skia_hsw_flags = ['-Dskvx=skvx_hsw', '-mavx2', '-mf16c', '-mfma'] ++ skia_avx_flags = ['-Dskvx=skvx_avx', '-mavx', '-fno-lto'] ++ skia_hsw_flags = ['-Dskvx=skvx_hsw', '-mavx2', '-mf16c', '-mfma', '-fno-lto'] + SOURCES['skia/src/core/SkBitmapProcState_opts_ssse3.cpp'].flags += skia_ssse3_flags + SOURCES['skia/src/core/SkBlitMask_opts_ssse3.cpp'].flags += skia_ssse3_flags + SOURCES['skia/src/core/SkSwizzler_opts_ssse3.cpp'].flags += ['-Dskvx=skvx_ssse3'] +diff -up firefox-145.0/gfx/skia/moz.build.pgo firefox-145.0/gfx/skia/moz.build +--- firefox-145.0/gfx/skia/moz.build.pgo 2025-11-03 16:56:57.000000000 +0100 ++++ firefox-145.0/gfx/skia/moz.build 2025-11-05 13:59:53.478077484 +0100 +@@ -597,8 +597,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wind + if CONFIG['INTEL_ARCHITECTURE']: + SOURCES['skia/modules/skcms/skcms.cc'].flags += ['-DSKCMS_DISABLE_SKX'] + skia_ssse3_flags = ['-Dskvx=skvx_ssse3', '-mssse3'] +- skia_avx_flags = ['-Dskvx=skvx_avx', '-mavx'] +- skia_hsw_flags = ['-Dskvx=skvx_hsw', '-mavx2', '-mf16c', '-mfma'] ++ skia_avx_flags = ['-Dskvx=skvx_avx', '-mavx', '-fno-lto'] ++ skia_hsw_flags = ['-Dskvx=skvx_hsw', '-mavx2', '-mf16c', '-mfma', '-fno-lto'] + SOURCES['skia/src/core/SkBitmapProcState_opts_ssse3.cpp'].flags += skia_ssse3_flags + SOURCES['skia/src/core/SkBlitMask_opts_ssse3.cpp'].flags += skia_ssse3_flags + SOURCES['skia/src/core/SkSwizzler_opts_ssse3.cpp'].flags += ['-Dskvx=skvx_ssse3'] +diff -up firefox-145.0/toolkit/components/terminator/nsTerminator.cpp.pgo firefox-145.0/toolkit/components/terminator/nsTerminator.cpp +--- firefox-145.0/toolkit/components/terminator/nsTerminator.cpp.pgo 2025-11-03 16:57:15.000000000 +0100 ++++ firefox-145.0/toolkit/components/terminator/nsTerminator.cpp 2025-11-05 13:59:53.478238011 +0100 +@@ -330,6 +330,11 @@ void nsTerminator::StartWatchdog() { } #endif diff --git a/rhbz-1173156.patch b/rhbz-1173156.patch index c35d901..067b561 100644 --- a/rhbz-1173156.patch +++ b/rhbz-1173156.patch @@ -1,12 +1,12 @@ -diff -up firefox-60.5.0/extensions/auth/nsAuthSambaNTLM.cpp.rhbz-1173156 firefox-60.5.0/extensions/auth/nsAuthSambaNTLM.cpp ---- firefox-60.5.0/extensions/auth/nsAuthSambaNTLM.cpp.rhbz-1173156 2019-01-22 10:36:09.284069020 +0100 -+++ firefox-60.5.0/extensions/auth/nsAuthSambaNTLM.cpp 2019-01-22 10:37:12.669757744 +0100 -@@ -161,7 +161,7 @@ nsresult nsAuthSambaNTLM::SpawnNTLMAuthH - const char* username = PR_GetEnv("USER"); - if (!username) return NS_ERROR_FAILURE; +diff -up firefox-132.0/extensions/auth/nsAuthSambaNTLM.cpp.rhbz-1173156 firefox-132.0/extensions/auth/nsAuthSambaNTLM.cpp +--- firefox-132.0/extensions/auth/nsAuthSambaNTLM.cpp.rhbz-1173156 2024-10-23 09:26:41.433895188 +0200 ++++ firefox-132.0/extensions/auth/nsAuthSambaNTLM.cpp 2024-10-23 10:05:11.025801336 +0200 +@@ -153,7 +153,7 @@ nsresult nsAuthSambaNTLM::SpawnNTLMAuthH + options.fds_to_remap.push_back( + std::pair{fromChildPipeWrite.get(), STDOUT_FILENO}); + +- std::vector argvVec{"ntlm_auth", "--helper-protocol", ++ std::vector argvVec{"/usr/bin/ntlm_auth", "--helper-protocol", + "ntlmssp-client-1", "--use-cached-creds", + "--username", username}; -- const char* const args[] = {"ntlm_auth", -+ const char* const args[] = {"/usr/bin/ntlm_auth", - "--helper-protocol", - "ntlmssp-client-1", - "--use-cached-creds", diff --git a/rhbz-1219542-s390-build.patch b/rhbz-1219542-s390-build.patch deleted file mode 100644 index f94e43a..0000000 --- a/rhbz-1219542-s390-build.patch +++ /dev/null @@ -1,23 +0,0 @@ -diff -up firefox-55.0/js/src/old-configure.in.rhbz-1219542-s390 firefox-55.0/js/src/old-configure.in ---- firefox-55.0/js/src/old-configure.in.rhbz-1219542-s390 2017-07-31 18:20:48.000000000 +0200 -+++ firefox-55.0/js/src/old-configure.in 2017-08-02 14:31:32.190243669 +0200 -@@ -541,7 +541,7 @@ case "$host" in - - *-linux*|*-kfreebsd*-gnu|*-gnu*) - HOST_CFLAGS="$HOST_CFLAGS -DXP_UNIX" -- HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O3}" -+ HOST_OPTIMIZE_FLAGS="${HOST_OPTIMIZE_FLAGS=-O1}" - ;; - - *) -@@ -617,8 +617,8 @@ case "$target" in - - *-*linux*) - if test "$GNU_CC" -o "$GNU_CXX"; then -- MOZ_PGO_OPTIMIZE_FLAGS="-O3" -- MOZ_OPTIMIZE_FLAGS="-O3" -+ MOZ_PGO_OPTIMIZE_FLAGS="-O1" -+ MOZ_OPTIMIZE_FLAGS="-O1" - if test -z "$CLANG_CC"; then - MOZ_OPTIMIZE_FLAGS="-freorder-blocks $MOZ_OPTIMIZE_FLAGS" - fi diff --git a/rhbz-1400293-fix-mozilla-1324096.patch b/rhbz-1400293-fix-mozilla-1324096.patch deleted file mode 100644 index 4a2691e..0000000 --- a/rhbz-1400293-fix-mozilla-1324096.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff --git a/security/certverifier/CertVerifier.cpp b/security/certverifier/CertVerifier.cpp ---- a/security/certverifier/CertVerifier.cpp -+++ b/security/certverifier/CertVerifier.cpp -@@ -120,16 +120,20 @@ IsCertChainRootBuiltInRoot(const UniqueC - } - CERTCertificate* root = rootNode->cert; - if (!root) { - return Result::FATAL_ERROR_LIBRARY_FAILURE; - } - return IsCertBuiltInRoot(root, result); - } - -+// The term "builtin root" traditionally refers to a root CA certificate that -+// has been added to the NSS trust store, because it has been approved -+// for inclusion according to the Mozilla CA policy, and might be accepted -+// by Mozilla applications as an issuer for certificates seen on the public web. - Result - IsCertBuiltInRoot(CERTCertificate* cert, bool& result) - { - result = false; - #ifdef DEBUG - nsCOMPtr component(do_GetService(PSM_COMPONENT_CONTRACTID)); - if (!component) { - return Result::FATAL_ERROR_LIBRARY_FAILURE; -@@ -142,25 +146,38 @@ IsCertBuiltInRoot(CERTCertificate* cert, - return Success; - } - #endif // DEBUG - AutoSECMODListReadLock lock; - for (SECMODModuleList* list = SECMOD_GetDefaultModuleList(); list; - list = list->next) { - for (int i = 0; i < list->module->slotCount; i++) { - PK11SlotInfo* slot = list->module->slots[i]; -- // PK11_HasRootCerts should return true if and only if the given slot has -- // an object with a CKA_CLASS of CKO_NETSCAPE_BUILTIN_ROOT_LIST, which -- // should be true only of the builtin root list. -- // If we can find a copy of the given certificate on the slot with the -- // builtin root list, that certificate must be a builtin. -- if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot) && -- PK11_FindCertInSlot(slot, cert, nullptr) != CK_INVALID_HANDLE) { -- result = true; -- return Success; -+ // We're searching for the "builtin root module", which is a module that -+ // contains an object with a CKA_CLASS of CKO_NETSCAPE_BUILTIN_ROOT_LIST. -+ // We use PK11_HasRootCerts() to identify a module with that property. -+ // In the past, we exclusively used the PKCS#11 module named nssckbi, -+ // which is provided by the NSS library. -+ // Nowadays, some distributions use a replacement module, which contains -+ // the builtin roots, but which also contains additional CA certificates, -+ // such as CAs trusted in a local deployment. -+ // We want to be able to distinguish between these two categories, -+ // because a CA, which may issue certificates for the public web, -+ // is expected to comply with additional requirements. -+ // If the certificate has attribute CKA_NSS_MOZILLA_CA_POLICY set to true, -+ // then we treat it as a "builtin root". -+ if (PK11_IsPresent(slot) && PK11_HasRootCerts(slot)) { -+ CK_OBJECT_HANDLE handle = PK11_FindCertInSlot(slot, cert, nullptr); -+ if (handle != CK_INVALID_HANDLE && -+ PK11_HasAttributeSet(slot, handle, CKA_NSS_MOZILLA_CA_POLICY, -+ false)) { -+ // Attribute was found, and is set to true -+ result = true; -+ break; -+ } - } - } - } - return Success; - } - - static Result - BuildCertChainForOneKeyUsage(NSSCertDBTrustDomain& trustDomain, Input certDER, diff --git a/run-wayland-compositor b/run-wayland-compositor index 0480ed2..2ac9f69 100755 --- a/run-wayland-compositor +++ b/run-wayland-compositor @@ -20,21 +20,24 @@ if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then # if not found, launch a new one eval `dbus-launch --sh-syntax` fi -eval `echo '' | /usr/bin/gnome-keyring-daemon -r -d --unlock --components=secrets` if [ -z "$XDG_RUNTIME_DIR" ]; then export XDG_RUNTIME_DIR=$HOME fi -. xvfb-run -s "-screen 0 1600x1200x24" -n 80 mutter --display=:80 --wayland --nested & -export DISPLAY=:80 - -if [ -z "$WAYLAND_DISPLAY" ] ; then - export WAYLAND_DISPLAY=wayland-0 -else - export WAYLAND_DISPLAY=wayland-1 +export WAYLAND_DISPLAY=firefox-pgo-wayland-0 +if [ -S "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" ]; then + rm -f $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY + rm -f $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY.lock fi -sleep 10 + +echo "Launch mutter for $WAYLAND_DISPLAY" +mutter --headless --virtual-monitor 1920x1080 --wayland-display=$WAYLAND_DISPLAY --no-x11 & MUTTER_PID=$! +export MUTTER_PID +echo "Mutter PID $MUTTER_PID" + +echo "Waiting for mutter to start..." +sleep 5 retry_count=0 max_retries=5 until [ $retry_count -gt $max_retries ]; do @@ -47,4 +50,10 @@ until [ $retry_count -gt $max_retries ]; do fi done -env | grep "DISPLAY" +if [ ! -S "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" ]; then + echo "Mutter failed to start!" + exit 1 +fi + +echo "Mutter is running, $XDG_RUNTIME_DIR/$WAYLAND_DISPLAY is here." + diff --git a/rust-thirdparty-checksum-fix.patch b/rust-thirdparty-checksum-fix.patch deleted file mode 100644 index 8047ea8..0000000 --- a/rust-thirdparty-checksum-fix.patch +++ /dev/null @@ -1,6 +0,0 @@ -diff -up firefox-72.0/third_party/rust/backtrace-sys/.cargo-checksum.json.checksum-fix firefox-72.0/third_party/rust/backtrace-sys/.cargo-checksum.json ---- firefox-72.0/third_party/rust/backtrace-sys/.cargo-checksum.json.checksum-fix 2020-01-07 10:55:14.265047927 +0100 -+++ firefox-72.0/third_party/rust/backtrace-sys/.cargo-checksum.json 2020-01-07 10:55:18.109059804 +0100 -@@ -1 +1 @@ --{"files":{"Cargo.toml":"d7b29a5b7e31bc0ffb83473b2f78041527903740402c1a6394329857045174f7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","build.rs":"0fe1e551ab35e7589f96979cf1d366561b62925e9c7da6249c25f25684ce9ede","src/lib.rs":"cb45ba047240bceac6ea74da50c2f48ae81a965b578c833a766a3ea0db1075f3","src/libbacktrace/LICENSE":"ef8a9b3247488f8901ca60de9b17b745d7bd67e5ec1e622f80d62364572200d8","src/libbacktrace/Makefile.am":"5353e0ce3a4732b42ccf031c474f7234336992cb23ba76cbfda3aa5262e69988","src/libbacktrace/Makefile.in":"1802d55fa8ef616a407c69311b3fa4e579093d124a215c834149ab1c50b4f3ad","src/libbacktrace/Mark.Twain-Tom.Sawyer.txt":"461eb7cb2d57d293fc680c836464c9125e4382be3596f7d415093ae9db8fcb0e","src/libbacktrace/README.md":"3b27ca2f7ddaf464ad81366a278ed4d34ad513de3766b330a51464828fa3131f","src/libbacktrace/acinclude.m4":"7f1d64805039b0e41d4c4106265618a6f8921d3cf091d64ab31fa7b900dc892f","src/libbacktrace/aclocal.m4":"4899cfe70722ba1de2b42b4e9965c1db1b173b5d6d4522cdc785becd5a5c212c","src/libbacktrace/alloc.c":"33891bbaf755c050058f8fd7dd3708e6062ef65245a0717216af45b78bab0fd0","src/libbacktrace/atomic.c":"82fd23c7ee7154d1ce4fc823637ede9cfa0e469f4073f38fff4dd9081070f1aa","src/libbacktrace/backtrace-supported.h.in":"42277f3c383386b6cfa3d3d889336e92303fac0ae1a9fb8a6a56737245dfb8f3","src/libbacktrace/backtrace.c":"837ea7b781a737d1ed37e4d03c463bcbe1432b2dc3b79b37344b21013cdfcca4","src/libbacktrace/backtrace.h":"9f035b3830c1c6000259c8ecf0bf53144f7c2e6064dfc95975b89f7f612ebf0e","src/libbacktrace/btest.c":"41c774496d58177e408b1dc33d6a792d0940634885978eed73fb192f732cafc5","src/libbacktrace/config.guess":"9be3de218833c076786b919dc34aab691611f4cd73316e7705f2673e2c41921b","src/libbacktrace/config.h.in":"b5002d9f96f6a26f54317f9d23a5ffff71fa3ee520fd8993810891d43b9a9bf7","src/libbacktrace/config.sub":"c8e70ab53f04d2f2b0280aa0e8a5432e90a902bfa2af7b0854168eb1fb3a84c0","src/libbacktrace/config/libtool.m4":"644ce34d5e9fcc544f3ef5c707f4cb29add798bbfc24e29932b55fb251e50353","src/libbacktrace/config/ltoptions.m4":"9d294950c4d97e2c891d472933113f397d410ef2a8ed875d714f81761626bbd8","src/libbacktrace/config/ltsugar.m4":"2c6618a04aa6389a2a528cde2e69ed5de55acc6c50892b486ea3e56e4e5b2c3b","src/libbacktrace/config/ltversion.m4":"8d129a46367fadad9f202dac50e708696d4d628313d01745127388e9c736e996","src/libbacktrace/config/lt~obsolete.m4":"c6c668594337aafef7d59f585bce7010436153815fe341461d81301a2235b959","src/libbacktrace/configure":"59763fc255248b54fba5d0761d61093a73d51fa4cb400b0df1b5f339b9c2f48a","src/libbacktrace/configure.ac":"b9292548330eb4d2cb014e9d9e6cd4df656aed982917365896a8f2534e9732e5","src/libbacktrace/dwarf.c":"c2103af5f94dd135e5df2a98dfc28ef2cbe0f3d56783d21e1487b9f314bfcbbc","src/libbacktrace/edtest.c":"947b9878ae45f6ba95d3b949bb080e9feed4ffdb27536cf5602b81ce79556ccf","src/libbacktrace/edtest2.c":"964bb0bb510a19013fb1cb56552929ed15cf55787eba4369d5820b74be07d249","src/libbacktrace/elf.c":"fe3e10d33c0c0965f016381302128ce82d664071095ad5077932377e3a789679","src/libbacktrace/fileline.c":"7b3b92044648f45becc498d4ed41ddc8ec08f0d11f6491cc05cfccd8a4d7627a","src/libbacktrace/filenames.h":"2c23cde7dd12dd9e0343cb37b5066036112deca703b61178f07c01f3e01398c9","src/libbacktrace/filetype.awk":"aa38776487a77dc13c93efa2a861204b384c3c4333501ed9bdb4ccbde2a784c0","src/libbacktrace/install-sh":"e7064b5e01a8d173409749c337966698fa04661cde1e3ef1a93be250eec0d2c3","src/libbacktrace/internal.h":"88c63ad6acc7e68330df3028675be4d4e3374bd787255fe22dd3febbbbc438b6","src/libbacktrace/ltmain.sh":"873bdcbc8690bd90c0f3632aac40027e880fd95ea45fb5a02ed901fea4afa4fe","src/libbacktrace/macho.c":"9a8864901eede4c34305b05bb6e815b25b76f04b59caf74381ca9dfbe8f1a8c4","src/libbacktrace/missing":"300bea3fb273b763eca2e4bb1576c663605d9b49de385fd375f82be8d912f506","src/libbacktrace/mmap.c":"5be917f3e9eba1fe49eb1bb391e28609e8377b4ce4593cace6012bf17434a33c","src/libbacktrace/mmapio.c":"be5719c4f92e70045fe6014a0493a5b4adc165ecde42c20130ea6e9da1ce978f","src/libbacktrace/move-if-change":"689762b92d23003926ba729acf98b9a109abf46de0698c09ddfa0d20490d8af5","src/libbacktrace/nounwind.c":"5eee9cc7298b7d0d2aea68eef62175541f34f88acf17736e0612056c5bb7318d","src/libbacktrace/pecoff.c":"bb536ae71a1a1c4dad5508d26032e7e81860df6d8ddfc8d696378ebefbc513b1","src/libbacktrace/posix.c":"f5e0ff701a1a1e29a25462ea49f174b049dafc6c25e040ee0eb77dd189353277","src/libbacktrace/print.c":"2d446406c8e2d9a1258d46d119be1c563bd86b6a4039cbf773b6de09c541390d","src/libbacktrace/read.c":"d0d4007f681f265a6c31e27ded45f4007502c90464eefdb4e80b69e4ae2ede28","src/libbacktrace/simple.c":"b0f767d3740195015aeadaa67e84bf6eb255a730f258485ca86bdbe02b066eca","src/libbacktrace/sort.c":"a82f911fc826a353ea5616379748dfa318ad4e57e20791af7ead853f7e73583d","src/libbacktrace/state.c":"a45abbe4077a47d17fb9687057c40828e633df12d21b8ed40b71a78d86918100","src/libbacktrace/stest.c":"7443fe435f1ee5ce49a3e634faf81a4137d66a057577fe88a211cfa819ddb2e2","src/libbacktrace/testlib.c":"a7e096e895b36db7f997a6673ce48f92a032046876511e813a8a52de6079b29a","src/libbacktrace/testlib.h":"02e02404dc89dd4f3dd82635f794a927541dd78d490d777bedf8a5424e5033fc","src/libbacktrace/ttest.c":"380f3b2be164bd6770768181fa05f1778cee8f0322434896d19724ae7cd105df","src/libbacktrace/unknown.c":"d2d148ea045dcad96ba1c5528b7036b000eeb8439ae397bca01deb0d8b287972","src/libbacktrace/xcoff.c":"e70ed97743306f71ea6132a058d68f1bb7be1380a2d38725b5dc877f5e07905d","src/libbacktrace/ztest.c":"7ad8277664e596aecb6af25818b7671e199ef6002ec2c38d9288179c5cad2082","symbol-map":"c81ced08aa32f0edb1d0ed6e4aaf5d3d516f8c158417d2ba3fa36b45b6ae08fd"},"package":"c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"} -+{"files":{"Cargo.toml":"d7b29a5b7e31bc0ffb83473b2f78041527903740402c1a6394329857045174f7","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","build.rs":"0fe1e551ab35e7589f96979cf1d366561b62925e9c7da6249c25f25684ce9ede","src/lib.rs":"cb45ba047240bceac6ea74da50c2f48ae81a965b578c833a766a3ea0db1075f3","src/libbacktrace/LICENSE":"ef8a9b3247488f8901ca60de9b17b745d7bd67e5ec1e622f80d62364572200d8","src/libbacktrace/Makefile.am":"5353e0ce3a4732b42ccf031c474f7234336992cb23ba76cbfda3aa5262e69988","src/libbacktrace/Makefile.in":"1802d55fa8ef616a407c69311b3fa4e579093d124a215c834149ab1c50b4f3ad","src/libbacktrace/Mark.Twain-Tom.Sawyer.txt":"461eb7cb2d57d293fc680c836464c9125e4382be3596f7d415093ae9db8fcb0e","src/libbacktrace/README.md":"3b27ca2f7ddaf464ad81366a278ed4d34ad513de3766b330a51464828fa3131f","src/libbacktrace/acinclude.m4":"7f1d64805039b0e41d4c4106265618a6f8921d3cf091d64ab31fa7b900dc892f","src/libbacktrace/aclocal.m4":"4899cfe70722ba1de2b42b4e9965c1db1b173b5d6d4522cdc785becd5a5c212c","src/libbacktrace/alloc.c":"33891bbaf755c050058f8fd7dd3708e6062ef65245a0717216af45b78bab0fd0","src/libbacktrace/atomic.c":"82fd23c7ee7154d1ce4fc823637ede9cfa0e469f4073f38fff4dd9081070f1aa","src/libbacktrace/backtrace-supported.h.in":"42277f3c383386b6cfa3d3d889336e92303fac0ae1a9fb8a6a56737245dfb8f3","src/libbacktrace/backtrace.c":"837ea7b781a737d1ed37e4d03c463bcbe1432b2dc3b79b37344b21013cdfcca4","src/libbacktrace/backtrace.h":"9f035b3830c1c6000259c8ecf0bf53144f7c2e6064dfc95975b89f7f612ebf0e","src/libbacktrace/btest.c":"41c774496d58177e408b1dc33d6a792d0940634885978eed73fb192f732cafc5","src/libbacktrace/config.guess":"0913c6ce799fbfca156ae5fb55fc2e5950808b4d1435e71c6a8b768e54424052","src/libbacktrace/config.h.in":"b5002d9f96f6a26f54317f9d23a5ffff71fa3ee520fd8993810891d43b9a9bf7","src/libbacktrace/config.sub":"c8e70ab53f04d2f2b0280aa0e8a5432e90a902bfa2af7b0854168eb1fb3a84c0","src/libbacktrace/config/libtool.m4":"644ce34d5e9fcc544f3ef5c707f4cb29add798bbfc24e29932b55fb251e50353","src/libbacktrace/config/ltoptions.m4":"9d294950c4d97e2c891d472933113f397d410ef2a8ed875d714f81761626bbd8","src/libbacktrace/config/ltsugar.m4":"2c6618a04aa6389a2a528cde2e69ed5de55acc6c50892b486ea3e56e4e5b2c3b","src/libbacktrace/config/ltversion.m4":"8d129a46367fadad9f202dac50e708696d4d628313d01745127388e9c736e996","src/libbacktrace/config/lt~obsolete.m4":"c6c668594337aafef7d59f585bce7010436153815fe341461d81301a2235b959","src/libbacktrace/configure":"59763fc255248b54fba5d0761d61093a73d51fa4cb400b0df1b5f339b9c2f48a","src/libbacktrace/configure.ac":"b9292548330eb4d2cb014e9d9e6cd4df656aed982917365896a8f2534e9732e5","src/libbacktrace/dwarf.c":"c2103af5f94dd135e5df2a98dfc28ef2cbe0f3d56783d21e1487b9f314bfcbbc","src/libbacktrace/edtest.c":"947b9878ae45f6ba95d3b949bb080e9feed4ffdb27536cf5602b81ce79556ccf","src/libbacktrace/edtest2.c":"964bb0bb510a19013fb1cb56552929ed15cf55787eba4369d5820b74be07d249","src/libbacktrace/elf.c":"fe3e10d33c0c0965f016381302128ce82d664071095ad5077932377e3a789679","src/libbacktrace/fileline.c":"7b3b92044648f45becc498d4ed41ddc8ec08f0d11f6491cc05cfccd8a4d7627a","src/libbacktrace/filenames.h":"2c23cde7dd12dd9e0343cb37b5066036112deca703b61178f07c01f3e01398c9","src/libbacktrace/filetype.awk":"aa38776487a77dc13c93efa2a861204b384c3c4333501ed9bdb4ccbde2a784c0","src/libbacktrace/install-sh":"e7064b5e01a8d173409749c337966698fa04661cde1e3ef1a93be250eec0d2c3","src/libbacktrace/internal.h":"88c63ad6acc7e68330df3028675be4d4e3374bd787255fe22dd3febbbbc438b6","src/libbacktrace/ltmain.sh":"873bdcbc8690bd90c0f3632aac40027e880fd95ea45fb5a02ed901fea4afa4fe","src/libbacktrace/macho.c":"9a8864901eede4c34305b05bb6e815b25b76f04b59caf74381ca9dfbe8f1a8c4","src/libbacktrace/missing":"300bea3fb273b763eca2e4bb1576c663605d9b49de385fd375f82be8d912f506","src/libbacktrace/mmap.c":"5be917f3e9eba1fe49eb1bb391e28609e8377b4ce4593cace6012bf17434a33c","src/libbacktrace/mmapio.c":"be5719c4f92e70045fe6014a0493a5b4adc165ecde42c20130ea6e9da1ce978f","src/libbacktrace/move-if-change":"689762b92d23003926ba729acf98b9a109abf46de0698c09ddfa0d20490d8af5","src/libbacktrace/nounwind.c":"5eee9cc7298b7d0d2aea68eef62175541f34f88acf17736e0612056c5bb7318d","src/libbacktrace/pecoff.c":"bb536ae71a1a1c4dad5508d26032e7e81860df6d8ddfc8d696378ebefbc513b1","src/libbacktrace/posix.c":"f5e0ff701a1a1e29a25462ea49f174b049dafc6c25e040ee0eb77dd189353277","src/libbacktrace/print.c":"2d446406c8e2d9a1258d46d119be1c563bd86b6a4039cbf773b6de09c541390d","src/libbacktrace/read.c":"d0d4007f681f265a6c31e27ded45f4007502c90464eefdb4e80b69e4ae2ede28","src/libbacktrace/simple.c":"b0f767d3740195015aeadaa67e84bf6eb255a730f258485ca86bdbe02b066eca","src/libbacktrace/sort.c":"a82f911fc826a353ea5616379748dfa318ad4e57e20791af7ead853f7e73583d","src/libbacktrace/state.c":"a45abbe4077a47d17fb9687057c40828e633df12d21b8ed40b71a78d86918100","src/libbacktrace/stest.c":"7443fe435f1ee5ce49a3e634faf81a4137d66a057577fe88a211cfa819ddb2e2","src/libbacktrace/testlib.c":"a7e096e895b36db7f997a6673ce48f92a032046876511e813a8a52de6079b29a","src/libbacktrace/testlib.h":"02e02404dc89dd4f3dd82635f794a927541dd78d490d777bedf8a5424e5033fc","src/libbacktrace/ttest.c":"380f3b2be164bd6770768181fa05f1778cee8f0322434896d19724ae7cd105df","src/libbacktrace/unknown.c":"d2d148ea045dcad96ba1c5528b7036b000eeb8439ae397bca01deb0d8b287972","src/libbacktrace/xcoff.c":"e70ed97743306f71ea6132a058d68f1bb7be1380a2d38725b5dc877f5e07905d","src/libbacktrace/ztest.c":"7ad8277664e596aecb6af25818b7671e199ef6002ec2c38d9288179c5cad2082","symbol-map":"c81ced08aa32f0edb1d0ed6e4aaf5d3d516f8c158417d2ba3fa36b45b6ae08fd"},"package":"c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"} diff --git a/sources b/sources index 39a05eb..b87ab2c 100644 --- a/sources +++ b/sources @@ -1,4 +1,7 @@ -SHA512 (cbindgen-vendor.tar.xz) = b9ab1498be90ecf60822df7021f8812f124550d97f8cd687c69d3ab56fc5fb714bfe88c78c978a1794d211724909a9a5cad6a4b483fa05f762909c45d5075520 -SHA512 (mochitest-python.tar.gz) = 18e1aeb475df5fbf1fe3838897d5ac2f3114aa349030713fc2be27af087b1b12f57642621b87bd052f324a7cb7fbae5f36b21502191d85692f62c8cdd69c8bf2 -SHA512 (firefox-101.0.source.tar.xz) = fffe7e0940c1443fcdc5b205677764cb4e04b29f33fcfafb2857d383700584f309806b81fc4989efb56cc12a3cca1ff7d451b647050c43e98777b5c952ed5d56 -SHA512 (firefox-langpacks-101.0-20220530.tar.xz) = aa81113b6aef965aa17921d563759da6c499021b6f471369d998c35802f72e79a107080b4df59ca51dae15ac464176f23bce2fc84942f5852e810d963553b687 +SHA512 (mochitest-python.tar.gz) = 089b1593068b76f4572af0086eaccf52a6a1299bfffb58593206d19bf021ae381f2380bbfeb4371586cd53706ff6dde3d240238b2caf19b96c57dfc2f4524e36 +SHA512 (dump_syms-vendor.tar.xz) = ee0ea52aac781b8dd48936a3d13b140bd725a48cc488d23693b68edbe3bcfba5723022dba3c3849d0da1bacf0e37ddd307cfc56304159f91b71495ce8a08b54a +SHA512 (wasi-sdk-25.tar.gz) = 1285981d26aa5eff27f08ed4b409909639ddcd62c94ee0cff7093ef68722f4b024c099ca3aa3ab50411e9aace13b86f1f30c5e08a3fc58b6a46b87369d6904aa +SHA512 (wasm-component-ld-vendor.tar.xz) = 707d942d31455ae0a4f68bf419fb09a20407b6747f831ca554dcd00925b7ea98ef4d03a8652b6d2ae54cf48d7ad15d85aa7eb8d0778ef66b89593eaa8b5c3465 +SHA512 (cbindgen-vendor.tar.xz) = bea420e66bdd1c7c944655dd3e01abd6e7d6ac4b245c7ee190f31d800f7786f21e5cae11715b479bf795f4369d18c40dc12df19e0b643664f2f78e5c8a681415 +SHA512 (firefox-langpacks-147.0-20260106.tar.xz) = 4006c6e8dda8722509c1d1756807373d431d75b20d5a0c3f19e72a2a0dc76df62b15ef871e3fff2d30b2682e6a56b4a4541d8445ea1b83641559a3270e0057b7 +SHA512 (firefox-147.0.source.tar.xz) = ac9017b1a2da7b2f139392c394c36341fd3476e3d4ea1a3c7e5e7bf100dc30d185132ef9256be7e6b0f9dbfc69234ac571ea1fc6db9d84543b15772f4ec85161 diff --git a/wasi.patch b/wasi.patch new file mode 100644 index 0000000..0a83f8c --- /dev/null +++ b/wasi.patch @@ -0,0 +1,35 @@ +diff -up firefox-134.0.1/toolkit/moz.configure.wasi firefox-134.0.1/toolkit/moz.configure +--- firefox-134.0.1/toolkit/moz.configure.wasi 2025-01-13 14:46:04.000000000 +0100 ++++ firefox-134.0.1/toolkit/moz.configure 2025-01-17 08:39:38.870092763 +0100 +@@ -2767,7 +2776,7 @@ with only_when(requires_wasm_sandboxing + def wasi_sysroot_flags(wasi_sysroot): + if wasi_sysroot: + log.info("Using wasi sysroot in %s", wasi_sysroot) +- return ["--sysroot=%s" % wasi_sysroot] ++ return ["--sysroot=%s" % wasi_sysroot, "-nodefaultlibs", "-lc", "-lwasi-emulated-process-clocks", "-lc++", "-lc++abi", "/raid/CVS/firefox/firefox-147.0-build/firefox-147.0/wasi-sdk-25/build/sysroot/install/wasi-resource-dir/lib/wasi/libclang_rt.builtins-wasm32.a"] + return [] + + set_config("WASI_SYSROOT", wasi_sysroot) +diff -up firefox-134.0.1/wasi-sdk-25/cmake/wasi-sdk-toolchain.cmake.wasi firefox-134.0.1/wasi-sdk-25/cmake/wasi-sdk-toolchain.cmake +--- firefox-134.0.1/wasi-sdk-25/cmake/wasi-sdk-toolchain.cmake.wasi 2025-01-17 08:40:23.004159900 +0100 ++++ firefox-134.0.1/wasi-sdk-25/cmake/wasi-sdk-toolchain.cmake 2025-01-17 08:40:35.478178790 +0100 +@@ -126,7 +126,7 @@ endif() + add_custom_command( + OUTPUT ${wasm_component_ld} + COMMAND +- cargo install --root ${wasm_component_ld_root} ${rust_target_flag} ++ cargo install --offline --root ${wasm_component_ld_root} ${rust_target_flag} + wasm-component-ld@${wasm_component_ld_version} + COMMAND + cmake -E make_directory ${wasi_tmp_install}/bin +diff -up firefox-134.0.2/wasi-sdk-25/version.py.wasi firefox-134.0.2/wasi-sdk-25/version.py +--- firefox-134.0.2/wasi-sdk-25/version.py.wasi 2025-01-16 08:03:26.042654800 +0100 ++++ firefox-134.0.2/wasi-sdk-25/version.py 2025-01-22 14:08:34.563909971 +0100 +@@ -60,6 +60,7 @@ assert parse_git_version( + + + def git_version(): ++ return 25 + version = exec(['git', 'describe', '--long', '--candidates=999', + '--match=wasi-sdk-*', '--dirty=+m', f'--abbrev={GIT_REF_LEN}'], + os.path.dirname(sys.argv[0])) diff --git a/wasi.patch.template b/wasi.patch.template new file mode 100644 index 0000000..fe4aee9 --- /dev/null +++ b/wasi.patch.template @@ -0,0 +1,35 @@ +diff -up firefox-134.0.1/toolkit/moz.configure.wasi firefox-134.0.1/toolkit/moz.configure +--- firefox-134.0.1/toolkit/moz.configure.wasi 2025-01-13 14:46:04.000000000 +0100 ++++ firefox-134.0.1/toolkit/moz.configure 2025-01-17 08:39:38.870092763 +0100 +@@ -2767,7 +2776,7 @@ with only_when(requires_wasm_sandboxing + def wasi_sysroot_flags(wasi_sysroot): + if wasi_sysroot: + log.info("Using wasi sysroot in %s", wasi_sysroot) +- return ["--sysroot=%s" % wasi_sysroot] ++ return ["--sysroot=%s" % wasi_sysroot, "-nodefaultlibs", "-lc", "-lwasi-emulated-process-clocks", "-lc++", "-lc++abi", "LIBCLANG_RT_PLACEHOLDER"] + return [] + + set_config("WASI_SYSROOT", wasi_sysroot) +diff -up firefox-134.0.1/wasi-sdk-25/cmake/wasi-sdk-toolchain.cmake.wasi firefox-134.0.1/wasi-sdk-25/cmake/wasi-sdk-toolchain.cmake +--- firefox-134.0.1/wasi-sdk-25/cmake/wasi-sdk-toolchain.cmake.wasi 2025-01-17 08:40:23.004159900 +0100 ++++ firefox-134.0.1/wasi-sdk-25/cmake/wasi-sdk-toolchain.cmake 2025-01-17 08:40:35.478178790 +0100 +@@ -126,7 +126,7 @@ endif() + add_custom_command( + OUTPUT ${wasm_component_ld} + COMMAND +- cargo install --root ${wasm_component_ld_root} ${rust_target_flag} ++ cargo install --offline --root ${wasm_component_ld_root} ${rust_target_flag} + wasm-component-ld@${wasm_component_ld_version} + COMMAND + cmake -E make_directory ${wasi_tmp_install}/bin +diff -up firefox-134.0.2/wasi-sdk-25/version.py.wasi firefox-134.0.2/wasi-sdk-25/version.py +--- firefox-134.0.2/wasi-sdk-25/version.py.wasi 2025-01-16 08:03:26.042654800 +0100 ++++ firefox-134.0.2/wasi-sdk-25/version.py 2025-01-22 14:08:34.563909971 +0100 +@@ -60,6 +60,7 @@ assert parse_git_version( + + + def git_version(): ++ return 25 + version = exec(['git', 'describe', '--long', '--candidates=999', + '--match=wasi-sdk-*', '--dirty=+m', f'--abbrev={GIT_REF_LEN}'], + os.path.dirname(sys.argv[0]))