diff --git a/.firefox.metadata b/.firefox.metadata index 37c649f..61dcda4 100644 --- a/.firefox.metadata +++ b/.firefox.metadata @@ -1,6 +1,6 @@ 18a8f30a0356c751b8d0ea6f76e764cab13ee046 SOURCES/Python-2.7.13.tar.xz -0fa5a71ce2cb90ea4be719a92645aa09dff3721f SOURCES/firefox-60.4.0esr.source.tar.xz -9d86cb1d4ccc300f5033e3fdb87c8d5fe5cd4786 SOURCES/firefox-langpacks-60.4.0esr-20181205.tar.xz +f375ffedfc3f86695623becc28a9a6f382535d37 SOURCES/firefox-60.5.0esr.source.tar.xz +df0031b81c1cf73ed05a2c92b9e13d155b9bf6c5 SOURCES/firefox-langpacks-60.5.0esr-20190125.tar.xz 6724218efbb1f3fa14541cb2f255970b98446a45 SOURCES/firefox-symbolic.svg 0de63f863b158454b9429234b52ed28a397ec45c SOURCES/gtk3-private-3.22.26-1.el6.src.rpm e188ab1a444697bc649e223c28389d82ca94c472 SOURCES/libffi-3.0.13-18.el7_3.src.rpm diff --git a/.gitignore b/.gitignore index c45903b..a031e84 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ SOURCES/Python-2.7.13.tar.xz -SOURCES/firefox-60.4.0esr.source.tar.xz -SOURCES/firefox-langpacks-60.4.0esr-20181205.tar.xz +SOURCES/firefox-60.5.0esr.source.tar.xz +SOURCES/firefox-langpacks-60.5.0esr-20190125.tar.xz SOURCES/firefox-symbolic.svg SOURCES/gtk3-private-3.22.26-1.el6.src.rpm SOURCES/libffi-3.0.13-18.el7_3.src.rpm diff --git a/README.debrand b/README.debrand deleted file mode 100644 index 01c46d2..0000000 --- a/README.debrand +++ /dev/null @@ -1,2 +0,0 @@ -Warning: This package was configured for automatic debranding, but the changes -failed to apply. diff --git a/SOURCES/build-disable-elfhack.patch b/SOURCES/build-disable-elfhack.patch index 172ecf0..1db9bdf 100644 --- a/SOURCES/build-disable-elfhack.patch +++ b/SOURCES/build-disable-elfhack.patch @@ -1,12 +1,12 @@ -diff -up firefox-63.0/toolkit/moz.configure.disable-elfhack firefox-63.0/toolkit/moz.configure ---- firefox-63.0/toolkit/moz.configure.disable-elfhack 2018-10-18 13:35:35.870039190 +0200 -+++ firefox-63.0/toolkit/moz.configure 2018-10-18 13:36:41.682515492 +0200 -@@ -1010,7 +1010,7 @@ with only_when('--enable-compile-environ - help='Disable elf hacks') +diff -up firefox-60.4.0/toolkit/moz.configure.disable-elfhack firefox-60.4.0/toolkit/moz.configure +--- firefox-60.4.0/toolkit/moz.configure.disable-elfhack 2019-01-03 14:47:00.566556623 +0100 ++++ firefox-60.4.0/toolkit/moz.configure 2019-01-03 14:49:14.243887620 +0100 +@@ -1192,7 +1192,7 @@ with only_when(has_elfhack): + option('--disable-elf-hack', help='Disable elf hacks') - set_config('USE_ELF_HACK', -- depends_if('--enable-elf-hack')(lambda _: True)) -+ depends_if('--enable-elf-hack')(lambda _: False)) + set_config('USE_ELF_HACK', +- depends_if('--enable-elf-hack')(lambda _: True)) ++ depends_if('--enable-elf-hack')(lambda _: False)) @depends(check_build_environment) diff --git a/SOURCES/build-jit-atomic-always-lucky.patch b/SOURCES/build-jit-atomic-always-lucky.patch index 31bc5ec..ab99524 100644 --- a/SOURCES/build-jit-atomic-always-lucky.patch +++ b/SOURCES/build-jit-atomic-always-lucky.patch @@ -1,30 +1,12 @@ -diff -up firefox-57.0b5/js/src/jit/AtomicOperations.h.jit-atomic-lucky firefox-57.0b5/js/src/jit/AtomicOperations.h ---- firefox-57.0b5/js/src/jit/AtomicOperations.h.jit-atomic-lucky 2017-10-06 12:34:02.338973607 +0200 -+++ firefox-57.0b5/js/src/jit/AtomicOperations.h 2017-10-06 12:38:24.632622215 +0200 -@@ -415,7 +415,7 @@ AtomicOperations::isLockfreeJS(int32_t s +diff -up firefox-60.5.0/js/src/jit/AtomicOperations.h.jit-atomic-lucky firefox-60.5.0/js/src/jit/AtomicOperations.h +--- firefox-60.5.0/js/src/jit/AtomicOperations.h.jit-atomic-lucky 2019-01-22 10:20:27.993697161 +0100 ++++ firefox-60.5.0/js/src/jit/AtomicOperations.h 2019-01-22 10:23:15.337873762 +0100 +@@ -394,7 +394,7 @@ inline bool AtomicOperations::isLockfree #elif defined(__s390__) || defined(__s390x__) - # include "jit/none/AtomicOperations-feeling-lucky.h" + #include "jit/none/AtomicOperations-feeling-lucky.h" #else --# error "No AtomicOperations support provided for this platform" -+# include "jit/none/AtomicOperations-feeling-lucky.h" +-#error "No AtomicOperations support provided for this platform" ++#include "jit/none/AtomicOperations-feeling-lucky.h" #endif - #endif // jit_AtomicOperations_h -diff -up firefox-57.0b5/js/src/jit/none/AtomicOperations-feeling-lucky.h.jit-atomic-lucky firefox-57.0b5/js/src/jit/none/AtomicOperations-feeling-lucky.h ---- firefox-57.0b5/js/src/jit/none/AtomicOperations-feeling-lucky.h.jit-atomic-lucky 2017-09-19 06:18:28.000000000 +0200 -+++ firefox-57.0b5/js/src/jit/none/AtomicOperations-feeling-lucky.h 2017-10-06 12:34:02.338973607 +0200 -@@ -79,6 +79,14 @@ - # define GNUC_COMPATIBLE - #endif - -+#ifdef __s390__ -+# define GNUC_COMPATIBLE -+#endif -+ -+#ifdef __s390x__ -+# define GNUC_COMPATIBLE -+#endif -+ - // The default implementation tactic for gcc/clang is to use the newer - // __atomic intrinsics added for use in C++11 . Where that - // isn't available, we use GCC's older __sync functions instead. + #endif // jit_AtomicOperations_h diff --git a/SOURCES/build-nss-version.patch b/SOURCES/build-nss-version.patch index 58e62c9..94947f2 100644 --- a/SOURCES/build-nss-version.patch +++ b/SOURCES/build-nss-version.patch @@ -5,7 +5,7 @@ diff -up firefox-60.1.0/old-configure.in.nss-version firefox-60.1.0/old-configur _USE_SYSTEM_NSS=1 ) if test -n "$_USE_SYSTEM_NSS"; then -- AM_PATH_NSS(3.36.6, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) +- AM_PATH_NSS(3.36.7, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) + AM_PATH_NSS(3.36.0, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])]) fi diff --git a/SOURCES/firefox-disable-dbus-remote.patch b/SOURCES/firefox-disable-dbus-remote.patch deleted file mode 100644 index 33b21cb..0000000 --- a/SOURCES/firefox-disable-dbus-remote.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff -up firefox-60.1.0/toolkit/components/remote/moz.build.disable-dbus-remote firefox-60.1.0/toolkit/components/remote/moz.build ---- firefox-60.1.0/toolkit/components/remote/moz.build.disable-dbus-remote 2018-06-21 09:29:35.975729500 +0200 -+++ firefox-60.1.0/toolkit/components/remote/moz.build 2018-06-21 09:29:53.863631963 +0200 -@@ -22,11 +22,6 @@ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT'] - 'nsGTKRemoteService.cpp', - 'nsRemoteService.cpp', - ] -- if CONFIG['MOZ_ENABLE_DBUS']: -- SOURCES += [ -- 'nsDBusRemoteService.cpp', -- ] -- CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] - - FINAL_LIBRARY = 'xul' - -diff -up firefox-60.1.0/toolkit/components/remote/nsRemoteService.cpp.disable-dbus-remote firefox-60.1.0/toolkit/components/remote/nsRemoteService.cpp ---- firefox-60.1.0/toolkit/components/remote/nsRemoteService.cpp.disable-dbus-remote 2018-06-19 22:35:27.000000000 +0200 -+++ firefox-60.1.0/toolkit/components/remote/nsRemoteService.cpp 2018-06-21 09:30:24.949462465 +0200 -@@ -6,7 +6,7 @@ - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - #include "nsGTKRemoteService.h" --#ifdef MOZ_ENABLE_DBUS -+#if 0 // Disable DBus remote - #include "nsDBusRemoteService.h" - #endif - #include "nsRemoteService.h" -@@ -34,7 +34,7 @@ NS_IMPL_ISUPPORTS(nsRemoteService, - NS_IMETHODIMP - nsRemoteService::Startup(const char* aAppName, const char* aProfileName) - { --#if defined(MOZ_ENABLE_DBUS) -+#if 0 // Disable DBus remote - nsresult rv; - mDBusRemoteService = new nsDBusRemoteService(); - rv = mDBusRemoteService->Startup(aAppName, aProfileName); diff --git a/SOURCES/firefox-pipewire.patch b/SOURCES/firefox-pipewire.patch new file mode 100644 index 0000000..57bf8b4 --- /dev/null +++ b/SOURCES/firefox-pipewire.patch @@ -0,0 +1,2572 @@ +diff -up firefox-60.3.0/config/system-headers.mozbuild.pipewire firefox-60.3.0/config/system-headers.mozbuild +--- firefox-60.3.0/config/system-headers.mozbuild.pipewire 2018-10-17 22:39:27.000000000 +0200 ++++ firefox-60.3.0/config/system-headers.mozbuild 2019-01-07 14:53:17.200061752 +0100 +@@ -314,6 +314,7 @@ system_headers = [ + 'Gestalt.h', + 'getopt.h', + 'gio/gio.h', ++ 'gio/gunixfdlist.h', + 'glibconfig.h', + 'glib.h', + 'glib-object.h', +@@ -607,6 +608,7 @@ system_headers = [ + 'Pgenerr.h', + 'PGenErr.h', + 'Ph.h', ++ 'pipewire/pipewire.h', + 'pixman.h', + 'pk11func.h', + 'pk11pqg.h', +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc.pipewire 2019-01-07 14:53:17.200061752 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc 2019-01-07 14:53:17.200061752 +0100 +@@ -0,0 +1,39 @@ ++/* ++ * Copyright (c) 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 "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capturer.h" ++ ++#if defined(USE_X11) ++#include "webrtc/modules/desktop_capture/app_capturer_x11.h" ++#endif // defined(USE_X11) ++ ++namespace webrtc { ++ ++// static ++AppCapturer* AppCapturer::Create(const DesktopCaptureOptions& options) { ++#if defined(USE_X11) ++ return AppCapturerX11::Create(options); ++#endif // defined(USE_X11) ++ ++ return nullptr; ++} ++ ++// static ++std::unique_ptr DesktopCapturer::CreateRawAppCapturer( ++ const DesktopCaptureOptions& options) { ++#if defined(USE_X11) ++ return AppCapturerX11::CreateRawAppCapturer(options); ++#endif // defined(USE_X11) ++ ++ return nullptr; ++} ++ ++} // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc.pipewire 2018-10-17 22:39:32.000000000 +0200 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.cc 2019-01-07 14:53:17.201061764 +0100 +@@ -7,9 +7,6 @@ + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +-#include "webrtc/modules/desktop_capture/app_capturer.h" +-#include "webrtc/modules/desktop_capture/shared_desktop_frame.h" +-#include "webrtc/modules/desktop_capture/x11/shared_x_util.h" + + #include + #include +@@ -21,80 +18,19 @@ + + #include + ++#include "webrtc/modules/desktop_capture/app_capturer_x11.h" ++ + #include "webrtc/modules/desktop_capture/desktop_capture_options.h" + #include "webrtc/modules/desktop_capture/desktop_frame.h" + #include "webrtc/modules/desktop_capture/x11/shared_x_display.h" ++#include "webrtc/modules/desktop_capture/x11/shared_x_util.h" + #include "webrtc/modules/desktop_capture/x11/x_error_trap.h" + #include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h" + #include "webrtc/system_wrappers/include/logging.h" + + namespace webrtc { + +-namespace { +- +-class ScreenCapturerProxy : DesktopCapturer::Callback { +-public: +- ScreenCapturerProxy() +- : screen_capturer_(DesktopCapturer::CreateScreenCapturer(DesktopCaptureOptions::CreateDefault())) { +- screen_capturer_->SelectSource(kFullDesktopScreenId); +- screen_capturer_->Start(this); +- } +- void CaptureFrame() { screen_capturer_->CaptureFrame(); } +- std::unique_ptr GetFrame() { return std::move(frame_); } +- +- // Callback interface +- virtual void OnCaptureResult(DesktopCapturer::Result result, +- std::unique_ptr frame) { +- frame_ = std::move(frame); +- } +- +-protected: +- std::unique_ptr screen_capturer_; +- std::unique_ptr frame_; +-}; +- +-class AppCapturerLinux : public AppCapturer { +-public: +- AppCapturerLinux(const DesktopCaptureOptions& options); +- virtual ~AppCapturerLinux(); +- +- // AppCapturer interface. +- virtual bool GetAppList(AppList* apps) override; +- virtual bool SelectApp(ProcessId processId) override; +- virtual bool BringAppToFront() override; +- +- // DesktopCapturer interface. +- virtual void Start(Callback* callback) override; +- virtual void Stop() override; +- virtual void CaptureFrame() override; +- virtual bool SelectSource(SourceId id) override +- { +- return SelectApp(static_cast(id)); +- } +- +-protected: +- Display* GetDisplay() { return x_display_->display(); } +- bool UpdateRegions(); +- +- void FillDesktopFrameRegionWithColor(DesktopFrame* pDesktopFrame,Region rgn, uint32_t color); +-private: +- Callback* callback_; +- ProcessId selected_process_; +- +- // Sample Mode +- ScreenCapturerProxy screen_capturer_proxy_; +- // Mask of foreground (non-app windows in front of selected) +- Region rgn_mask_; +- // Region of selected windows +- Region rgn_visual_; +- // Mask of background (desktop, non-app windows behind selected) +- Region rgn_background_; +- +- rtc::scoped_refptr x_display_; +- RTC_DISALLOW_COPY_AND_ASSIGN(AppCapturerLinux); +-}; +- +-AppCapturerLinux::AppCapturerLinux(const DesktopCaptureOptions& options) ++AppCapturerX11::AppCapturerX11(const DesktopCaptureOptions& options) + : callback_(NULL), + selected_process_(0), + x_display_(options.x_display()) { +@@ -103,7 +39,7 @@ AppCapturerLinux::AppCapturerLinux(const + rgn_background_ = XCreateRegion(); + } + +-AppCapturerLinux::~AppCapturerLinux() { ++AppCapturerX11::~AppCapturerX11() { + if (rgn_mask_) { + XDestroyRegion(rgn_mask_); + } +@@ -116,32 +52,32 @@ AppCapturerLinux::~AppCapturerLinux() { + } + + // AppCapturer interface. +-bool AppCapturerLinux::GetAppList(AppList* apps) { ++bool AppCapturerX11::GetAppList(AppList* apps) { + // Implemented in DesktopDeviceInfo + return true; + } +-bool AppCapturerLinux::SelectApp(ProcessId processId) { ++bool AppCapturerX11::SelectApp(ProcessId processId) { + selected_process_ = processId; + return true; + } +-bool AppCapturerLinux::BringAppToFront() { ++bool AppCapturerX11::BringAppToFront() { + // Not implemented yet: See Bug 1036653 + return true; + } + + // DesktopCapturer interface. +-void AppCapturerLinux::Start(Callback* callback) { ++void AppCapturerX11::Start(Callback* callback) { + assert(!callback_); + assert(callback); + + callback_ = callback; + } + +-void AppCapturerLinux::Stop() { ++void AppCapturerX11::Stop() { + callback_ = NULL; + } + +-void AppCapturerLinux::CaptureFrame() { ++void AppCapturerX11::CaptureFrame() { + XErrorTrap error_trap(GetDisplay()); + + //Capture screen >> set root window as capture window +@@ -169,7 +105,7 @@ void AppCapturerLinux::CaptureFrame() { + } + } + +-void AppCapturerLinux::FillDesktopFrameRegionWithColor(DesktopFrame* pDesktopFrame, Region rgn, uint32_t color) { ++void AppCapturerX11::FillDesktopFrameRegionWithColor(DesktopFrame* pDesktopFrame, Region rgn, uint32_t color) { + XErrorTrap error_trap(GetDisplay()); + + if (!pDesktopFrame) { +@@ -192,7 +128,7 @@ void AppCapturerLinux::FillDesktopFrameR + } + } + +-bool AppCapturerLinux::UpdateRegions() { ++bool AppCapturerX11::UpdateRegions() { + XErrorTrap error_trap(GetDisplay()); + + XSubtractRegion(rgn_visual_, rgn_visual_, rgn_visual_); +@@ -269,21 +205,19 @@ bool AppCapturerLinux::UpdateRegions() { + return true; + } + +-} // namespace +- + // static +-AppCapturer* AppCapturer::Create(const DesktopCaptureOptions& options) { +- return new AppCapturerLinux(options); ++AppCapturer* AppCapturerX11::Create(const DesktopCaptureOptions& options) { ++ return new AppCapturerX11(options); + } + + // static +-std::unique_ptr DesktopCapturer::CreateRawAppCapturer( ++std::unique_ptr AppCapturerX11::CreateRawAppCapturer( + const DesktopCaptureOptions& options) { + + if (!options.x_display()) + return nullptr; + +- std::unique_ptr capturer(new AppCapturerLinux(options)); ++ std::unique_ptr capturer(new AppCapturerX11(options)); + + return std::unique_ptr(std::move(capturer)); + } +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.h.pipewire 2019-01-07 14:53:17.201061764 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_x11.h 2019-01-07 14:53:17.201061764 +0100 +@@ -0,0 +1,98 @@ ++/* ++ * 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_APP_CAPTURER_X11_H_ ++#define MODULES_DESKTOP_CAPTURE_APP_CAPTURER_X11_H_ ++ ++#include ++#include ++#include ++#include ++ ++#include "webrtc/modules/desktop_capture/app_capturer.h" ++#include "webrtc/modules/desktop_capture/shared_desktop_frame.h" ++#include "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capturer.h" ++#include "webrtc/modules/desktop_capture/desktop_geometry.h" ++#include "webrtc/modules/desktop_capture/x11/shared_x_display.h" ++#include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h" ++#include "webrtc/base/constructormagic.h" ++#include "webrtc/base/scoped_ref_ptr.h" ++ ++namespace webrtc { ++ ++class ScreenCapturerProxy : DesktopCapturer::Callback { ++public: ++ ScreenCapturerProxy() ++ : screen_capturer_(DesktopCapturer::CreateScreenCapturer(DesktopCaptureOptions::CreateDefault())) { ++ screen_capturer_->SelectSource(kFullDesktopScreenId); ++ screen_capturer_->Start(this); ++ } ++ void CaptureFrame() { screen_capturer_->CaptureFrame(); } ++ std::unique_ptr GetFrame() { return std::move(frame_); } ++ ++ // Callback interface ++ virtual void OnCaptureResult(DesktopCapturer::Result result, ++ std::unique_ptr frame) { ++ frame_ = std::move(frame); ++ } ++ ++protected: ++ std::unique_ptr screen_capturer_; ++ std::unique_ptr frame_; ++}; ++ ++class AppCapturerX11 : public AppCapturer { ++public: ++ AppCapturerX11(const DesktopCaptureOptions& options); ++ virtual ~AppCapturerX11(); ++ ++ static AppCapturer* Create(const DesktopCaptureOptions& options); ++ static std::unique_ptr CreateRawAppCapturer(const DesktopCaptureOptions& options); ++ ++ // AppCapturer interface. ++ virtual bool GetAppList(AppList* apps) override; ++ virtual bool SelectApp(ProcessId processId) override; ++ virtual bool BringAppToFront() override; ++ ++ // DesktopCapturer interface. ++ virtual void Start(Callback* callback) override; ++ virtual void Stop() override; ++ virtual void CaptureFrame() override; ++ virtual bool SelectSource(SourceId id) override ++ { ++ return SelectApp(static_cast(id)); ++ } ++ ++protected: ++ Display* GetDisplay() { return x_display_->display(); } ++ bool UpdateRegions(); ++ ++ void FillDesktopFrameRegionWithColor(DesktopFrame* pDesktopFrame,Region rgn, uint32_t color); ++private: ++ Callback* callback_; ++ ProcessId selected_process_; ++ ++ // Sample Mode ++ ScreenCapturerProxy screen_capturer_proxy_; ++ // Mask of foreground (non-app windows in front of selected) ++ Region rgn_mask_; ++ // Region of selected windows ++ Region rgn_visual_; ++ // Mask of background (desktop, non-app windows behind selected) ++ Region rgn_background_; ++ ++ rtc::scoped_refptr x_display_; ++ RTC_DISALLOW_COPY_AND_ASSIGN(AppCapturerX11); ++}; ++ ++} // namespace webrtc ++ ++#endif // MODULES_DESKTOP_CAPTURE_APP_CAPTURER_X11_H_ +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc.pipewire 2019-01-07 14:53:17.201061764 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc 2019-01-07 14:53:17.201061764 +0100 +@@ -0,0 +1,849 @@ ++/* ++ * 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 ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#include "webrtc/modules/desktop_capture/base_capturer_pipewire.h" ++ ++#include "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capturer.h" ++#include "webrtc/base/checks.h" ++#include "webrtc/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"; ++ ++const int kBytesPerPixelPw = 4; ++ ++// static ++void BaseCapturerPipeWire::OnStateChanged(void* data, ++ pw_remote_state old_state, ++ pw_remote_state state, ++ const char* error_message) { ++ BaseCapturerPipeWire* that = static_cast(data); ++ RTC_DCHECK(that); ++ ++ switch (state) { ++ case PW_REMOTE_STATE_ERROR: ++ LOG(LS_ERROR) << "PipeWire remote state error: " << error_message; ++ break; ++ case PW_REMOTE_STATE_CONNECTED: ++ LOG(LS_INFO) << "PipeWire remote state: connected."; ++ that->CreateReceivingStream(); ++ break; ++ case PW_REMOTE_STATE_CONNECTING: ++ LOG(LS_INFO) << "PipeWire remote state: connecting."; ++ break; ++ case PW_REMOTE_STATE_UNCONNECTED: ++ LOG(LS_INFO) << "PipeWire remote state: unconnected."; ++ break; ++ } ++} ++ ++// 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: ++ LOG(LS_ERROR) << "PipeWire stream state error: " << error_message; ++ break; ++ case PW_STREAM_STATE_CONFIGURE: ++ pw_stream_set_active(that->pw_stream_, true); ++ break; ++ case PW_STREAM_STATE_UNCONNECTED: ++ case PW_STREAM_STATE_CONNECTING: ++ case PW_STREAM_STATE_READY: ++ case PW_STREAM_STATE_PAUSED: ++ case PW_STREAM_STATE_STREAMING: ++ break; ++ } ++} ++ ++// static ++void BaseCapturerPipeWire::OnStreamFormatChanged( ++ void* data, ++ const struct spa_pod* format) { ++ BaseCapturerPipeWire* that = static_cast(data); ++ RTC_DCHECK(that); ++ ++ LOG(LS_INFO) << "PipeWire stream format changed."; ++ ++ if (!format) { ++ pw_stream_finish_format(that->pw_stream_, /*res=*/0, /*params=*/nullptr, ++ /*n_params=*/0); ++ return; ++ } ++ ++ that->spa_video_format_ = new spa_video_info_raw(); ++ spa_format_video_raw_parse(format, that->spa_video_format_, ++ &that->pw_type_->format_video); ++ ++ auto width = that->spa_video_format_->size.width; ++ auto height = that->spa_video_format_->size.height; ++ auto stride = SPA_ROUND_UP_N(width * kBytesPerPixelPw, 4); ++ auto size = height * stride; ++ ++ 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[2]; ++ params[0] = reinterpret_cast(spa_pod_builder_object( ++ &builder, ++ // id to enumerate buffer requirements ++ that->pw_core_type_->param.idBuffers, ++ that->pw_core_type_->param_buffers.Buffers, ++ // Size: specified as integer (i) and set to specified size ++ ":", that->pw_core_type_->param_buffers.size, "i", size, ++ // Stride: specified as integer (i) and set to specified stride ++ ":", that->pw_core_type_->param_buffers.stride, "i", stride, ++ // Buffers: specifies how many buffers we want to deal with, set as ++ // integer (i) where preferred number is 8, then allowed number is defined ++ // as range (r) from min and max values and it is undecided (u) to allow ++ // negotiation ++ ":", that->pw_core_type_->param_buffers.buffers, "iru", 8, ++ SPA_POD_PROP_MIN_MAX(1, 32), ++ // Align: memory alignment of the buffer, set as integer (i) to specified ++ // value ++ ":", that->pw_core_type_->param_buffers.align, "i", 16)); ++ params[1] = reinterpret_cast(spa_pod_builder_object( ++ &builder, ++ // id to enumerate supported metadata ++ that->pw_core_type_->param.idMeta, that->pw_core_type_->param_meta.Meta, ++ // Type: specified as id or enum (I) ++ ":", that->pw_core_type_->param_meta.type, "I", ++ that->pw_core_type_->meta.Header, ++ // Size: size of the metadata, specified as integer (i) ++ ":", that->pw_core_type_->param_meta.size, "i", ++ sizeof(struct spa_meta_header))); ++ ++ pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/2); ++} ++ ++// static ++void BaseCapturerPipeWire::OnStreamProcess(void* data) { ++ BaseCapturerPipeWire* that = static_cast(data); ++ RTC_DCHECK(that); ++ ++ pw_buffer* buf = nullptr; ++ ++ if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) { ++ return; ++ } ++ ++ that->HandleBuffer(buf); ++ ++ pw_stream_queue_buffer(that->pw_stream_, buf); ++} ++ ++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_type_) { ++ delete pw_type_; ++ } ++ ++ if (spa_video_format_) { ++ delete spa_video_format_; ++ } ++ ++ if (pw_stream_) { ++ pw_stream_destroy(pw_stream_); ++ } ++ ++ if (pw_remote_) { ++ pw_remote_destroy(pw_remote_); ++ } ++ ++ if (pw_core_) { ++ pw_core_destroy(pw_core_); ++ } ++ ++ if (pw_main_loop_) { ++ pw_thread_loop_destroy(pw_main_loop_); ++ } ++ ++ if (pw_loop_) { ++ pw_loop_destroy(pw_loop_); ++ } ++ ++ if (current_frame_) { ++ free(current_frame_); ++ } ++ ++ 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) { ++ 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 (proxy_) { ++ g_clear_object(&proxy_); ++ } ++} ++ ++void BaseCapturerPipeWire::InitPortals() { ++ g_dbus_proxy_new_for_bus( ++ G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, /*info=*/nullptr, ++ kDesktopBusName, kDesktopObjectPath, kScreenCastInterfaceName, ++ /*cancellable=*/nullptr, ++ reinterpret_cast(OnProxyRequested), this); ++} ++ ++void BaseCapturerPipeWire::InitPipeWire() { ++ pw_init(/*argc=*/nullptr, /*argc=*/nullptr); ++ ++ pw_loop_ = pw_loop_new(/*properties=*/nullptr); ++ pw_main_loop_ = pw_thread_loop_new(pw_loop_, "pipewire-main-loop"); ++ ++ pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr); ++ pw_core_type_ = pw_core_get_type(pw_core_); ++ pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0); ++ ++ InitPipeWireTypes(); ++ ++ // Initialize event handlers, remote end and stream-related. ++ pw_remote_events_.version = PW_VERSION_REMOTE_EVENTS; ++ pw_remote_events_.state_changed = &OnStateChanged; ++ ++ pw_stream_events_.version = PW_VERSION_STREAM_EVENTS; ++ pw_stream_events_.state_changed = &OnStreamStateChanged; ++ pw_stream_events_.format_changed = &OnStreamFormatChanged; ++ pw_stream_events_.process = &OnStreamProcess; ++ ++ pw_remote_add_listener(pw_remote_, &spa_remote_listener_, &pw_remote_events_, ++ this); ++ pw_remote_connect_fd(pw_remote_, pw_fd_); ++ ++ if (pw_thread_loop_start(pw_main_loop_) < 0) { ++ LOG(LS_ERROR) << "Failed to start main PipeWire loop"; ++ portal_init_failed_ = true; ++ } ++} ++ ++void BaseCapturerPipeWire::InitPipeWireTypes() { ++ spa_type_map* map = pw_core_type_->map; ++ pw_type_ = new PipeWireType(); ++ ++ spa_type_media_type_map(map, &pw_type_->media_type); ++ spa_type_media_subtype_map(map, &pw_type_->media_subtype); ++ spa_type_format_video_map(map, &pw_type_->format_video); ++ spa_type_video_format_map(map, &pw_type_->video_format); ++} ++ ++void BaseCapturerPipeWire::CreateReceivingStream() { ++ spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1}; ++ spa_rectangle pwScreenBounds = ++ spa_rectangle{static_cast(desktop_size_.width()), ++ static_cast(desktop_size_.height())}; ++ ++ spa_fraction pwFrameRateMin = spa_fraction{0, 1}; ++ spa_fraction pwFrameRateMax = spa_fraction{60, 1}; ++ ++ pw_properties* reuseProps = pw_properties_new("pipewire.client.reuse", "1", ++ /*end of varargs*/ nullptr); ++ pw_stream_ = pw_stream_new(pw_remote_, "webrtc-consume-stream", reuseProps); ++ ++ uint8_t buffer[1024] = {}; ++ const spa_pod* params[1]; ++ spa_pod_builder builder = spa_pod_builder{buffer, sizeof(buffer)}; ++ params[0] = reinterpret_cast(spa_pod_builder_object( ++ &builder, ++ // id to enumerate formats ++ pw_core_type_->param.idEnumFormat, pw_core_type_->spa_format, "I", ++ pw_type_->media_type.video, "I", pw_type_->media_subtype.raw, ++ // Video format: specified as id or enum (I), preferred format is BGRx, ++ // then allowed formats are enumerated (e) and the format is undecided (u) ++ // to allow negotiation ++ ":", pw_type_->format_video.format, "Ieu", pw_type_->video_format.BGRx, ++ SPA_POD_PROP_ENUM(2, pw_type_->video_format.RGBx, ++ pw_type_->video_format.BGRx), ++ // Video size: specified as rectangle (R), preferred size is specified as ++ // first parameter, then allowed size is defined as range (r) from min and ++ // max values and the format is undecided (u) to allow negotiation ++ ":", pw_type_->format_video.size, "Rru", &pwScreenBounds, 2, ++ &pwMinScreenBounds, &pwScreenBounds, ++ // Frame rate: specified as fraction (F) and set to minimum frame rate ++ // value ++ ":", pw_type_->format_video.framerate, "F", &pwFrameRateMin, ++ // Max frame rate: specified as fraction (F), preferred frame rate is set ++ // to maximum value, then allowed frame rate is defined as range (r) from ++ // min and max values and it is undecided (u) to allow negotiation ++ ":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2, ++ &pwFrameRateMin, &pwFrameRateMax)); ++ ++ pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_, ++ this); ++ pw_stream_flags flags = static_cast( ++ PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE | ++ PW_STREAM_FLAG_MAP_BUFFERS); ++ if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr, ++ flags, params, ++ /*n_params=*/1) != 0) { ++ LOG(LS_ERROR) << "Could not connect receiving stream."; ++ portal_init_failed_ = true; ++ return; ++ } ++} ++ ++void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) { ++ spa_buffer* spaBuffer = buffer->buffer; ++ void* src = nullptr; ++ ++ if (!(src = spaBuffer->datas[0].data)) { ++ return; ++ } ++ ++ uint32_t maxSize = spaBuffer->datas[0].maxsize; ++ int32_t srcStride = spaBuffer->datas[0].chunk->stride; ++ if (srcStride != (desktop_size_.width() * kBytesPerPixelPw)) { ++ LOG(LS_ERROR) << "Got buffer with stride different from screen stride: " ++ << srcStride ++ << " != " << (desktop_size_.width() * kBytesPerPixelPw); ++ portal_init_failed_ = true; ++ return; ++ } ++ ++ if (!current_frame_) { ++ current_frame_ = static_cast(malloc(maxSize)); ++ } ++ RTC_DCHECK(current_frame_ != nullptr); ++ ++ // 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 == pw_type_->video_format.RGBx) { ++ uint8_t* tempFrame = static_cast(malloc(maxSize)); ++ std::memcpy(tempFrame, src, maxSize); ++ ConvertRGBxToBGRx(tempFrame, maxSize); ++ std::memcpy(current_frame_, tempFrame, maxSize); ++ free(tempFrame); ++ } else { ++ std::memcpy(current_frame_, src, maxSize); ++ } ++} ++ ++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; ++ that->proxy_ = g_dbus_proxy_new_finish(result, &error); ++ if (!that->proxy_) { ++ 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->connection_ = g_dbus_proxy_get_connection(that->proxy_); ++ ++ 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); ++ ++ 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=*/nullptr, ++ reinterpret_cast(OnSessionRequested), this); ++} ++ ++// static ++void BaseCapturerPipeWire::OnSessionRequested(GDBusConnection* connection, ++ GAsyncResult* result, ++ gpointer user_data) { ++ BaseCapturerPipeWire* that = ++ static_cast(user_data); ++ RTC_DCHECK(that); ++ ++ GError* error = nullptr; ++ GVariant* variant = g_dbus_proxy_call_finish(that->proxy_, result, &error); ++ if (!variant) { ++ LOG(LS_ERROR) << "Failed to create a screen cast session: " ++ << error->message; ++ g_error_free(error); ++ that->portal_init_failed_ = true; ++ return; ++ } ++ 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) { ++ LOG(LS_ERROR) << "Failed to initialize the screen cast session."; ++ if (that->session_request_signal_id_) { ++ g_dbus_connection_signal_unsubscribe(connection, ++ that->session_request_signal_id_); ++ that->session_request_signal_id_ = 0; ++ } ++ that->portal_init_failed_ = true; ++ return; ++ } ++ ++ g_free(handle); ++ ++ 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); ++ ++ ++ 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); ++ g_variant_lookup(response_data, "session_handle", "s", ++ &that->session_handle_); ++ g_variant_unref(response_data); ++ ++ if (!that->session_handle_ || portal_response) { ++ 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); ++ ++ 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=*/nullptr, ++ reinterpret_cast(OnSourcesRequested), this); ++} ++ ++// static ++void BaseCapturerPipeWire::OnSourcesRequested(GDBusConnection* connection, ++ GAsyncResult* result, ++ gpointer user_data) { ++ BaseCapturerPipeWire* that = ++ static_cast(user_data); ++ RTC_DCHECK(that); ++ ++ GError* error = nullptr; ++ GVariant* variant = g_dbus_proxy_call_finish(that->proxy_, result, &error); ++ if (!variant) { ++ LOG(LS_ERROR) << "Failed to request the sources: " << error->message; ++ g_error_free(error); ++ that->portal_init_failed_ = true; ++ return; ++ } ++ ++ 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) { ++ LOG(LS_ERROR) << "Failed to initialize the screen cast session."; ++ if (that->sources_request_signal_id_) { ++ g_dbus_connection_signal_unsubscribe(connection, ++ that->sources_request_signal_id_); ++ that->sources_request_signal_id_ = 0; ++ } ++ that->portal_init_failed_ = true; ++ return; ++ } ++ ++ g_free(handle); ++ ++ 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); ++ ++ guint32 portal_response; ++ g_variant_get(parameters, "(u@a{sv})", &portal_response, nullptr); ++ if (portal_response) { ++ LOG(LS_ERROR) ++ << "Failed to select sources for the screen cast session."; ++ that->portal_init_failed_ = true; ++ return; ++ } ++ ++ LOG(LS_INFO) << "Received sources signal from session."; ++ 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[] = ""; ++ ++ 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=*/nullptr, ++ reinterpret_cast(OnStartRequested), this); ++} ++ ++// static ++void BaseCapturerPipeWire::OnStartRequested(GDBusConnection* connection, ++ GAsyncResult* result, ++ gpointer user_data) { ++ BaseCapturerPipeWire* that = ++ static_cast(user_data); ++ RTC_DCHECK(that); ++ ++ GError* error = nullptr; ++ GVariant* variant = g_dbus_proxy_call_finish(that->proxy_, result, &error); ++ if (!variant) { ++ LOG(LS_ERROR) << "Failed to start the screen cast session: " ++ << error->message; ++ g_error_free(error); ++ that->portal_init_failed_ = true; ++ return; ++ } ++ ++ 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) { ++ LOG(LS_ERROR) ++ << "Failed to initialize the start of the screen cast session."; ++ if (that->start_request_signal_id_) { ++ g_dbus_connection_signal_unsubscribe(connection, ++ that->start_request_signal_id_); ++ that->start_request_signal_id_ = 0; ++ } ++ that->portal_init_failed_ = true; ++ return; ++ } ++ ++ g_free(handle); ++ ++ 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); ++ ++ 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) { ++ 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; ++ gint32 width; ++ gint32 height; ++ GVariant* options; ++ ++ g_variant_get(variant, "(u@a{sv})", &stream_id, &options); ++ RTC_DCHECK(options != nullptr); ++ ++ g_variant_lookup(options, "size", "(ii)", &width, &height); ++ ++ that->desktop_size_.set(width, height); ++ ++ 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); ++ ++ 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=*/nullptr, ++ reinterpret_cast(OnOpenPipeWireRemoteRequested), ++ this); ++} ++ ++// static ++void BaseCapturerPipeWire::OnOpenPipeWireRemoteRequested( ++ GDBusConnection* connection, ++ 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( ++ that->proxy_, &outlist, result, &error); ++ if (!variant) { ++ 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) { ++ 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(); ++ LOG(LS_INFO) << "PipeWire remote opened."; ++} ++ ++void BaseCapturerPipeWire::Start(Callback* callback) { ++ RTC_DCHECK(!callback_); ++ RTC_DCHECK(callback); ++ ++ InitPortals(); ++ ++ callback_ = callback; ++} ++ ++void BaseCapturerPipeWire::CaptureFrame() { ++ if (portal_init_failed_) { ++ callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); ++ return; ++ } ++ ++ if (!current_frame_) { ++ callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); ++ return; ++ } ++ ++ std::unique_ptr result(new BasicDesktopFrame(desktop_size_)); ++ result->CopyPixelsFrom( ++ current_frame_, (desktop_size_.width() * kBytesPerPixelPw), ++ DesktopRect::MakeWH(desktop_size_.width(), desktop_size_.height())); ++ if (!result) { ++ callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); ++ return; ++ } ++ callback_->OnCaptureResult(Result::SUCCESS, std::move(result)); ++} ++ ++bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) { ++ RTC_DCHECK(sources->size() == 0); ++ // List of available screens is already presented by the xdg-desktop-portal. ++ // But we have to add an empty source as the code expects it. ++ sources->push_back({0}); ++ return true; ++} ++ ++bool BaseCapturerPipeWire::SelectSource(SourceId id) { ++ // Screen selection is handled by the xdg-desktop-portal. ++ return true; ++} ++ ++} // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.h.pipewire 2019-01-07 14:53:17.201061764 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.h 2019-01-07 14:53:17.201061764 +0100 +@@ -0,0 +1,167 @@ ++/* ++ * 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_BASE_CAPTURER_PIPEWIRE_H_ ++#define MODULES_DESKTOP_CAPTURE_BASE_CAPTURER_PIPEWIRE_H_ ++ ++#include ++#define typeof __typeof__ ++#include ++#include ++ ++#include "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capturer.h" ++ ++namespace webrtc { ++ ++class PipeWireType { ++ public: ++ spa_type_media_type media_type; ++ spa_type_media_subtype media_subtype; ++ spa_type_format_video format_video; ++ spa_type_video_format video_format; ++}; ++ ++class BaseCapturerPipeWire : public DesktopCapturer { ++ public: ++ enum CaptureSourceType { Screen = 1, Window }; ++ ++ explicit BaseCapturerPipeWire(CaptureSourceType source_type); ++ ~BaseCapturerPipeWire() override; ++ ++ // DesktopCapturer interface. ++ void Start(Callback* delegate) override; ++ void Stop() override { callback_ = nullptr; } ++ void CaptureFrame() override; ++ bool GetSourceList(SourceList* sources) override; ++ bool SelectSource(SourceId id) override; ++ ++ private: ++ // PipeWire types --> ++ pw_core* pw_core_ = nullptr; ++ pw_type* pw_core_type_ = nullptr; ++ pw_stream* pw_stream_ = nullptr; ++ pw_remote* pw_remote_ = nullptr; ++ pw_loop* pw_loop_ = nullptr; ++ pw_thread_loop* pw_main_loop_ = nullptr; ++ PipeWireType* pw_type_ = nullptr; ++ ++ spa_hook spa_stream_listener_ = {}; ++ spa_hook spa_remote_listener_ = {}; ++ ++ pw_stream_events pw_stream_events_ = {}; ++ pw_remote_events pw_remote_events_ = {}; ++ ++ spa_video_info_raw* spa_video_format_ = nullptr; ++ ++ gint32 pw_fd_ = -1; ++ ++ CaptureSourceType capture_source_type_ = ++ BaseCapturerPipeWire::CaptureSourceType::Screen; ++ ++ // <-- end of PipeWire types ++ ++ GDBusConnection* connection_ = nullptr; ++ GDBusProxy* proxy_ = 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; ++ ++ DesktopSize desktop_size_ = {}; ++ DesktopCaptureOptions options_ = {}; ++ ++ uint8_t* current_frame_ = nullptr; ++ Callback* callback_ = nullptr; ++ ++ bool portal_init_failed_ = false; ++ ++ void InitPortals(); ++ void InitPipeWire(); ++ void InitPipeWireTypes(); ++ ++ void CreateReceivingStream(); ++ void HandleBuffer(pw_buffer* buffer); ++ ++ void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size); ++ ++ static void OnStateChanged(void* data, ++ pw_remote_state old_state, ++ pw_remote_state state, ++ const char* error); ++ static void OnStreamStateChanged(void* data, ++ pw_stream_state old_state, ++ pw_stream_state state, ++ const char* error_message); ++ ++ static void OnStreamFormatChanged(void* data, const struct spa_pod* format); ++ 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(GDBusConnection* connection, ++ 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(GDBusConnection* connection, ++ 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(GDBusConnection* connection, ++ 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(GDBusConnection* connection, ++ GAsyncResult* result, ++ gpointer user_data); ++ ++ RTC_DISALLOW_COPY_AND_ASSIGN(BaseCapturerPipeWire); ++}; ++ ++} // namespace webrtc ++ ++#endif // MODULES_DESKTOP_CAPTURE_BASE_CAPTURER_PIPEWIRE_H_ +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build.pipewire 2019-01-07 14:53:17.201061764 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_gn/moz.build 2019-01-07 14:56:57.674544724 +0100 +@@ -144,14 +144,26 @@ if CONFIG["OS_TARGET"] == "FreeBSD": + "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.cc" + ] + ++# Common Linux stuff between X11 and PipeWire + if CONFIG["OS_TARGET"] == "Linux": + + DEFINES["USE_NSS_CERTS"] = "1" +- DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_LINUX"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_FILE_OFFSET_BITS"] = "64" + ++ UNIFIED_SOURCES += [ ++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/app_capturer_linux.cc", ++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc", ++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc", ++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc", ++ ] ++ ++# X11 specific files ++if CONFIG["OS_TARGET"] == "Linux": ++ ++ DEFINES["USE_X11"] = "1" ++ + OS_LIBS += [ + "rt", + "X11", +@@ -178,6 +190,28 @@ if CONFIG["OS_TARGET"] == "Linux": + "/media/webrtc/trunk/webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.cc" + ] + ++# PipeWire specific files ++if CONFIG["OS_TARGET"] == "Linux": ++ ++ DEFINES["WEBRTC_USE_PIPEWIRE"] = "1" ++ ++ OS_LIBS += [ ++ "rt", ++ "pipewire-0.2", ++ "glib-2.0", ++ "gio-2.0", ++ "gobject-2.0" ++ ] ++ ++ CXXFLAGS += CONFIG['TK_CFLAGS'] ++ ++ UNIFIED_SOURCES += [ ++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/base_capturer_pipewire.cc", ++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc", ++ "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc" ++ ] ++ ++ + if CONFIG["OS_TARGET"] == "NetBSD": + + DEFINES["USE_X11"] = "1" +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h.pipewire 2018-10-17 22:39:32.000000000 +0200 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h 2019-01-07 14:53:17.202061775 +0100 +@@ -107,6 +107,11 @@ class DesktopCaptureOptions { + } + #endif + ++#if defined(WEBRTC_USE_PIPEWIRE) ++ bool allow_pipewire() const { return allow_pipewire_; } ++ void set_allow_pipewire(bool allow) { allow_pipewire_ = allow; } ++#endif ++ + private: + #if defined(USE_X11) + rtc::scoped_refptr x_display_; +@@ -129,6 +134,9 @@ class DesktopCaptureOptions { + #endif + bool disable_effects_ = true; + bool detect_updated_region_ = false; ++#if defined(WEBRTC_USE_PIPEWIRE) ++ bool allow_pipewire_ = true; ++#endif + }; + + } // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc.pipewire 2018-10-17 22:39:32.000000000 +0200 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.cc 2019-01-07 14:53:17.202061775 +0100 +@@ -66,4 +66,17 @@ std::unique_ptr Desktop + return capturer; + } + ++#if defined(WEBRTC_USE_PIPEWIRE) || defined(USE_X11) ++bool DesktopCapturer::IsRunningUnderWayland() { ++ const char* xdg_session_type = getenv("XDG_SESSION_TYPE"); ++ if (!xdg_session_type || strncmp(xdg_session_type, "wayland", 7) != 0) ++ return false; ++ ++ if (!(getenv("WAYLAND_DISPLAY"))) ++ return false; ++ ++ return true; ++} ++#endif ++ + } // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h.pipewire 2018-10-17 22:39:32.000000000 +0200 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capturer.h 2019-01-07 14:53:17.202061775 +0100 +@@ -129,6 +129,10 @@ class DesktopCapturer { + static std::unique_ptr CreateAppCapturer( + const DesktopCaptureOptions& options); + ++#if defined(WEBRTC_USE_PIPEWIRE) || defined(USE_X11) ++ static bool IsRunningUnderWayland(); ++#endif ++ + protected: + // CroppingWindowCapturer needs to create raw capturers without wrappers, so + // the following two functions are protected. +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc.pipewire 2019-01-07 14:53:17.202061775 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc 2019-01-07 14:53:17.202061775 +0100 +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 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 "webrtc/modules/desktop_capture/mouse_cursor_monitor.h" ++ ++#if defined(USE_X11) ++#include "webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.h" ++#endif // defined(USE_X11) ++ ++namespace webrtc { ++ ++// static ++MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( ++ const DesktopCaptureOptions& options, WindowId window) { ++#if defined(USE_X11) ++ return MouseCursorMonitorX11::CreateForWindow(options, window); ++#else ++ return nullptr; ++#endif // defined(USE_X11) ++} ++ ++// static ++MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( ++ const DesktopCaptureOptions& options, ++ ScreenId screen) { ++#if defined(USE_X11) ++ return MouseCursorMonitorX11::CreateForScreen(options, screen); ++#else ++ return nullptr; ++#endif // defined(USE_X11) ++} ++ ++} // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc.pipewire 2018-10-17 22:39:32.000000000 +0200 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.cc 2019-01-07 14:53:17.202061775 +0100 +@@ -16,6 +16,8 @@ + #include + #include + ++#include "webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.h" ++ + #include "webrtc/modules/desktop_capture/desktop_capture_options.h" + #include "webrtc/modules/desktop_capture/desktop_frame.h" + #include "webrtc/modules/desktop_capture/mouse_cursor.h" +@@ -59,38 +61,6 @@ Window GetTopLevelWindow(Display* displa + + namespace webrtc { + +-class MouseCursorMonitorX11 : public MouseCursorMonitor, +- public SharedXDisplay::XEventHandler { +- public: +- MouseCursorMonitorX11(const DesktopCaptureOptions& options, Window window, Window inner_window); +- ~MouseCursorMonitorX11() override; +- +- void Start(Callback* callback, Mode mode) override; +- void Stop() override; +- void Capture() override; +- +- private: +- // SharedXDisplay::XEventHandler interface. +- bool HandleXEvent(const XEvent& event) override; +- +- Display* display() { return x_display_->display(); } +- +- // Captures current cursor shape and stores it in |cursor_shape_|. +- void CaptureCursor(); +- +- rtc::scoped_refptr x_display_; +- Callback* callback_; +- Mode mode_; +- Window window_; +- Window inner_window_; +- +- bool have_xfixes_; +- int xfixes_event_base_; +- int xfixes_error_base_; +- +- std::unique_ptr cursor_shape_; +-}; +- + MouseCursorMonitorX11::MouseCursorMonitorX11( + const DesktopCaptureOptions& options, + Window window, Window inner_window) +@@ -244,7 +214,7 @@ void MouseCursorMonitorX11::CaptureCurso + } + + // static +-MouseCursorMonitor* MouseCursorMonitor::CreateForWindow( ++MouseCursorMonitor* MouseCursorMonitorX11::CreateForWindow( + const DesktopCaptureOptions& options, WindowId window) { + if (!options.x_display()) + return NULL; +@@ -254,7 +224,7 @@ MouseCursorMonitor* MouseCursorMonitor:: + return new MouseCursorMonitorX11(options, outer_window, window); + } + +-MouseCursorMonitor* MouseCursorMonitor::CreateForScreen( ++MouseCursorMonitor* MouseCursorMonitorX11::CreateForScreen( + const DesktopCaptureOptions& options, + ScreenId screen) { + if (!options.x_display()) +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.h.pipewire 2019-01-07 14:53:17.202061775 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/mouse_cursor_monitor_x11.h 2019-01-07 14:53:17.202061775 +0100 +@@ -0,0 +1,63 @@ ++/* ++ * 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_MOUSE_CURSOR_MONITOR_X11_H_ ++#define MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_MONITOR_X11_H_ ++ ++#include ++#include ++ ++#include "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capture_types.h" ++#include "webrtc/modules/desktop_capture/x11/shared_x_display.h" ++#include "webrtc/modules/desktop_capture/mouse_cursor.h" ++#include "webrtc/modules/desktop_capture/mouse_cursor_monitor.h" ++#include "webrtc/base/scoped_ref_ptr.h" ++ ++namespace webrtc { ++ ++class MouseCursorMonitorX11 : public MouseCursorMonitor, ++ public SharedXDisplay::XEventHandler { ++ public: ++ MouseCursorMonitorX11(const DesktopCaptureOptions& options, Window window, Window inner_window); ++ ~MouseCursorMonitorX11() override; ++ ++ void Start(Callback* callback, Mode mode) override; ++ void Stop() override; ++ void Capture() override; ++ ++ static MouseCursorMonitor* CreateForWindow(const DesktopCaptureOptions& options, WindowId window); ++ static MouseCursorMonitor* CreateForScreen(const DesktopCaptureOptions& options, ScreenId screen); ++ ++ private: ++ // SharedXDisplay::XEventHandler interface. ++ bool HandleXEvent(const XEvent& event) override; ++ ++ Display* display() { return x_display_->display(); } ++ ++ // Captures current cursor shape and stores it in |cursor_shape_|. ++ void CaptureCursor(); ++ ++ rtc::scoped_refptr x_display_; ++ Callback* callback_; ++ Mode mode_; ++ Window window_; ++ Window inner_window_; ++ ++ bool have_xfixes_; ++ int xfixes_event_base_; ++ int xfixes_error_base_; ++ ++ std::unique_ptr cursor_shape_; ++}; ++ ++} // namespace webrtc ++ ++#endif // MODULES_DESKTOP_CAPTURE_MOUSE_CURSOR_MONITOR_X11_H_ +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc.pipewire 2019-01-07 14:53:17.203061786 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc 2019-01-07 14:53:17.203061786 +0100 +@@ -0,0 +1,40 @@ ++/* ++ * 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 "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capturer.h" ++ ++#if defined(WEBRTC_USE_PIPEWIRE) ++#include "webrtc/modules/desktop_capture/screen_capturer_pipewire.h" ++#endif // defined(WEBRTC_USE_PIPEWIRE) ++ ++#if defined(USE_X11) ++#include "webrtc/modules/desktop_capture/screen_capturer_x11.h" ++#endif // defined(USE_X11) ++ ++namespace webrtc { ++ ++// static ++std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( ++ const DesktopCaptureOptions& options) { ++#if defined(WEBRTC_USE_PIPEWIRE) ++ if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { ++ return ScreenCapturerPipeWire::CreateRawScreenCapturer(options); ++ } ++#endif // defined(WEBRTC_USE_PIPEWIRE) ++ ++#if defined(USE_X11) ++ return ScreenCapturerX11::CreateRawScreenCapturer(options); ++#endif // defined(USE_X11) ++ ++ return nullptr; ++} ++ ++} // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc.pipewire 2019-01-07 14:53:17.203061786 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.cc 2019-01-07 14:53:17.203061786 +0100 +@@ -0,0 +1,31 @@ ++/* ++ * 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 "webrtc/modules/desktop_capture/screen_capturer_pipewire.h" ++ ++#include ++ ++namespace webrtc { ++ ++ScreenCapturerPipeWire::ScreenCapturerPipeWire() ++ : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {} ++ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {} ++ ++// static ++std::unique_ptr ++ScreenCapturerPipeWire::CreateRawScreenCapturer( ++ const DesktopCaptureOptions& options) { ++ std::unique_ptr capturer( ++ new ScreenCapturerPipeWire()); ++ ++ return std::move(capturer); ++} ++ ++} // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.h.pipewire 2019-01-07 14:53:17.203061786 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_pipewire.h 2019-01-07 14:53:17.203061786 +0100 +@@ -0,0 +1,33 @@ ++/* ++ * 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_SCREEN_CAPTURER_PIPEWIRE_H_ ++#define MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURER_PIPEWIRE_H_ ++ ++#include ++ ++#include "webrtc/modules/desktop_capture/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_SCREEN_CAPTURER_PIPEWIRE_H_ +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc.pipewire 2018-10-17 22:39:32.000000000 +0200 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.cc 2019-01-07 14:53:17.203061786 +0100 +@@ -19,6 +19,8 @@ + #include + #include + ++#include "webrtc/modules/desktop_capture/screen_capturer_x11.h" ++ + #include "webrtc/base/checks.h" + #include "webrtc/base/constructormagic.h" + #include "webrtc/base/timeutils.h" +@@ -32,100 +34,12 @@ + #include "webrtc/system_wrappers/include/logging.h" + + namespace webrtc { +-namespace { +- +-// A class to perform video frame capturing for Linux. +-// +-// If XDamage is used, this class sets DesktopFrame::updated_region() according +-// to the areas reported by XDamage. Otherwise this class does not detect +-// DesktopFrame::updated_region(), the field is always set to the entire frame +-// rectangle. ScreenCapturerDifferWrapper should be used if that functionality +-// is necessary. +-class ScreenCapturerLinux : public DesktopCapturer, +- public SharedXDisplay::XEventHandler { +- public: +- ScreenCapturerLinux(); +- ~ScreenCapturerLinux() override; +- +- // TODO(ajwong): Do we really want this to be synchronous? +- bool Init(const DesktopCaptureOptions& options); +- +- // DesktopCapturer interface. +- void Start(Callback* delegate) override; +- void Stop() override; +- void CaptureFrame() override; +- bool GetSourceList(SourceList* sources) override; +- bool SelectSource(SourceId id) override; +- +- private: +- Display* display() { return options_.x_display()->display(); } +- +- // SharedXDisplay::XEventHandler interface. +- bool HandleXEvent(const XEvent& event) override; +- +- void InitXDamage(); +- +- // Capture screen pixels to the current buffer in the queue. In the DAMAGE +- // case, the ScreenCapturerHelper already holds the list of invalid rectangles +- // from HandleXEvent(). In the non-DAMAGE case, this captures the +- // whole screen, then calculates some invalid rectangles that include any +- // differences between this and the previous capture. +- std::unique_ptr CaptureScreen(); +- +- // Called when the screen configuration is changed. +- void ScreenConfigurationChanged(); +- +- // Synchronize the current buffer with |last_buffer_|, by copying pixels from +- // the area of |last_invalid_rects|. +- // Note this only works on the assumption that kNumBuffers == 2, as +- // |last_invalid_rects| holds the differences from the previous buffer and +- // the one prior to that (which will then be the current buffer). +- void SynchronizeFrame(); +- +- void DeinitXlib(); +- +- DesktopCaptureOptions options_; +- +- Callback* callback_ = nullptr; +- +- // X11 graphics context. +- GC gc_ = nullptr; +- Window root_window_ = BadValue; +- +- // XFixes. +- bool has_xfixes_ = false; +- int xfixes_event_base_ = -1; +- int xfixes_error_base_ = -1; +- +- // XDamage information. +- bool use_damage_ = false; +- Damage damage_handle_ = 0; +- int damage_event_base_ = -1; +- int damage_error_base_ = -1; +- XserverRegion damage_region_ = 0; +- +- // Access to the X Server's pixel buffer. +- XServerPixelBuffer x_server_pixel_buffer_; +- +- // A thread-safe list of invalid rectangles, and the size of the most +- // recently captured screen. +- ScreenCapturerHelper helper_; +- +- // Queue of the frames buffers. +- ScreenCaptureFrameQueue queue_; +- +- // Invalid region from the previous capture. This is used to synchronize the +- // current with the last buffer used. +- DesktopRegion last_invalid_region_; + +- RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerLinux); +-}; +- +-ScreenCapturerLinux::ScreenCapturerLinux() { ++ScreenCapturerX11::ScreenCapturerX11() { + helper_.SetLogGridSize(4); + } + +-ScreenCapturerLinux::~ScreenCapturerLinux() { ++ScreenCapturerX11::~ScreenCapturerX11() { + options_.x_display()->RemoveEventHandler(ConfigureNotify, this); + if (use_damage_) { + options_.x_display()->RemoveEventHandler( +@@ -134,7 +48,7 @@ ScreenCapturerLinux::~ScreenCapturerLinu + DeinitXlib(); + } + +-bool ScreenCapturerLinux::Init(const DesktopCaptureOptions& options) { ++bool ScreenCapturerX11::Init(const DesktopCaptureOptions& options) { + options_ = options; + + root_window_ = RootWindow(display(), DefaultScreen(display())); +@@ -177,7 +91,7 @@ bool ScreenCapturerLinux::Init(const Des + return true; + } + +-void ScreenCapturerLinux::InitXDamage() { ++void ScreenCapturerX11::InitXDamage() { + // Our use of XDamage requires XFixes. + if (!has_xfixes_) { + return; +@@ -218,18 +132,18 @@ void ScreenCapturerLinux::InitXDamage() + LOG(LS_INFO) << "Using XDamage extension."; + } + +-void ScreenCapturerLinux::Start(Callback* callback) { ++void ScreenCapturerX11::Start(Callback* callback) { + RTC_DCHECK(!callback_); + RTC_DCHECK(callback); + + callback_ = callback; + } + +-void ScreenCapturerLinux::Stop() { ++void ScreenCapturerX11::Stop() { + callback_ = NULL; + } + +-void ScreenCapturerLinux::CaptureFrame() { ++void ScreenCapturerX11::CaptureFrame() { + int64_t capture_start_time_nanos = rtc::TimeNanos(); + + queue_.MoveToNextFrame(); +@@ -243,6 +157,7 @@ void ScreenCapturerLinux::CaptureFrame() + // in a good shape. + if (!x_server_pixel_buffer_.is_initialized()) { + // We failed to initialize pixel buffer. ++ LOG(LS_ERROR) << "Pixel buffer is not initialized."; + callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); + return; + } +@@ -258,6 +173,7 @@ void ScreenCapturerLinux::CaptureFrame() + + std::unique_ptr result = CaptureScreen(); + if (!result) { ++ LOG(LS_WARNING) << "Temporarily failed to capture screen."; + callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); + return; + } +@@ -268,19 +184,19 @@ void ScreenCapturerLinux::CaptureFrame() + callback_->OnCaptureResult(Result::SUCCESS, std::move(result)); + } + +-bool ScreenCapturerLinux::GetSourceList(SourceList* sources) { ++bool ScreenCapturerX11::GetSourceList(SourceList* sources) { + RTC_DCHECK(sources->size() == 0); + // TODO(jiayl): implement screen enumeration. + sources->push_back({0}); + return true; + } + +-bool ScreenCapturerLinux::SelectSource(SourceId id) { ++bool ScreenCapturerX11::SelectSource(SourceId id) { + // TODO(jiayl): implement screen selection. + return true; + } + +-bool ScreenCapturerLinux::HandleXEvent(const XEvent& event) { ++bool ScreenCapturerX11::HandleXEvent(const XEvent& event) { + if (use_damage_ && (event.type == damage_event_base_ + XDamageNotify)) { + const XDamageNotifyEvent* damage_event = + reinterpret_cast(&event); +@@ -295,7 +211,7 @@ bool ScreenCapturerLinux::HandleXEvent(c + return false; + } + +-std::unique_ptr ScreenCapturerLinux::CaptureScreen() { ++std::unique_ptr ScreenCapturerX11::CaptureScreen() { + std::unique_ptr frame = queue_.current_frame()->Share(); + RTC_DCHECK(x_server_pixel_buffer_.window_size().equals(frame->size())); + +@@ -345,14 +261,15 @@ std::unique_ptr ScreenCapt + // Doing full-screen polling, or this is the first capture after a + // screen-resolution change. In either case, need a full-screen capture. + DesktopRect screen_rect = DesktopRect::MakeSize(frame->size()); +- x_server_pixel_buffer_.CaptureRect(screen_rect, frame.get()); ++ if (!x_server_pixel_buffer_.CaptureRect(screen_rect, frame.get())) ++ return nullptr; + updated_region->SetRect(screen_rect); + } + + return std::move(frame); + } + +-void ScreenCapturerLinux::ScreenConfigurationChanged() { ++void ScreenCapturerX11::ScreenConfigurationChanged() { + // Make sure the frame buffers will be reallocated. + queue_.Reset(); + +@@ -363,7 +280,7 @@ void ScreenCapturerLinux::ScreenConfigur + } + } + +-void ScreenCapturerLinux::SynchronizeFrame() { ++void ScreenCapturerX11::SynchronizeFrame() { + // Synchronize the current buffer with the previous one since we do not + // capture the entire desktop. Note that encoder may be reading from the + // previous buffer at this time so thread access complaints are false +@@ -383,7 +300,7 @@ void ScreenCapturerLinux::SynchronizeFra + } + } + +-void ScreenCapturerLinux::DeinitXlib() { ++void ScreenCapturerX11::DeinitXlib() { + if (gc_) { + XFreeGC(display(), gc_); + gc_ = nullptr; +@@ -404,20 +321,18 @@ void ScreenCapturerLinux::DeinitXlib() { + } + } + +-} // namespace +- + // static +-std::unique_ptr DesktopCapturer::CreateRawScreenCapturer( ++std::unique_ptr ScreenCapturerX11::CreateRawScreenCapturer( + const DesktopCaptureOptions& options) { + if (!options.x_display()) + return nullptr; + +- std::unique_ptr capturer(new ScreenCapturerLinux()); ++ std::unique_ptr capturer(new ScreenCapturerX11()); + if (!capturer.get()->Init(options)) { + return nullptr; + } + +- return std::unique_ptr(capturer.release()); ++ return std::move(capturer); + } + + } // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.h.pipewire 2019-01-07 14:53:17.203061786 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_x11.h 2019-01-07 14:53:17.203061786 +0100 +@@ -0,0 +1,124 @@ ++/* ++ * 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_SCREEN_CAPTURER_X11_H_ ++#define MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURER_X11_H_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capturer.h" ++#include "webrtc/modules/desktop_capture/desktop_frame.h" ++#include "webrtc/modules/desktop_capture/desktop_region.h" ++#include "webrtc/modules/desktop_capture/x11/shared_x_display.h" ++#include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h" ++#include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" ++#include "webrtc/modules/desktop_capture/screen_capturer_helper.h" ++#include "webrtc/modules/desktop_capture/shared_desktop_frame.h" ++#include "webrtc/base/constructormagic.h" ++ ++namespace webrtc { ++ ++// A class to perform video frame capturing for Linux on X11. ++// ++// If XDamage is used, this class sets DesktopFrame::updated_region() according ++// to the areas reported by XDamage. Otherwise this class does not detect ++// DesktopFrame::updated_region(), the field is always set to the entire frame ++// rectangle. ScreenCapturerDifferWrapper should be used if that functionality ++// is necessary. ++class ScreenCapturerX11 : public DesktopCapturer, ++ public SharedXDisplay::XEventHandler { ++ public: ++ ScreenCapturerX11(); ++ ~ScreenCapturerX11() override; ++ ++ static std::unique_ptr CreateRawScreenCapturer(const DesktopCaptureOptions& options); ++ ++ // TODO(ajwong): Do we really want this to be synchronous? ++ bool Init(const DesktopCaptureOptions& options); ++ ++ // DesktopCapturer interface. ++ void Start(Callback* delegate) override; ++ void Stop() override; ++ void CaptureFrame() override; ++ bool GetSourceList(SourceList* sources) override; ++ bool SelectSource(SourceId id) override; ++ ++ private: ++ Display* display() { return options_.x_display()->display(); } ++ ++ // SharedXDisplay::XEventHandler interface. ++ bool HandleXEvent(const XEvent& event) override; ++ ++ void InitXDamage(); ++ ++ // Capture screen pixels to the current buffer in the queue. In the DAMAGE ++ // case, the ScreenCapturerHelper already holds the list of invalid rectangles ++ // from HandleXEvent(). In the non-DAMAGE case, this captures the ++ // whole screen, then calculates some invalid rectangles that include any ++ // differences between this and the previous capture. ++ std::unique_ptr CaptureScreen(); ++ ++ // Called when the screen configuration is changed. ++ void ScreenConfigurationChanged(); ++ ++ // Synchronize the current buffer with |last_buffer_|, by copying pixels from ++ // the area of |last_invalid_rects|. ++ // Note this only works on the assumption that kNumBuffers == 2, as ++ // |last_invalid_rects| holds the differences from the previous buffer and ++ // the one prior to that (which will then be the current buffer). ++ void SynchronizeFrame(); ++ ++ void DeinitXlib(); ++ ++ DesktopCaptureOptions options_; ++ ++ Callback* callback_ = nullptr; ++ ++ // X11 graphics context. ++ GC gc_ = nullptr; ++ Window root_window_ = BadValue; ++ ++ // XFixes. ++ bool has_xfixes_ = false; ++ int xfixes_event_base_ = -1; ++ int xfixes_error_base_ = -1; ++ ++ // XDamage information. ++ bool use_damage_ = false; ++ Damage damage_handle_ = 0; ++ int damage_event_base_ = -1; ++ int damage_error_base_ = -1; ++ XserverRegion damage_region_ = 0; ++ ++ // Access to the X Server's pixel buffer. ++ XServerPixelBuffer x_server_pixel_buffer_; ++ ++ // A thread-safe list of invalid rectangles, and the size of the most ++ // recently captured screen. ++ ScreenCapturerHelper helper_; ++ ++ // Queue of the frames buffers. ++ ScreenCaptureFrameQueue queue_; ++ ++ // Invalid region from the previous capture. This is used to synchronize the ++ // current with the last buffer used. ++ DesktopRegion last_invalid_region_; ++ ++ RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerX11); ++}; ++ ++} // namespace webrtc ++ ++#endif // MODULES_DESKTOP_CAPTURE_SCREEN_CAPTURER_X11_H_ +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc.pipewire 2019-01-07 14:53:17.203061786 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc 2019-01-07 14:53:17.203061786 +0100 +@@ -0,0 +1,40 @@ ++/* ++ * 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 "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capturer.h" ++ ++#if defined(WEBRTC_USE_PIPEWIRE) ++#include "webrtc/modules/desktop_capture/window_capturer_pipewire.h" ++#endif // defined(WEBRTC_USE_PIPEWIRE) ++ ++#if defined(USE_X11) ++#include "webrtc/modules/desktop_capture/window_capturer_x11.h" ++#endif // defined(USE_X11) ++ ++namespace webrtc { ++ ++// static ++std::unique_ptr DesktopCapturer::CreateRawWindowCapturer( ++ const DesktopCaptureOptions& options) { ++#if defined(WEBRTC_USE_PIPEWIRE) ++ if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { ++ return WindowCapturerPipeWire::CreateRawWindowCapturer(options); ++ } ++#endif // defined(WEBRTC_USE_PIPEWIRE) ++ ++#if defined(USE_X11) ++ return WindowCapturerX11::CreateRawWindowCapturer(options); ++#endif // defined(USE_X11) ++ ++ return nullptr; ++} ++ ++} // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc.pipewire 2019-01-07 14:53:17.204061797 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.cc 2019-01-07 14:53:17.204061797 +0100 +@@ -0,0 +1,28 @@ ++/* ++ * 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 "webrtc/modules/desktop_capture/window_capturer_pipewire.h" ++ ++namespace webrtc { ++ ++WindowCapturerPipeWire::WindowCapturerPipeWire() ++ : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Window) {} ++WindowCapturerPipeWire::~WindowCapturerPipeWire() {} ++ ++// static ++std::unique_ptr ++WindowCapturerPipeWire::CreateRawWindowCapturer( ++ const DesktopCaptureOptions& options) { ++ std::unique_ptr capturer( ++ new WindowCapturerPipeWire()); ++ ++ return std::move(capturer); ++} ++} // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.h.pipewire 2019-01-07 14:53:17.204061797 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_pipewire.h 2019-01-07 14:53:17.204061797 +0100 +@@ -0,0 +1,33 @@ ++/* ++ * 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_WINDOW_CAPTURER_PIPEWIRE_H_ ++#define MODULES_DESKTOP_CAPTURE_WINDOW_CAPTURER_PIPEWIRE_H_ ++ ++#include ++ ++#include "webrtc/modules/desktop_capture/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_WINDOW_CAPTURER_PIPEWIRE_H_ +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc.pipewire 2018-10-17 22:39:32.000000000 +0200 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.cc 2019-01-07 14:53:17.204061797 +0100 +@@ -17,6 +17,8 @@ + + #include + ++#include "webrtc/modules/desktop_capture/window_capturer_x11.h" ++ + #include "webrtc/base/constructormagic.h" + #include "webrtc/base/scoped_ref_ptr.h" + #include "webrtc/modules/desktop_capture/desktop_capturer.h" +@@ -30,58 +32,7 @@ + + namespace webrtc { + +-namespace { +- +-class WindowCapturerLinux : public DesktopCapturer, +- public SharedXDisplay::XEventHandler { +- public: +- WindowCapturerLinux(const DesktopCaptureOptions& options); +- ~WindowCapturerLinux() override; +- +- // DesktopCapturer interface. +- void Start(Callback* callback) override; +- void Stop() override; +- void CaptureFrame() override; +- bool GetSourceList(SourceList* sources) override; +- bool SelectSource(SourceId id) override; +- bool FocusOnSelectedSource() override; +- +- // SharedXDisplay::XEventHandler interface. +- bool HandleXEvent(const XEvent& event) override; +- +- private: +- Display* display() { return x_display_->display(); } +- +- // Iterates through |window| hierarchy to find first visible window, i.e. one +- // that has WM_STATE property set to NormalState. +- // See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 . +- ::Window GetApplicationWindow(::Window window); +- +- // Returns true if the |window| is a desktop element. +- bool IsDesktopElement(::Window window); +- +- // Returns window title for the specified X |window|. +- bool GetWindowTitle(::Window window, std::string* title); +- +- // Returns the id of the owning process. +- int GetWindowProcessID(::Window window); +- +- Callback* callback_ = nullptr; +- +- rtc::scoped_refptr x_display_; +- +- Atom wm_state_atom_; +- Atom window_type_atom_; +- Atom normal_window_type_atom_; +- bool has_composite_extension_ = false; +- +- ::Window selected_window_ = 0; +- XServerPixelBuffer x_server_pixel_buffer_; +- +- RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerLinux); +-}; +- +-WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options) ++WindowCapturerX11::WindowCapturerX11(const DesktopCaptureOptions& options) + : x_display_(options.x_display()) { + // Create Atoms so we don't need to do it every time they are used. + wm_state_atom_ = XInternAtom(display(), "WM_STATE", True); +@@ -102,11 +53,11 @@ WindowCapturerLinux::WindowCapturerLinux + x_display_->AddEventHandler(ConfigureNotify, this); + } + +-WindowCapturerLinux::~WindowCapturerLinux() { ++WindowCapturerX11::~WindowCapturerX11() { + x_display_->RemoveEventHandler(ConfigureNotify, this); + } + +-bool WindowCapturerLinux::GetSourceList(SourceList* sources) { ++bool WindowCapturerX11::GetSourceList(SourceList* sources) { + SourceList result; + + XErrorTrap error_trap(display()); +@@ -159,7 +110,7 @@ bool WindowCapturerLinux::GetSourceList( + return true; + } + +-bool WindowCapturerLinux::SelectSource(SourceId id) { ++bool WindowCapturerX11::SelectSource(SourceId id) { + if (!x_server_pixel_buffer_.Init(display(), id)) + return false; + +@@ -180,7 +131,7 @@ bool WindowCapturerLinux::SelectSource(S + return true; + } + +-bool WindowCapturerLinux::FocusOnSelectedSource() { ++bool WindowCapturerX11::FocusOnSelectedSource() { + if (!selected_window_) + return false; + +@@ -229,18 +180,18 @@ bool WindowCapturerLinux::FocusOnSelecte + return true; + } + +-void WindowCapturerLinux::Start(Callback* callback) { ++void WindowCapturerX11::Start(Callback* callback) { + assert(!callback_); + assert(callback); + + callback_ = callback; + } + +-void WindowCapturerLinux::Stop() { ++void WindowCapturerX11::Stop() { + callback_ = NULL; + } + +-void WindowCapturerLinux::CaptureFrame() { ++void WindowCapturerX11::CaptureFrame() { + x_display_->ProcessPendingXEvents(); + + if (!x_server_pixel_buffer_.IsWindowValid()) { +@@ -274,7 +225,7 @@ void WindowCapturerLinux::CaptureFrame() + callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); + } + +-bool WindowCapturerLinux::HandleXEvent(const XEvent& event) { ++bool WindowCapturerX11::HandleXEvent(const XEvent& event) { + if (event.type == ConfigureNotify) { + XConfigureEvent xce = event.xconfigure; + if (!DesktopSize(xce.width, xce.height).equals( +@@ -288,7 +239,7 @@ bool WindowCapturerLinux::HandleXEvent(c + return false; + } + +-::Window WindowCapturerLinux::GetApplicationWindow(::Window window) { ++::Window WindowCapturerX11::GetApplicationWindow(::Window window) { + // Get WM_STATE property of the window. + XWindowProperty window_state(display(), window, wm_state_atom_); + +@@ -326,7 +277,7 @@ bool WindowCapturerLinux::HandleXEvent(c + return app_window; + } + +-bool WindowCapturerLinux::IsDesktopElement(::Window window) { ++bool WindowCapturerX11::IsDesktopElement(::Window window) { + if (window == 0) + return false; + +@@ -361,7 +312,7 @@ bool WindowCapturerLinux::IsDesktopEleme + return result; + } + +-bool WindowCapturerLinux::GetWindowTitle(::Window window, std::string* title) { ++bool WindowCapturerX11::GetWindowTitle(::Window window, std::string* title) { + int status; + bool result = false; + XTextProperty window_name; +@@ -390,9 +341,7 @@ bool WindowCapturerLinux::GetWindowTitle + return result; + } + +-} // namespace +- +-int WindowCapturerLinux::GetWindowProcessID(::Window window) { ++int WindowCapturerX11::GetWindowProcessID(::Window window) { + // Get _NET_WM_PID property of the window. + Atom process_atom = XInternAtom(display(), "_NET_WM_PID", True); + XWindowProperty process_id(display(), window, process_atom); +@@ -401,11 +350,11 @@ int WindowCapturerLinux::GetWindowProces + } + + // static +-std::unique_ptr DesktopCapturer::CreateRawWindowCapturer( ++std::unique_ptr WindowCapturerX11::CreateRawWindowCapturer( + const DesktopCaptureOptions& options) { + if (!options.x_display()) + return nullptr; +- return std::unique_ptr(new WindowCapturerLinux(options)); ++ return std::unique_ptr(new WindowCapturerX11(options)); + } + + } // namespace webrtc +diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.h.pipewire firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.h +--- firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.h.pipewire 2019-01-07 14:53:17.204061797 +0100 ++++ firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_x11.h 2019-01-07 14:53:17.204061797 +0100 +@@ -0,0 +1,83 @@ ++/* ++ * 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_WINDOW_CAPTURER_X11_H_ ++#define MODULES_DESKTOP_CAPTURE_WINDOW_CAPTURER_X11_H_ ++ ++#include ++#include ++#include ++#include ++ ++#include "webrtc/modules/desktop_capture/desktop_capture_options.h" ++#include "webrtc/modules/desktop_capture/desktop_capturer.h" ++#include "webrtc/modules/desktop_capture/desktop_geometry.h" ++#include "webrtc/modules/desktop_capture/x11/shared_x_display.h" ++#include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h" ++#include "webrtc/base/constructormagic.h" ++#include "webrtc/base/scoped_ref_ptr.h" ++ ++namespace webrtc { ++ ++class WindowCapturerX11 : public DesktopCapturer, ++ public SharedXDisplay::XEventHandler { ++ public: ++ explicit WindowCapturerX11(const DesktopCaptureOptions& options); ++ ~WindowCapturerX11() override; ++ ++ static std::unique_ptr CreateRawWindowCapturer( ++ const DesktopCaptureOptions& options); ++ ++ // DesktopCapturer interface. ++ void Start(Callback* callback) override; ++ void Stop() override; ++ void CaptureFrame() override; ++ bool GetSourceList(SourceList* sources) override; ++ bool SelectSource(SourceId id) override; ++ bool FocusOnSelectedSource() override; ++ ++ // SharedXDisplay::XEventHandler interface. ++ bool HandleXEvent(const XEvent& event) override; ++ ++ private: ++ Display* display() { return x_display_->display(); } ++ ++ // Iterates through |window| hierarchy to find first visible window, i.e. one ++ // that has WM_STATE property set to NormalState. ++ // See http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.3.1 . ++ ::Window GetApplicationWindow(::Window window); ++ ++ // Returns true if the |window| is a desktop element. ++ bool IsDesktopElement(::Window window); ++ ++ // Returns window title for the specified X |window|. ++ bool GetWindowTitle(::Window window, std::string* title); ++ ++ // Returns the id of the owning process. ++ int GetWindowProcessID(::Window window); ++ ++ Callback* callback_ = nullptr; ++ ++ rtc::scoped_refptr x_display_; ++ ++ Atom wm_state_atom_; ++ Atom window_type_atom_; ++ Atom normal_window_type_atom_; ++ bool has_composite_extension_ = false; ++ ++ ::Window selected_window_ = 0; ++ XServerPixelBuffer x_server_pixel_buffer_; ++ ++ RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerX11); ++}; ++ ++} // namespace webrtc ++ ++#endif // MODULES_DESKTOP_CAPTURE_WINDOW_CAPTURER_X11_H_ diff --git a/SOURCES/mozilla-1170092.patch b/SOURCES/mozilla-1170092.patch index 9e8906f..b182d64 100644 --- a/SOURCES/mozilla-1170092.patch +++ b/SOURCES/mozilla-1170092.patch @@ -1,33 +1,32 @@ -diff -up firefox-58.0/extensions/pref/autoconfig/src/nsReadConfig.cpp.1170092 firefox-58.0/extensions/pref/autoconfig/src/nsReadConfig.cpp ---- firefox-58.0/extensions/pref/autoconfig/src/nsReadConfig.cpp.1170092 2018-01-11 21:17:03.000000000 +0100 -+++ firefox-58.0/extensions/pref/autoconfig/src/nsReadConfig.cpp 2018-01-23 13:59:45.446495820 +0100 -@@ -239,9 +239,20 @@ nsresult nsReadConfig::openAndEvaluateJS - return rv; +diff -up firefox-60.5.0/extensions/pref/autoconfig/src/nsReadConfig.cpp.1170092 firefox-60.5.0/extensions/pref/autoconfig/src/nsReadConfig.cpp +--- firefox-60.5.0/extensions/pref/autoconfig/src/nsReadConfig.cpp.1170092 2019-01-22 10:48:38.187383614 +0100 ++++ firefox-60.5.0/extensions/pref/autoconfig/src/nsReadConfig.cpp 2019-01-22 11:26:11.027108692 +0100 +@@ -225,8 +225,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 = 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(NS_LITERAL_CSTRING("pref")); -+ NS_ENSURE_SUCCESS(rv, rv); -+ rv = jsFile->AppendNative(nsDependentCString(aFileName)); -+ NS_ENSURE_SUCCESS(rv, rv); ++ rv = jsFile->AppendNative(NS_LITERAL_CSTRING("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-58.0/modules/libpref/Preferences.cpp.1170092 firefox-58.0/modules/libpref/Preferences.cpp ---- firefox-58.0/modules/libpref/Preferences.cpp.1170092 2018-01-23 13:59:45.447495817 +0100 -+++ firefox-58.0/modules/libpref/Preferences.cpp 2018-01-23 14:02:51.456987774 +0100 -@@ -4402,6 +4402,8 @@ pref_InitInitialObjects() ++ rv = NS_NewLocalFileInputStream(getter_AddRefs(inStr), jsFile); ++ NS_ENSURE_SUCCESS(rv, rv); ++ } + } else { + nsAutoCString location("resource://gre/defaults/autoconfig/"); + location += aFileName; +diff -up firefox-60.5.0/modules/libpref/Preferences.cpp.1170092 firefox-60.5.0/modules/libpref/Preferences.cpp +--- firefox-60.5.0/modules/libpref/Preferences.cpp.1170092 2019-01-21 17:38:16.000000000 +0100 ++++ firefox-60.5.0/modules/libpref/Preferences.cpp 2019-01-22 10:48:38.187383614 +0100 +@@ -3459,6 +3459,8 @@ static nsresult pref_ReadPrefFromJar(nsZ // // Thus, in the omni.jar case, we always load app-specific default // preferences from omni.jar, whether or not `$app == $gre`. @@ -36,10 +35,10 @@ diff -up firefox-58.0/modules/libpref/Preferences.cpp.1170092 firefox-58.0/modul nsresult rv; nsZipFind* findPtr; -diff -up firefox-58.0/toolkit/xre/nsXREDirProvider.cpp.1170092 firefox-58.0/toolkit/xre/nsXREDirProvider.cpp ---- firefox-58.0/toolkit/xre/nsXREDirProvider.cpp.1170092 2018-01-11 21:17:06.000000000 +0100 -+++ firefox-58.0/toolkit/xre/nsXREDirProvider.cpp 2018-01-23 13:59:45.447495817 +0100 -@@ -59,6 +59,7 @@ +diff -up firefox-60.5.0/toolkit/xre/nsXREDirProvider.cpp.1170092 firefox-60.5.0/toolkit/xre/nsXREDirProvider.cpp +--- firefox-60.5.0/toolkit/xre/nsXREDirProvider.cpp.1170092 2019-01-21 17:38:51.000000000 +0100 ++++ firefox-60.5.0/toolkit/xre/nsXREDirProvider.cpp 2019-01-22 11:37:01.868896974 +0100 +@@ -58,6 +58,7 @@ #endif #ifdef XP_UNIX #include @@ -47,10 +46,11 @@ diff -up firefox-58.0/toolkit/xre/nsXREDirProvider.cpp.1170092 firefox-58.0/tool #endif #ifdef XP_IOS #include "UIKitDirProvider.h" -@@ -554,6 +555,20 @@ nsXREDirProvider::GetFile(const char* aP +@@ -491,6 +492,21 @@ nsXREDirProvider::GetFile(const char* aP } } } ++ +#if defined(XP_UNIX) + if (!strcmp(aProperty, NS_APP_PREFS_SYSTEM_CONFIG_DIR)) { + nsCString sysConfigDir = NS_LITERAL_CSTRING("/etc/"); @@ -65,32 +65,34 @@ diff -up firefox-58.0/toolkit/xre/nsXREDirProvider.cpp.1170092 firefox-58.0/tool + } +#endif + - if (NS_FAILED(rv) || !file) - return NS_ERROR_FAILURE; + if (NS_FAILED(rv) || !file) return NS_ERROR_FAILURE; -@@ -887,6 +902,14 @@ nsXREDirProvider::GetFilesInternal(const + if (ensureFilePermissions) { +@@ -796,6 +812,16 @@ nsresult nsXREDirProvider::GetFilesInter LoadDirIntoArray(mXULAppDir, kAppendPrefDir, directories); - LoadDirsIntoArray(mAppBundleDirectories, - kAppendPrefDir, directories); + LoadDirsIntoArray(mAppBundleDirectories, kAppendPrefDir, directories); + + // Add /etc//pref/ directory if it exists + nsCOMPtr systemPrefDir; -+ rv = NS_GetSpecialDirectory(NS_APP_PREFS_SYSTEM_CONFIG_DIR, getter_AddRefs(systemPrefDir)); ++ rv = NS_GetSpecialDirectory(NS_APP_PREFS_SYSTEM_CONFIG_DIR, ++ getter_AddRefs(systemPrefDir)); + if (NS_SUCCEEDED(rv)) { + rv = systemPrefDir->AppendNative(NS_LITERAL_CSTRING("pref")); + if (NS_SUCCEEDED(rv)) + directories.AppendObject(systemPrefDir); + } - ++ rv = NS_NewArrayEnumerator(aResult, directories); - } -diff -up firefox-58.0/xpcom/io/nsAppDirectoryServiceDefs.h.1170092 firefox-58.0/xpcom/io/nsAppDirectoryServiceDefs.h ---- firefox-58.0/xpcom/io/nsAppDirectoryServiceDefs.h.1170092 2018-01-23 13:59:45.447495817 +0100 -+++ firefox-58.0/xpcom/io/nsAppDirectoryServiceDefs.h 2018-01-23 14:02:02.871120476 +0100 -@@ -59,6 +59,7 @@ - #define NS_APP_PREFS_50_FILE "PrefF" - #define NS_APP_PREFS_DEFAULTS_DIR_LIST "PrefDL" - #define NS_APP_PREFS_OVERRIDE_DIR "PrefDOverride" // Directory for per-profile defaults + } 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-60.5.0/xpcom/io/nsAppDirectoryServiceDefs.h.1170092 firefox-60.5.0/xpcom/io/nsAppDirectoryServiceDefs.h +--- firefox-60.5.0/xpcom/io/nsAppDirectoryServiceDefs.h.1170092 2019-01-22 10:48:38.188383609 +0100 ++++ firefox-60.5.0/xpcom/io/nsAppDirectoryServiceDefs.h 2019-01-22 11:08:12.068459480 +0100 +@@ -62,6 +62,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" + #define NS_APP_USER_PROFILE_50_DIR "ProfD" + #define NS_APP_USER_PROFILE_LOCAL_50_DIR "ProfLD" diff --git a/SOURCES/mozilla-1196777.patch b/SOURCES/mozilla-1196777.patch index ba5e4b7..c28cf94 100644 --- a/SOURCES/mozilla-1196777.patch +++ b/SOURCES/mozilla-1196777.patch @@ -1,28 +1,13 @@ -# HG changeset patch -# User Martin Stransky -# Parent 4e3ad95d689a5beabf3c1f41d958794fe00e3767 -Bug 1196777 - Ask GDK to receive focus events, r=?karlt - -diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp ---- a/widget/gtk/nsWindow.cpp -+++ b/widget/gtk/nsWindow.cpp -@@ -142,17 +142,18 @@ const gint kEvents = GDK_EXPOSURE_MASK | - GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | - GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | - #if GTK_CHECK_VERSION(3,4,0) - GDK_SMOOTH_SCROLL_MASK | - GDK_TOUCH_MASK | +diff -up firefox-60.5.0/widget/gtk/nsWindow.cpp.1196777 firefox-60.5.0/widget/gtk/nsWindow.cpp +--- firefox-60.5.0/widget/gtk/nsWindow.cpp.1196777 2019-01-22 11:41:58.630469400 +0100 ++++ firefox-60.5.0/widget/gtk/nsWindow.cpp 2019-01-22 11:42:50.134227448 +0100 +@@ -152,7 +152,8 @@ const gint kEvents = + #if GTK_CHECK_VERSION(3, 4, 0) + GDK_SMOOTH_SCROLL_MASK | GDK_TOUCH_MASK | #endif - GDK_SCROLL_MASK | - GDK_POINTER_MOTION_MASK | -- GDK_PROPERTY_CHANGE_MASK; -+ GDK_PROPERTY_CHANGE_MASK | -+ GDK_FOCUS_CHANGE_MASK; +- GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK; ++ GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK | ++ GDK_FOCUS_CHANGE_MASK; /* utility functions */ - static bool is_mouse_in_window(GdkWindow* aWindow, - gdouble aMouseX, gdouble aMouseY); - static nsWindow *get_window_for_gtk_widget(GtkWidget *widget); - static nsWindow *get_window_for_gdk_window(GdkWindow *window); - static GtkWidget *get_gtk_widget_for_gdk_window(GdkWindow *window); - static GdkCursor *get_gtk_cursor(nsCursor aCursor); + static bool is_mouse_in_window(GdkWindow *aWindow, gdouble aMouseX, diff --git a/SOURCES/mozilla-256180.patch b/SOURCES/mozilla-256180.patch index 13a1c97..4b61b5f 100644 --- a/SOURCES/mozilla-256180.patch +++ b/SOURCES/mozilla-256180.patch @@ -1,5 +1,6 @@ ---- a/layout/generic/nsIFrame.h.old 2016-07-11 13:41:39.688276559 +0200 -+++ b/layout/generic/nsIFrame.h 2016-07-11 13:42:12.791406976 +0200 +diff -up firefox-60.5.0/layout/generic/nsIFrame.h.256180 firefox-60.5.0/layout/generic/nsIFrame.h +--- firefox-60.5.0/layout/generic/nsIFrame.h.256180 2019-01-22 11:44:10.849848268 +0100 ++++ firefox-60.5.0/layout/generic/nsIFrame.h 2019-01-22 11:44:53.918645941 +0100 @@ -13,7 +13,7 @@ #error This header/class should only be used within Mozilla code. It should not be used by extensions. #endif @@ -7,5 +8,5 @@ -#define MAX_REFLOW_DEPTH 200 +#define MAX_REFLOW_DEPTH 1000 - /* nsIFrame is in the process of being deCOMtaminated, i.e., this file is eventually - going to be eliminated, and all callers will use nsFrame instead. At the moment + /* nsIFrame is in the process of being deCOMtaminated, i.e., this file is + eventually going to be eliminated, and all callers will use nsFrame instead. diff --git a/SOURCES/rhbz-1173156.patch b/SOURCES/rhbz-1173156.patch index 9855710..c35d901 100644 --- a/SOURCES/rhbz-1173156.patch +++ b/SOURCES/rhbz-1173156.patch @@ -1,12 +1,12 @@ -diff -up firefox-31.3.0/mozilla-esr31/extensions/auth/nsAuthSambaNTLM.cpp.old firefox-31.3.0/mozilla-esr31/extensions/auth/nsAuthSambaNTLM.cpp ---- firefox-31.3.0/mozilla-esr31/extensions/auth/nsAuthSambaNTLM.cpp.old 2014-11-25 12:23:22.000000000 +0100 -+++ firefox-31.3.0/mozilla-esr31/extensions/auth/nsAuthSambaNTLM.cpp 2014-12-23 15:26:36.606674625 +0100 -@@ -174,7 +174,7 @@ nsAuthSambaNTLM::SpawnNTLMAuthHelper() - return NS_ERROR_FAILURE; +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; - const char* const args[] = { -- "ntlm_auth", -+ "/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/SOURCES/rhbz-1354671.patch b/SOURCES/rhbz-1354671.patch index 6ee89b7..7660f14 100644 --- a/SOURCES/rhbz-1354671.patch +++ b/SOURCES/rhbz-1354671.patch @@ -1,12 +1,12 @@ -diff -up firefox-53.0/layout/base/nsIPresShell.h.1354671 firefox-53.0/layout/base/nsIPresShell.h ---- firefox-53.0/layout/base/nsIPresShell.h.1354671 2017-04-27 13:07:43.808653320 +0200 -+++ firefox-53.0/layout/base/nsIPresShell.h 2017-04-27 13:09:40.404427641 +0200 -@@ -212,7 +212,7 @@ public: +diff -up firefox-60.5.0/layout/base/nsIPresShell.h.1354671 firefox-60.5.0/layout/base/nsIPresShell.h +--- firefox-60.5.0/layout/base/nsIPresShell.h.1354671 2019-01-22 16:08:40.796539950 +0100 ++++ firefox-60.5.0/layout/base/nsIPresShell.h 2019-01-22 16:10:25.106069228 +0100 +@@ -204,7 +204,7 @@ class nsIPresShell : public nsStubDocume * to the same aSize value. AllocateFrame is infallible and will abort * on out-of-memory. */ -- void* AllocateFrame(nsQueryFrame::FrameIID aID, size_t aSize) -+ void* __attribute__((optimize("no-lifetime-dse"))) AllocateFrame(nsQueryFrame::FrameIID aID, size_t aSize) - { +- void* AllocateFrame(nsQueryFrame::FrameIID aID, size_t aSize) { ++ void* __attribute__((optimize("no-lifetime-dse"))) AllocateFrame(nsQueryFrame::FrameIID aID, size_t aSize) { void* result = mFrameArena.AllocateByFrameID(aID, aSize); RecordAlloc(result); + return result; diff --git a/SOURCES/rhbz-1503632-nss.patch b/SOURCES/rhbz-1503632-nss.patch index f9f5e4d..f7a26d3 100644 --- a/SOURCES/rhbz-1503632-nss.patch +++ b/SOURCES/rhbz-1503632-nss.patch @@ -1,12 +1,7 @@ -diff --git a/security/certverifier/NSSCertDBTrustDomain.cpp b/security/certverifier/NSSCertDBTrustDomain.cpp ---- a/security/certverifier/NSSCertDBTrustDomain.cpp -+++ b/security/certverifier/NSSCertDBTrustDomain.cpp -@@ -1057,22 +1057,20 @@ InitializeNSS(const nsACString& dir, boo - // "/usr/lib/nss/libnssckbi.so". - uint32_t flags = NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE; - if (readOnly) { - flags |= NSS_INIT_READONLY; - } +diff -up firefox-60.5.0/security/certverifier/NSSCertDBTrustDomain.cpp.1503632-nss firefox-60.5.0/security/certverifier/NSSCertDBTrustDomain.cpp +--- firefox-60.5.0/security/certverifier/NSSCertDBTrustDomain.cpp.1503632-nss 2019-01-22 11:38:49.484365928 +0100 ++++ firefox-60.5.0/security/certverifier/NSSCertDBTrustDomain.cpp 2019-01-22 11:40:52.694779150 +0100 +@@ -1077,13 +1077,11 @@ SECStatus InitializeNSS(const nsACString if (!loadPKCS11Modules) { flags |= NSS_INIT_NOMODDB; } @@ -16,13 +11,9 @@ diff --git a/security/certverifier/NSSCertDBTrustDomain.cpp b/security/certverif - ("InitializeNSS(%s, %d, %d)", dbTypeAndDirectory.get(), readOnly, + ("InitializeNSS(%s, %d, %d)", PromiseFlatCString(dir).get(), readOnly, loadPKCS11Modules)); -- SECStatus srv = NSS_Initialize(dbTypeAndDirectory.get(), "", "", -+ SECStatus srv = NSS_Initialize(PromiseFlatCString(dir).get(), "", "", - SECMOD_DB, flags); + SECStatus srv = +- NSS_Initialize(dbTypeAndDirectory.get(), "", "", SECMOD_DB, flags); ++ NSS_Initialize(PromiseFlatCString(dir).get(), "", "", SECMOD_DB, flags); if (srv != SECSuccess) { return srv; } - - if (!readOnly) { - UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); - if (!slot) { diff --git a/SOURCES/xulrunner-24.0-jemalloc-ppc.patch b/SOURCES/xulrunner-24.0-jemalloc-ppc.patch index 75aed9a..c8fe421 100644 --- a/SOURCES/xulrunner-24.0-jemalloc-ppc.patch +++ b/SOURCES/xulrunner-24.0-jemalloc-ppc.patch @@ -1,12 +1,12 @@ -diff -up firefox-60.0/memory/build/mozjemalloc.cpp.ppc-jemalloc firefox-60.0/memory/build/mozjemalloc.cpp ---- firefox-60.0/memory/build/mozjemalloc.cpp.ppc-jemalloc 2018-06-06 14:39:28.454371053 +0200 -+++ firefox-60.0/memory/build/mozjemalloc.cpp 2018-06-06 14:39:40.242397928 +0200 +diff -up firefox-60.5.0/memory/build/mozjemalloc.cpp.jemalloc-ppc firefox-60.5.0/memory/build/mozjemalloc.cpp +--- firefox-60.5.0/memory/build/mozjemalloc.cpp.jemalloc-ppc 2019-01-22 10:25:30.764207480 +0100 ++++ firefox-60.5.0/memory/build/mozjemalloc.cpp 2019-01-22 10:28:48.352235343 +0100 @@ -180,7 +180,7 @@ using namespace mozilla; // Debug builds are opted out too, for test coverage. #ifndef MOZ_DEBUG - #if !defined(__ia64__) && !defined(__sparc__) && !defined(__mips__) && \ -- !defined(__aarch64__) -+ !defined(__aarch64__) && !defined(__powerpc__) + #if !defined(__ia64__) && !defined(__sparc__) && !defined(__mips__) && \ +- !defined(__aarch64__) ++ !defined(__aarch64__) && !defined(__powerpc__) #define MALLOC_STATIC_PAGESIZE 1 #endif #endif diff --git a/SPECS/firefox.spec b/SPECS/firefox.spec index dd09789..18f3345 100644 --- a/SPECS/firefox.spec +++ b/SPECS/firefox.spec @@ -26,7 +26,9 @@ %define use_bundled_python 0 %endif +%if 0%{?rhel} < 8 %global use_rustts 1 +%endif %global dts_version 7 %global rst_version 7 %global llvm_version 7 @@ -139,8 +141,8 @@ Summary: Mozilla Firefox Web browser Name: firefox -Version: 60.4.0 -Release: 1%{?pre_tag}%{?dist} +Version: 60.5.0 +Release: 2%{?pre_tag}%{?dist} URL: https://www.mozilla.org/firefox/ License: MPLv1.1 or GPLv2+ or LGPLv2+ %if 0%{?rhel} == 7 @@ -152,7 +154,7 @@ ExclusiveArch: i686 x86_64 ppc64 s390x Source0: https://hg.mozilla.org/releases/mozilla-release/archive/firefox-%{version}%{?pre_version}.source.tar.xz %if %{build_langpacks} -Source1: firefox-langpacks-%{version}%{?pre_version}-20181205.tar.xz +Source1: firefox-langpacks-%{version}%{?pre_version}-20190125.tar.xz %endif Source10: firefox-mozconfig Source12: firefox-redhat-default-prefs.js @@ -190,7 +192,7 @@ Patch37: build-jit-atomic-always-lucky.patch Patch40: build-aarch64-skia.patch Patch41: build-debug-qcms.patch Patch43: xulrunner-24.0-jemalloc-ppc.patch -Patch44: firefox-disable-dbus-remote.patch +#Patch44: firefox-disable-dbus-remote.patch Patch45: build-disable-elfhack.patch # Fedora/RHEL specific patches @@ -201,6 +203,7 @@ Patch225: mozilla-1005640-accept-lang.patch #ARM run-time patch Patch226: rhbz-1354671.patch Patch230: rhbz-1503632-nss.patch +Patch231: firefox-pipewire.patch # Upstream patches Patch402: mozilla-1196777.patch @@ -262,6 +265,14 @@ BuildRequires: llvm-toolset-%{llvm_version} BuildRequires: llvm-toolset-%{llvm_version}-llvm-devel %endif %endif + +%if 0%{?rhel} == 8 +BuildRequires: cargo +BuildRequires: rust >= 1.24 +BuildRequires: llvm >= %{llvm_version} +BuildRequires: llvm-devel >= %{llvm_version} +BuildRequires: clang >= %{llvm_version} +%else %if 0%{?use_rustts} BuildRequires: rust-toolset-%{rst_version}-cargo BuildRequires: rust-toolset-%{rst_version}-rust >= 1.24 @@ -270,6 +281,8 @@ BuildRequires: rust-toolset-%{rst_version}-rust >= 1.24 BuildRequires: llvm-toolset-%{llvm_version} BuildRequires: llvm-toolset-%{llvm_version}-llvm-devel %endif +%endif + %if 0%{?use_bundled_python} #%if 0%{?rhel} == 6 # Needed for Python in RHEL6 @@ -277,6 +290,10 @@ BuildRequires: openssl-devel #%endif %endif +%if 0%{?rhel} == 8 +BuildRequires: pipewire-devel +%endif + %if 0%{?bundle_gtk3} BuildRequires: automake BuildRequires: autoconf @@ -403,9 +420,6 @@ Requires: gnome-icon-theme Requires: gnome-shell Requires: hicolor-icon-theme Requires: mozilla-filesystem -Requires: python3-gobject-base -Requires: python3-requests - %description -n firefox-gnome-shell-extension Browser extension for Firefox and native host messaging connector that provides @@ -431,9 +445,9 @@ https://extensions.gnome.org. %endif %patch43 -p1 -b .jemalloc-ppc # Disable DBus remote on RHEL6 as it does not build here. -%if 0%{?rhel} == 6 -%patch44 -p1 -b .disable-dbus-remote -%endif +#%if 0%{?rhel} == 6 +#%patch44 -p1 -b .disable-dbus-remote +#%endif %if 0%{?rhel} == 8 %patch45 -p1 -b .disable-elfhack %endif @@ -445,9 +459,12 @@ https://extensions.gnome.org. # Fedora patches %patch215 -p1 -b .addons -%patch219 -p2 -b .rhbz-1173156 +%patch219 -p1 -b .rhbz-1173156 %patch224 -p1 -b .1170092 %patch225 -p1 -b .1005640-accept-lang +%if 0%{?rhel} == 8 +%patch231 -p1 -b .pipewire +%endif # This ensures no migration of certdb to sqlite on the RHEL6 and RHEL7. # This needs to stay for the future releases @@ -810,6 +827,9 @@ MOZ_SMP_FLAGS=-j1 export MOZ_MAKE_FLAGS="$MOZ_SMP_FLAGS" export MOZ_SERVICES_SYNC="1" export STRIP=/bin/true +%if 0%{?rhel} == 8 +export LLVM_CONFIG=/usr/bin/llvm-config-64 +%endif ./mach build -v # create debuginfo for crash-stats.mozilla.com @@ -908,7 +928,7 @@ desktop-file-install --dir %{buildroot}%{_datadir}/applications %{SOURCE20} %{__rm} -rf %{buildroot}%{_bindir}/firefox %{__cat} %{SOURCE21} > %{buildroot}%{_bindir}/firefox %if 0%{?bundle_gtk3} -sed -i -e 's|%RHEL_ENV_VARS%|export XDG_DATA_DIRS="$MOZ_LIB_DIR/firefox/bundled/share:/usr/share:$XDG_DATA_DIRS"|' %{buildroot}%{_bindir}/firefox +sed -i -e 's|%RHEL_ENV_VARS%|export XDG_DATA_DIRS="$MOZ_LIB_DIR/firefox/bundled/share:/usr/share:$XDG_DATA_DIRS"\nexport FONTCONFIG_FILE="$MOZ_LIB_DIR/firefox/bundled/etc/fonts/fonts.conf"|' %{buildroot}%{_bindir}/firefox %else sed -i -e 's|%RHEL_ENV_VARS%||' %{buildroot}%{_bindir}/firefox %endif @@ -1199,6 +1219,18 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #--------------------------------------------------------------------- %changelog +* Fri Jan 25 2019 Martin Stransky - 60.5.0-2 +- Updated to 60.5.0 ESR build2 + +* Tue Jan 22 2019 Martin Stransky - 60.5.0-1 +- Updated to 60.5.0 ESR build1 + +* Thu Jan 10 2019 Jan Horak - 60.4.0-3 +- Fixing fontconfig warnings (rhbz#1601475) + +* Wed Jan 9 2019 Jan Horak - 60.4.0-2 +- Added pipewire patch from Tomas Popela (rhbz#1664270) + * Wed Dec 5 2018 Jan Horak - 60.4.0-1 - Update to 60.4.0 ESR