diff --git a/.firefox.metadata b/.firefox.metadata
index 49c7dde..0fab77b 100644
--- a/.firefox.metadata
+++ b/.firefox.metadata
@@ -1,7 +1,10 @@
 18a8f30a0356c751b8d0ea6f76e764cab13ee046 SOURCES/Python-2.7.13.tar.xz
-733187de6b20f8902fa207f08ec85f952a2c2e40 SOURCES/firefox-60.7.0esr.source.tar.xz
-7078da81de13917fa6c4e85f1395552bff67f056 SOURCES/firefox-langpacks-60.7.0esr-20190515.tar.xz
+e86c38c48960b95353503b78e1de9ddca1ed34d7 SOURCES/cbindgen-vendor.tar.xz
+220c262c5cb2ee81d29c58a5afe4522c9880cf2b SOURCES/firefox-68.3.0esr.source.tar.xz
+e4958412ffa347f9de0315e54d6596461169f029 SOURCES/firefox-langpacks-68.3.0esr-20191127.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
+4f8d3bf2483d95261ff90742ecec82d6a899eca3 SOURCES/nodejs-8.11.4-1.3.fc27.src.rpm
+a379070abf5000cde61411c97af7e733b267a4d3 SOURCES/openssl-1.0.2k-19.6.bundle.el7_7.src.rpm
 77fd30f7ebc12a629a31c1e252cec06af55a71fe SOURCES/yasm-1.2.0-3.el5.src.rpm
diff --git a/.gitignore b/.gitignore
index 09d4148..bc20190 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,10 @@
 SOURCES/Python-2.7.13.tar.xz
-SOURCES/firefox-60.7.0esr.source.tar.xz
-SOURCES/firefox-langpacks-60.7.0esr-20190515.tar.xz
+SOURCES/cbindgen-vendor.tar.xz
+SOURCES/firefox-68.3.0esr.source.tar.xz
+SOURCES/firefox-langpacks-68.3.0esr-20191127.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
+SOURCES/nodejs-8.11.4-1.3.fc27.src.rpm
+SOURCES/openssl-1.0.2k-19.6.bundle.el7_7.src.rpm
 SOURCES/yasm-1.2.0-3.el5.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-icu-big-endian.patch b/SOURCES/build-icu-big-endian.patch
index c26a4d4..ee5fd6a 100644
--- a/SOURCES/build-icu-big-endian.patch
+++ b/SOURCES/build-icu-big-endian.patch
@@ -1,12 +1,13 @@
-diff -up firefox-60.0/build/autoconf/icu.m4.icu firefox-60.0/build/autoconf/icu.m4
---- firefox-60.0/build/autoconf/icu.m4.icu	2018-04-17 15:11:54.100644119 +0200
-+++ firefox-60.0/build/autoconf/icu.m4	2018-04-17 15:12:50.740686636 +0200
+diff -up firefox-68.0/build/autoconf/icu.m4.icu firefox-68.0/build/autoconf/icu.m4
+--- firefox-68.0/build/autoconf/icu.m4.icu	2019-06-25 21:25:25.394425654 +0200
++++ firefox-68.0/build/autoconf/icu.m4	2019-06-25 21:26:23.544210474 +0200
 @@ -78,7 +78,7 @@ if test -n "$USE_ICU"; then
      # TODO: the l is actually endian-dependent
      # We could make this set as 'l' or 'b' for little or big, respectively,
      # but we'd need to check in a big-endian version of the file.
 -    ICU_DATA_FILE="icudt${version}l.dat"
 +    ICU_DATA_FILE="icudt${version}b.dat"
- 
-     MOZ_ICU_DATA_ARCHIVE=
  fi
+ 
+ AC_SUBST(MOZ_ICU_VERSION)
+
diff --git a/SOURCES/build-nss-version.patch b/SOURCES/build-nss-version.patch
index 94947f2..680961d 100644
--- a/SOURCES/build-nss-version.patch
+++ b/SOURCES/build-nss-version.patch
@@ -1,12 +1,12 @@
-diff -up firefox-60.1.0/old-configure.in.nss-version firefox-60.1.0/old-configure.in
---- firefox-60.1.0/old-configure.in.nss-version	2018-06-20 14:24:55.204158540 +0200
-+++ firefox-60.1.0/old-configure.in	2018-06-20 14:30:19.517004230 +0200
-@@ -1768,7 +1768,7 @@ MOZ_ARG_WITH_BOOL(system-nss,
+diff -up firefox-68.3.0/old-configure.in.nss-version firefox-68.3.0/old-configure.in
+--- firefox-68.3.0/old-configure.in.nss-version	2019-11-27 19:48:01.045677621 +0100
++++ firefox-68.3.0/old-configure.in	2019-11-27 19:59:52.856894047 +0100
+@@ -1537,7 +1537,7 @@ MOZ_ARG_WITH_BOOL(system-nss,
      _USE_SYSTEM_NSS=1 )
  
  if test -n "$_USE_SYSTEM_NSS"; then
--    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])])
+-    AM_PATH_NSS(3.44.3, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
++    AM_PATH_NSS(3.44.0, [MOZ_SYSTEM_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
  fi
  
- if test -z "$MOZ_SYSTEM_NSS"; then
+ NSS_CFLAGS="$NSS_CFLAGS -I${DIST}/include/nss"
diff --git a/SOURCES/build-ppc64le-inline.patch b/SOURCES/build-ppc64le-inline.patch
new file mode 100644
index 0000000..de0f6d9
--- /dev/null
+++ b/SOURCES/build-ppc64le-inline.patch
@@ -0,0 +1,27 @@
+diff -up firefox-68.1.0/js/xpconnect/src/XPCWrappedNative.cpp.ppc64le-inline firefox-68.1.0/js/xpconnect/src/XPCWrappedNative.cpp
+--- firefox-68.1.0/js/xpconnect/src/XPCWrappedNative.cpp.ppc64le-inline	2019-08-26 18:52:28.000000000 +0200
++++ firefox-68.1.0/js/xpconnect/src/XPCWrappedNative.cpp	2019-08-29 08:49:57.695687874 +0200
+@@ -1092,7 +1092,11 @@ class MOZ_STACK_CLASS CallMethodHelper f
+   MOZ_ALWAYS_INLINE bool GetOutParamSource(uint8_t paramIndex,
+                                            MutableHandleValue srcp) const;
+ 
++#if (__GNUC__ && __linux__ && __PPC64__ && _LITTLE_ENDIAN)
++  bool GatherAndConvertResults();
++#else
+   MOZ_ALWAYS_INLINE bool GatherAndConvertResults();
++#endif
+ 
+   MOZ_ALWAYS_INLINE bool QueryInterfaceFastPath();
+ 
+@@ -1139,7 +1143,11 @@ class MOZ_STACK_CLASS CallMethodHelper f
+ 
+   ~CallMethodHelper();
+ 
++#if (__GNUC__ && __linux__ && __PPC64__ && _LITTLE_ENDIAN)
++  bool Call();
++#else
+   MOZ_ALWAYS_INLINE bool Call();
++#endif
+ 
+   // Trace implementation so we can put our CallMethodHelper in a Rooted<T>.
+   void trace(JSTracer* aTrc);
diff --git a/SOURCES/firefox-debugedits-error.patch b/SOURCES/firefox-debugedits-error.patch
new file mode 100644
index 0000000..a4b005f
--- /dev/null
+++ b/SOURCES/firefox-debugedits-error.patch
@@ -0,0 +1,50 @@
+diff -up firefox-68.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.old firefox-68.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium
+diff -up firefox-68.0/media/webrtc/trunk/Makefile.old firefox-68.0/media/webrtc/trunk/Makefile
+diff -up firefox-68.0/media/webrtc/trunk/webrtc/modules/audio_processing/utility/ooura_fft.cc.old firefox-68.0/media/webrtc/trunk/webrtc/modules/audio_processing/utility/ooura_fft.cc
+--- firefox-68.0/media/webrtc/trunk/webrtc/modules/audio_processing/utility/ooura_fft.cc.old	2019-06-12 08:17:02.673268442 +0200
++++ firefox-68.0/media/webrtc/trunk/webrtc/modules/audio_processing/utility/ooura_fft.cc	2019-06-12 08:17:13.582328073 +0200
+@@ -21,7 +21,7 @@
+  *  be found in the AUTHORS file in the root of the source tree.
+  */
+ 
+-#include "modules/audio_processing//utility/ooura_fft.h"
++#include "modules/audio_processing/utility/ooura_fft.h"
+ 
+ #include <math.h>
+ 
+diff -up firefox-68.0/media/webrtc/trunk/webrtc/modules/audio_processing/utility/ooura_fft_sse2.cc.old firefox-68.0/media/webrtc/trunk/webrtc/modules/audio_processing/utility/ooura_fft_sse2.cc
+--- firefox-68.0/media/webrtc/trunk/webrtc/modules/audio_processing/utility/ooura_fft_sse2.cc.old	2019-06-12 08:17:36.671454285 +0200
++++ firefox-68.0/media/webrtc/trunk/webrtc/modules/audio_processing/utility/ooura_fft_sse2.cc	2019-06-12 08:17:46.989510679 +0200
+@@ -8,7 +8,7 @@
+  *  be found in the AUTHORS file in the root of the source tree.
+  */
+ 
+-#include "modules/audio_processing//utility/ooura_fft.h"
++#include "modules/audio_processing/utility/ooura_fft.h"
+ 
+ #include <emmintrin.h>
+ 
+diff -up firefox-68.0/third_party/aom/aom_dsp/x86/masked_sad_intrin_avx2.c.old firefox-68.0/third_party/aom/aom_dsp/x86/masked_sad_intrin_avx2.c
+--- firefox-68.0/third_party/aom/aom_dsp/x86/masked_sad_intrin_avx2.c.old	2019-06-12 08:16:15.673011534 +0200
++++ firefox-68.0/third_party/aom/aom_dsp/x86/masked_sad_intrin_avx2.c	2019-06-12 08:16:22.602049410 +0200
+@@ -17,7 +17,7 @@
+ #include "aom_dsp/blend.h"
+ #include "aom/aom_integer.h"
+ #include "aom_dsp/x86/synonyms.h"
+-#include "aom_dsp/x86//masked_sad_intrin_ssse3.h"
++#include "aom_dsp/x86/masked_sad_intrin_ssse3.h"
+ 
+ static INLINE unsigned int masked_sad32xh_avx2(
+     const uint8_t *src_ptr, int src_stride, const uint8_t *a_ptr, int a_stride,
+diff -up firefox-68.0/third_party/aom/aom_dsp/x86/masked_sad_intrin_ssse3.c.old firefox-68.0/third_party/aom/aom_dsp/x86/masked_sad_intrin_ssse3.c
+--- firefox-68.0/third_party/aom/aom_dsp/x86/masked_sad_intrin_ssse3.c.old	2019-06-12 08:16:35.404119384 +0200
++++ firefox-68.0/third_party/aom/aom_dsp/x86/masked_sad_intrin_ssse3.c	2019-06-12 08:16:43.415163174 +0200
+@@ -19,7 +19,7 @@
+ #include "aom/aom_integer.h"
+ #include "aom_dsp/x86/synonyms.h"
+ 
+-#include "aom_dsp/x86//masked_sad_intrin_ssse3.h"
++#include "aom_dsp/x86/masked_sad_intrin_ssse3.h"
+ 
+ // For width a multiple of 16
+ static INLINE unsigned int masked_sad_ssse3(const uint8_t *src_ptr,
diff --git a/SOURCES/firefox-dont-check-binary.patch b/SOURCES/firefox-dont-check-binary.patch
new file mode 100644
index 0000000..c498034
--- /dev/null
+++ b/SOURCES/firefox-dont-check-binary.patch
@@ -0,0 +1,47 @@
+diff -up firefox-68.0/config/rules.mk.old firefox-68.0/config/rules.mk
+--- firefox-68.0/config/rules.mk.old	2019-06-26 09:36:58.537034443 +0200
++++ firefox-68.0/config/rules.mk	2019-06-26 09:37:38.004970573 +0200
+@@ -569,7 +569,6 @@ ifdef MOZ_PROFILE_GENERATE
+ endif
+ else # !WINNT || GNU_CC
+ 	$(call EXPAND_CC_OR_CXX,$@) -o $@ $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) $($(notdir $@)_$(OBJS_VAR_SUFFIX)) $(RESFILE) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(STATIC_LIBS) $(RUST_STATIC_LIB) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(OS_LIBS)
+-	$(call py_action,check_binary,--target $@)
+ endif # WINNT && !GNU_CC
+ 
+ ifdef ENABLE_STRIP
+@@ -604,9 +603,6 @@ else
+ 	$(HOST_CC) -o $@ $(HOST_C_LDFLAGS) $(HOST_LDFLAGS) $($(notdir $@)_OBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+ endif # HOST_CPP_PROG_LINK
+ endif
+-ifndef CROSS_COMPILE
+-	$(call py_action,check_binary,--host $@)
+-endif
+ 
+ #
+ # This is an attempt to support generation of multiple binaries
+@@ -630,7 +626,6 @@ ifdef MSMANIFEST_TOOL
+ endif	# MSVC with manifest tool
+ else
+ 	$(call EXPAND_CC_OR_CXX,$@) $(COMPUTED_CXX_LDFLAGS) $(PGO_CFLAGS) -o $@ $($@_$(OBJS_VAR_SUFFIX)) $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(STATIC_LIBS) $(MOZ_PROGRAM_LDFLAGS) $(SHARED_LIBS) $(OS_LIBS)
+-	$(call py_action,check_binary,--target $@)
+ endif # WINNT && !GNU_CC
+ 
+ ifdef ENABLE_STRIP
+@@ -651,9 +646,6 @@ else
+ 	$(HOST_CC) $(HOST_OUTOPTION)$@ $(HOST_C_LDFLAGS) $($(notdir $@)_OBJS) $(HOST_LIBS) $(HOST_EXTRA_LIBS)
+ endif
+ endif
+-ifndef CROSS_COMPILE
+-	$(call py_action,check_binary,--host $@)
+-endif
+ 
+ $(LIBRARY): $(OBJS) $(STATIC_LIBS) $(EXTRA_DEPS) $(GLOBAL_DEPS)
+ 	$(REPORT_BUILD)
+@@ -691,7 +683,6 @@ ifndef INCREMENTAL_LINKER
+ 	$(RM) $@
+ endif
+ 	$(MKSHLIB) $($@_$(OBJS_VAR_SUFFIX)) $(RESFILE) $(LDFLAGS) $(STATIC_LIBS) $(RUST_STATIC_LIB) $(SHARED_LIBS) $(EXTRA_DSO_LDOPTS) $(MOZ_GLUE_LDFLAGS) $(OS_LIBS)
+-	$(call py_action,check_binary,--target $@)
+ 
+ ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
+ ifdef MSMANIFEST_TOOL
diff --git a/SOURCES/firefox-mozconfig b/SOURCES/firefox-mozconfig
index 87d1efc..5585559 100644
--- a/SOURCES/firefox-mozconfig
+++ b/SOURCES/firefox-mozconfig
@@ -6,7 +6,6 @@ ac_add_options --prefix="$PREFIX"
 ac_add_options --libdir="$LIBDIR"
 ac_add_options --with-system-zlib
 ac_add_options --with-system-bz2
-ac_add_options --with-pthreads
 ac_add_options --disable-strip
 ac_add_options --disable-tests
 #ac_add_options --enable-libnotify
@@ -19,8 +18,7 @@ ac_add_options --with-system-icu
 ac_add_options --with-mozilla-api-keyfile=../mozilla-api-key
 ac_add_options --with-google-location-service-api-keyfile=../google-api-key
 ac_add_options --with-google-safebrowsing-api-keyfile=../google-api-key
-ac_add_options --enable-release
-ac_add_options --enable-pie
+ac_add_options --disable-av1
 
 export BUILD_OFFICIAL=1
 export MOZILLA_OFFICIAL=1
diff --git a/SOURCES/firefox-pipewire.patch b/SOURCES/firefox-pipewire.patch
index 57bf8b4..7233a73 100644
--- a/SOURCES/firefox-pipewire.patch
+++ b/SOURCES/firefox-pipewire.patch
@@ -1,6 +1,6 @@
-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
+diff -up firefox-68.0/config/system-headers.mozbuild.firefox-pipewire firefox-68.0/config/system-headers.mozbuild
+--- firefox-68.0/config/system-headers.mozbuild.firefox-pipewire	2019-07-01 22:30:26.000000000 +0200
++++ firefox-68.0/config/system-headers.mozbuild	2019-07-08 15:26:15.397161627 +0200
 @@ -314,6 +314,7 @@ system_headers = [
      'Gestalt.h',
      'getopt.h',
@@ -17,1398 +17,11 @@ diff -up firefox-60.3.0/config/system-headers.mozbuild.pipewire firefox-60.3.0/c
      '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> 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 <assert.h>
- #include <string.h>
-@@ -21,80 +18,19 @@
- 
- #include <algorithm>
- 
-+#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<DesktopFrame> GetFrame() { return std::move(frame_); }
--
--   // Callback interface
--  virtual void OnCaptureResult(DesktopCapturer::Result result,
--                               std::unique_ptr<DesktopFrame> frame) {
--    frame_ = std::move(frame);
--  }
--
--protected:
--  std::unique_ptr<DesktopCapturer> screen_capturer_;
--  std::unique_ptr<DesktopFrame> 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<ProcessId>(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<SharedXDisplay> 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> DesktopCapturer::CreateRawAppCapturer(
-+std::unique_ptr<DesktopCapturer> AppCapturerX11::CreateRawAppCapturer(
-     const DesktopCaptureOptions& options) {
- 
-   if (!options.x_display())
-     return nullptr;
- 
--  std::unique_ptr<AppCapturerLinux> capturer(new AppCapturerLinux(options));
-+  std::unique_ptr<AppCapturerX11> capturer(new AppCapturerX11(options));
- 
-   return std::unique_ptr<DesktopCapturer>(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 <X11/X.h>
-+#include <X11/Xlib.h>
-+#include <memory>
-+#include <string>
-+
-+#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<DesktopFrame> GetFrame() { return std::move(frame_); }
-+
-+   // Callback interface
-+  virtual void OnCaptureResult(DesktopCapturer::Result result,
-+                               std::unique_ptr<DesktopFrame> frame) {
-+    frame_ = std::move(frame);
-+  }
-+
-+protected:
-+  std::unique_ptr<DesktopCapturer> screen_capturer_;
-+  std::unique_ptr<DesktopFrame> frame_;
-+};
-+
-+class AppCapturerX11 : public AppCapturer {
-+public:
-+  AppCapturerX11(const DesktopCaptureOptions& options);
-+  virtual ~AppCapturerX11();
-+
-+  static AppCapturer* Create(const DesktopCaptureOptions& options);
-+  static std::unique_ptr<DesktopCapturer> 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<ProcessId>(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<SharedXDisplay> 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 <cstring>
-+#include <gio/gunixfdlist.h>
-+#include <glib-object.h>
-+
-+#include <spa/param/format-utils.h>
-+#include <spa/param/props.h>
-+#include <spa/param/video/raw-utils.h>
-+#include <spa/support/type-map.h>
-+
-+#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<BaseCapturerPipeWire*>(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<BaseCapturerPipeWire*>(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<BaseCapturerPipeWire*>(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*>(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*>(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<BaseCapturerPipeWire*>(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<GAsyncReadyCallback>(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<uint32_t>(desktop_size_.width()),
-+                    static_cast<uint32_t>(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*>(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_flags>(
-+      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<uint8_t*>(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<uint8_t*>(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<BaseCapturerPipeWire*>(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<GAsyncReadyCallback>(OnSessionRequested), this);
-+}
-+
-+// static
-+void BaseCapturerPipeWire::OnSessionRequested(GDBusConnection* connection,
-+                                                GAsyncResult* result,
-+                                                gpointer user_data) {
-+  BaseCapturerPipeWire* that =
-+      static_cast<BaseCapturerPipeWire*>(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<BaseCapturerPipeWire*>(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<GAsyncReadyCallback>(OnSourcesRequested), this);
-+}
-+
-+// static
-+void BaseCapturerPipeWire::OnSourcesRequested(GDBusConnection* connection,
-+                                                GAsyncResult* result,
-+                                                gpointer user_data) {
-+  BaseCapturerPipeWire* that =
-+      static_cast<BaseCapturerPipeWire*>(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<BaseCapturerPipeWire*>(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<GAsyncReadyCallback>(OnStartRequested), this);
-+}
-+
-+// static
-+void BaseCapturerPipeWire::OnStartRequested(GDBusConnection* connection,
-+                                              GAsyncResult* result,
-+                                              gpointer user_data) {
-+  BaseCapturerPipeWire* that =
-+      static_cast<BaseCapturerPipeWire*>(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<BaseCapturerPipeWire*>(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 <method name="Start">.
-+  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<GAsyncReadyCallback>(OnOpenPipeWireRemoteRequested),
-+      this);
-+}
-+
-+// static
-+void BaseCapturerPipeWire::OnOpenPipeWireRemoteRequested(
-+    GDBusConnection* connection,
-+    GAsyncResult* result,
-+    gpointer user_data) {
-+  BaseCapturerPipeWire* that =
-+      static_cast<BaseCapturerPipeWire*>(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<DesktopFrame> 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 <gio/gio.h>
-+#define typeof __typeof__
-+#include <pipewire/pipewire.h>
-+#include <spa/param/video/format-utils.h>
-+
-+#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"
+diff -up firefox-68.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build.firefox-pipewire firefox-68.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build
+--- firefox-68.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build.firefox-pipewire	2019-07-01 22:30:33.000000000 +0200
++++ firefox-68.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build	2019-07-08 15:26:15.397161627 +0200
+@@ -194,6 +194,28 @@ if CONFIG["OS_TARGET"] == "Linux":
+         "/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc"
      ]
  
 +# PipeWire specific files
@@ -1427,1146 +40,24 @@ diff -up firefox-60.3.0/media/webrtc/trunk/webrtc/modules/desktop_capture/deskto
 +    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"
++        "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc",
++        "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc",
++        "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/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<SharedXDisplay> x_display_;
-@@ -129,6 +134,9 @@ class DesktopCaptureOptions {
- #endif
+diff -up firefox-68.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h.firefox-pipewire firefox-68.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h
+--- firefox-68.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h.firefox-pipewire	2019-07-08 16:42:13.936254926 +0200
++++ firefox-68.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h	2019-07-08 16:42:17.509264974 +0200
+@@ -141,7 +141,7 @@ class DesktopCaptureOptions {
    bool disable_effects_ = true;
    bool detect_updated_region_ = false;
-+#if defined(WEBRTC_USE_PIPEWIRE)
+ #if defined(WEBRTC_USE_PIPEWIRE)
+-  bool allow_pipewire_ = false;
 +  bool allow_pipewire_ = true;
-+#endif
+ #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<DesktopCapturer> 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<DesktopCapturer> 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 <X11/Xlib.h>
- #include <X11/Xutil.h>
- 
-+#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<SharedXDisplay> 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<MouseCursor> 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 <X11/X.h>
-+#include <memory>
-+
-+#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<SharedXDisplay> 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<MouseCursor> 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> 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 <memory>
-+
-+namespace webrtc {
-+
-+ScreenCapturerPipeWire::ScreenCapturerPipeWire()
-+    : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {}
-+ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {}
-+
-+// static
-+std::unique_ptr<DesktopCapturer>
-+ScreenCapturerPipeWire::CreateRawScreenCapturer(
-+    const DesktopCaptureOptions& options) {
-+  std::unique_ptr<ScreenCapturerPipeWire> 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 <memory>
-+
-+#include "webrtc/modules/desktop_capture/base_capturer_pipewire.h"
-+
-+namespace webrtc {
-+
-+class ScreenCapturerPipeWire : public BaseCapturerPipeWire {
-+ public:
-+  ScreenCapturerPipeWire();
-+  ~ScreenCapturerPipeWire() override;
-+
-+  static std::unique_ptr<DesktopCapturer> 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 <X11/Xlib.h>
- #include <X11/Xutil.h>
- 
-+#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<DesktopFrame> 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<SharedDesktopFrame> 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<DesktopFrame> 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<const XDamageNotifyEvent*>(&event);
-@@ -295,7 +211,7 @@ bool ScreenCapturerLinux::HandleXEvent(c
-   return false;
- }
- 
--std::unique_ptr<DesktopFrame> ScreenCapturerLinux::CaptureScreen() {
-+std::unique_ptr<DesktopFrame> ScreenCapturerX11::CaptureScreen() {
-   std::unique_ptr<SharedDesktopFrame> frame = queue_.current_frame()->Share();
-   RTC_DCHECK(x_server_pixel_buffer_.window_size().equals(frame->size()));
- 
-@@ -345,14 +261,15 @@ std::unique_ptr<DesktopFrame> 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> DesktopCapturer::CreateRawScreenCapturer(
-+std::unique_ptr<DesktopCapturer> ScreenCapturerX11::CreateRawScreenCapturer(
-     const DesktopCaptureOptions& options) {
-   if (!options.x_display())
-     return nullptr;
- 
--  std::unique_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux());
-+  std::unique_ptr<ScreenCapturerX11> capturer(new ScreenCapturerX11());
-   if (!capturer.get()->Init(options)) {
-     return nullptr;
-   }
- 
--  return std::unique_ptr<DesktopCapturer>(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 <X11/X.h>
-+#include <X11/Xlib.h>
-+#include <X11/extensions/Xdamage.h>
-+#include <X11/extensions/Xfixes.h>
-+#include <memory>
-+
-+#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<DesktopCapturer> 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<DesktopFrame> 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<SharedDesktopFrame> 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> 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<DesktopCapturer>
-+WindowCapturerPipeWire::CreateRawWindowCapturer(
-+    const DesktopCaptureOptions& options) {
-+  std::unique_ptr<WindowCapturerPipeWire> 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 <memory>
-+
-+#include "webrtc/modules/desktop_capture/base_capturer_pipewire.h"
-+
-+namespace webrtc {
-+
-+class WindowCapturerPipeWire : public BaseCapturerPipeWire {
-+ public:
-+  WindowCapturerPipeWire();
-+  ~WindowCapturerPipeWire() override;
-+
-+  static std::unique_ptr<DesktopCapturer> 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 <algorithm>
- 
-+#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<SharedXDisplay> 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<uint32_t> 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<uint32_t> process_id(display(), window, process_atom);
-@@ -401,11 +350,11 @@ int WindowCapturerLinux::GetWindowProces
- }
- 
- // static
--std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
-+std::unique_ptr<DesktopCapturer> WindowCapturerX11::CreateRawWindowCapturer(
-     const DesktopCaptureOptions& options) {
-   if (!options.x_display())
-     return nullptr;
--  return std::unique_ptr<DesktopCapturer>(new WindowCapturerLinux(options));
-+  return std::unique_ptr<DesktopCapturer>(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 <X11/X.h>
-+#include <X11/Xlib.h>
-+#include <memory>
-+#include <string>
-+
-+#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<DesktopCapturer> 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<SharedXDisplay> 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/firefox-rhel6-hugepage.patch b/SOURCES/firefox-rhel6-hugepage.patch
new file mode 100644
index 0000000..4855721
--- /dev/null
+++ b/SOURCES/firefox-rhel6-hugepage.patch
@@ -0,0 +1,13 @@
+diff -up firefox-68.1.0/xpcom/threads/nsThread.cpp.old firefox-68.1.0/xpcom/threads/nsThread.cpp
+--- firefox-68.1.0/xpcom/threads/nsThread.cpp.old	2019-09-20 12:17:35.481661390 +0200
++++ firefox-68.1.0/xpcom/threads/nsThread.cpp	2019-09-20 12:19:14.269180516 +0200
+@@ -556,7 +556,8 @@ void nsThread::InitCommon() {
+     // kernel report them as separate regions, even when they are adjacent to
+     // heap memory. This allows us to accurately track the actual memory
+     // consumption of our allocated stacks.
+-    madvise(mStackBase, stackSize, MADV_NOHUGEPAGE);
++    // not supported on RHEL6
++    // madvise(mStackBase, stackSize, MADV_NOHUGEPAGE);
+ 
+     pthread_attr_destroy(&attr);
+ #elif defined(XP_WIN)
diff --git a/SOURCES/firefox-rhel6-nss-tls1.3.patch b/SOURCES/firefox-rhel6-nss-tls1.3.patch
new file mode 100644
index 0000000..2b6e8f7
--- /dev/null
+++ b/SOURCES/firefox-rhel6-nss-tls1.3.patch
@@ -0,0 +1,13 @@
+diff -up firefox-68.2.0/security/manager/ssl/nsNSSComponent.cpp.old firefox-68.2.0/security/manager/ssl/nsNSSComponent.cpp
+--- firefox-68.2.0/security/manager/ssl/nsNSSComponent.cpp.old	2019-10-24 14:20:21.227037984 +0200
++++ firefox-68.2.0/security/manager/ssl/nsNSSComponent.cpp	2019-10-24 14:45:52.769506967 +0200
+@@ -996,6 +996,9 @@ void nsNSSComponent::FillTLSVersionRange
+     return;
+   }
+ 
++  // Enable TLS 1.3 as our NSS supports it.
++  supported.max = 0x304;
++
+   // Clip the defaults by what NSS actually supports to enable
+   // working with a system NSS with different ranges.
+   rangeOut.min = std::max(rangeOut.min, supported.min);
diff --git a/SOURCES/gtk3-private-3.22.26-1-files.inc b/SOURCES/gtk3-private-3.22.26-1-files.inc
index cf89c66..8e1e31a 100644
--- a/SOURCES/gtk3-private-3.22.26-1-files.inc
+++ b/SOURCES/gtk3-private-3.22.26-1-files.inc
@@ -40,6 +40,7 @@
 %{gtk3_install_path}/%{_lib}/gio
 %ghost %attr(644, root, root) %{gtk3_install_path}/%{_lib}/gio/modules/giomodule.cache
 %{gtk3_install_path}/%{_lib}/gtk-3.0
+%ghost %attr(644, root, root) %{gtk3_install_path}/%{_lib}/gtk-3.0/3.0.0/immodules.cache
 
 %{gtk3_install_path}/libexec
 
diff --git a/SOURCES/mozilla-1196777.patch b/SOURCES/mozilla-1196777.patch
index c28cf94..7fa1595 100644
--- a/SOURCES/mozilla-1196777.patch
+++ b/SOURCES/mozilla-1196777.patch
@@ -1,7 +1,7 @@
-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 =
+diff -up firefox-68.0/widget/gtk/nsWindow.cpp.1196777 firefox-68.0/widget/gtk/nsWindow.cpp
+--- firefox-68.0/widget/gtk/nsWindow.cpp.1196777	2019-05-21 11:29:55.833376744 +0200
++++ firefox-68.0/widget/gtk/nsWindow.cpp	2019-05-21 12:15:35.446089316 +0200
+@@ -156,7 +156,8 @@ const gint kEvents =
  #if GTK_CHECK_VERSION(3, 4, 0)
      GDK_SMOOTH_SCROLL_MASK | GDK_TOUCH_MASK |
  #endif
@@ -9,5 +9,5 @@ diff -up firefox-60.5.0/widget/gtk/nsWindow.cpp.1196777 firefox-60.5.0/widget/gt
 +    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,
+ #if !GTK_CHECK_VERSION(3, 22, 0)
+ typedef enum {
diff --git a/SOURCES/mozilla-1353817.patch b/SOURCES/mozilla-1353817.patch
deleted file mode 100644
index dc8d8f8..0000000
--- a/SOURCES/mozilla-1353817.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 1cc652f5525f458b0b4ceb12af24bf5a4367db32 Mon Sep 17 00:00:00 2001
-From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
-Date: Tue, 23 May 2017 13:09:48 -0400
-Subject: [PATCH] Bug 1353817: Include SkNx_neon.h for ARM64 too
-
-This fixes build errors as arm_neon.h was missing along with some
-missing converters.
----
- gfx/skia/skia/src/core/SkNx.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/gfx/skia/skia/src/core/SkNx.h b/gfx/skia/skia/src/core/SkNx.h
-index 6bca856..b0427aa 100644
---- a/gfx/skia/skia/src/core/SkNx.h
-+++ b/gfx/skia/skia/src/core/SkNx.h
-@@ -299,7 +299,7 @@ typedef SkNx<4, uint32_t> Sk4u;
- // Include platform specific specializations if available.
- #if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
-     #include "../opts/SkNx_sse.h"
--#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON)
-+#elif !defined(SKNX_NO_SIMD) && (defined(SK_ARM_HAS_NEON) || defined(SK_CPU_ARM64))
-     #include "../opts/SkNx_neon.h"
- #else
- 
--- 
-2.9.4
-
diff --git a/SOURCES/mozilla-526293.patch b/SOURCES/mozilla-526293.patch
deleted file mode 100644
index a03796a..0000000
--- a/SOURCES/mozilla-526293.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-diff -up firefox-60.6.0/widget/gtk/nsFilePicker.cpp.old firefox-60.6.0/widget/gtk/nsFilePicker.cpp
---- firefox-60.6.0/widget/gtk/nsFilePicker.cpp.old	2019-03-27 10:29:47.918560620 +0100
-+++ firefox-60.6.0/widget/gtk/nsFilePicker.cpp	2019-03-27 10:30:08.384491717 +0100
-@@ -366,9 +366,7 @@ nsFilePicker::Open(nsIFilePickerShownCal
-   // If we have --enable-proxy-bypass-protection, then don't allow
-   // remote URLs to be used.
- #ifndef MOZ_PROXY_BYPASS_PROTECTION
--  if (mAllowURLs) {
--    gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(file_chooser), FALSE);
--  }
-+  gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(file_chooser), FALSE);
- #endif
- 
-   if (action == GTK_FILE_CHOOSER_ACTION_OPEN ||
diff --git a/SOURCES/no-rust-lto.patch b/SOURCES/no-rust-lto.patch
new file mode 100644
index 0000000..7d8ae5d
--- /dev/null
+++ b/SOURCES/no-rust-lto.patch
@@ -0,0 +1,12 @@
+diff -up firefox-68.0/config/makefiles/rust.mk.old firefox-68.0/config/makefiles/rust.mk
+--- firefox-68.0/config/makefiles/rust.mk.old	2019-06-05 10:33:34.290128660 +0200
++++ firefox-68.0/config/makefiles/rust.mk	2019-06-05 10:33:59.835052814 +0200
+@@ -47,7 +47,7 @@ cargo_rustc_flags = $(CARGO_RUSTCFLAGS)
+ ifndef DEVELOPER_OPTIONS
+ ifndef MOZ_DEBUG_RUST
+ # Enable link-time optimization for release builds.
+-cargo_rustc_flags += -C lto
++#cargo_rustc_flags += -C lto
+ endif
+ endif
+ 
diff --git a/SOURCES/node-stdout-nonblocking-wrapper b/SOURCES/node-stdout-nonblocking-wrapper
new file mode 100755
index 0000000..e36d134
--- /dev/null
+++ b/SOURCES/node-stdout-nonblocking-wrapper
@@ -0,0 +1,3 @@
+#!/bin/sh
+#exec /usr/bin/node "$@" 2>&1 | cat -
+exec $MOZ_NODEJS "$@" 2>&1 | cat -
diff --git a/SOURCES/nss-build-mozilla-1564499.patch b/SOURCES/nss-build-mozilla-1564499.patch
new file mode 100644
index 0000000..9d5bb5c
--- /dev/null
+++ b/SOURCES/nss-build-mozilla-1564499.patch
@@ -0,0 +1,12 @@
+diff -up firefox-68.0/security/nss/lib/freebl/mpi/mpcpucache.c.old firefox-68.0/security/nss/lib/freebl/mpi/mpcpucache.c
+--- firefox-68.0/security/nss/lib/freebl/mpi/mpcpucache.c.old	2019-07-26 07:09:02.383303420 +0200
++++ firefox-68.0/security/nss/lib/freebl/mpi/mpcpucache.c	2019-07-26 07:09:27.228193798 +0200
+@@ -727,7 +727,7 @@ static inline void
+ dcbzl(char *array)
+ {
+     register char *a asm("r2") = array;
+-    __asm__ __volatile__("dcbzl %0,r0"
++    __asm__ __volatile__("dcbzl %0,0"
+                          : "=r"(a)
+                          : "0"(a));
+ }
diff --git a/SOURCES/python-2.7-gcc8-fix.patch b/SOURCES/python-2.7-gcc8-fix.patch
new file mode 100644
index 0000000..d4da520
--- /dev/null
+++ b/SOURCES/python-2.7-gcc8-fix.patch
@@ -0,0 +1,57 @@
+commit 0b91f8a668201fc58fa732b8acc496caedfdbae0
+Author: Florian Weimer <fw@deneb.enyo.de>
+Date:   Sun Apr 29 12:18:33 2018 -0700
+
+    Indicate that _PyGC_Head is only 8-byte aligned. (closes bpo-33374)
+
+    By spec, the "long double" in _PyGC_Head requires the union to always be 16-byte
+    aligned. However, obmalloc only yields 8-byte alignment. Compilers including GCC
+    8 are starting to use alignment information to do store-merging. So, the "long
+    double" needs to be changed to a simple "double" as was long ago done in Python
+    3 by e348c8d154cf6342c79d627ebfe89dfe9de23817. For 2.7, we need to add some
+    dummy padding to make sure _PyGC_Head stays the same size.
+
+diff --git a/Include/objimpl.h b/Include/objimpl.h
+index 5f28683329..cbf6bc3f87 100644
+--- Python-2.7.13/Include/objimpl.h
++++ Python-2.7.13/Include/objimpl.h
+@@ -248,6 +248,20 @@ PyAPI_FUNC(PyVarObject *) _PyObject_GC_Resize(PyVarObject *, Py_ssize_t);
+ /* for source compatibility with 2.2 */
+ #define _PyObject_GC_Del PyObject_GC_Del
+
++/*
++ * Former over-aligned definition of PyGC_Head, used to compute the size of the
++ * padding for the new version below.
++ */
++union _gc_head;
++union _gc_head_old {
++    struct {
++        union _gc_head_old *gc_next;
++        union _gc_head_old *gc_prev;
++        Py_ssize_t gc_refs;
++    } gc;
++    long double dummy;
++};
++
+ /* GC information is stored BEFORE the object structure. */
+ typedef union _gc_head {
+     struct {
+@@ -255,7 +269,8 @@ typedef union _gc_head {
+         union _gc_head *gc_prev;
+         Py_ssize_t gc_refs;
+     } gc;
+-    long double dummy;  /* force worst-case alignment */
++    double dummy; /* Force at least 8-byte alignment. */
++    char dummy_padding[sizeof(union _gc_head_old)];
+ } PyGC_Head;
+
+ extern PyGC_Head *_PyGC_generation0;
+diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-04-29-12-07-00.bpo-33374.-xegL6.rst b/Misc/NEWS.d/next/Core and Builtins/2018-04-29-12-07-00.bpo-33374.-xegL6.rst
+new file mode 100644
+index 0000000000..9ec1a605c8
+--- /dev/null
++++ Python-2.7.13/Misc/NEWS.d/next/Core and Builtins/2018-04-29-12-07-00.bpo-33374.-xegL6.rst
+@@ -0,0 +1,3 @@
++Tweak the definition of PyGC_Head, so compilers do not believe it is always
++16-byte aligned on x86. This prevents crashes with more aggressive
++optimizations present in GCC 8.
diff --git a/SOURCES/python-2.7.patch b/SOURCES/python-2.7.patch
new file mode 100644
index 0000000..cad1c67
--- /dev/null
+++ b/SOURCES/python-2.7.patch
@@ -0,0 +1,17 @@
+diff -up Python-2.7.13/configure.build Python-2.7.13/configure
+--- Python-2.7.13/configure.build	2019-06-04 13:32:12.772134075 +0200
++++ Python-2.7.13/configure	2019-06-04 13:32:26.140144601 +0200
+@@ -6018,11 +6018,11 @@ then
+ 		# debug builds.
+ 		OPT="-g -O0 -Wall $STRICT_PROTO"
+ 	    else
+-		OPT="-g $WRAP -O3 -Wall $STRICT_PROTO"
++		OPT="-g $WRAP -O2 -Wall $STRICT_PROTO"
+ 	    fi
+ 	    ;;
+ 	*)
+-	    OPT="-O3 -Wall $STRICT_PROTO"
++	    OPT="-O2 -Wall $STRICT_PROTO"
+ 	    ;;
+ 	esac
+ 	case $ac_sys_system in
diff --git a/SOURCES/python-encode.patch b/SOURCES/python-encode.patch
new file mode 100644
index 0000000..2f3bad9
--- /dev/null
+++ b/SOURCES/python-encode.patch
@@ -0,0 +1,12 @@
+diff -up firefox-68.0/python/mozbuild/mozbuild/controller/building.py.old firefox-68.0/python/mozbuild/mozbuild/controller/building.py
+--- firefox-68.0/python/mozbuild/mozbuild/controller/building.py.old	2019-05-29 10:46:55.403262995 +0200
++++ firefox-68.0/python/mozbuild/mozbuild/controller/building.py	2019-05-29 10:47:42.691176970 +0200
+@@ -571,7 +571,7 @@ class TerminalLoggingHandler(logging.Han
+             if self.footer:
+                 self.footer.clear()
+ 
+-            self.fh.write(msg)
++            self.fh.write(msg.encode("utf-8"))
+             self.fh.write('\n')
+ 
+             if self.footer:
diff --git a/SOURCES/python-missing-utimensat.patch b/SOURCES/python-missing-utimensat.patch
new file mode 100644
index 0000000..d19ecab
--- /dev/null
+++ b/SOURCES/python-missing-utimensat.patch
@@ -0,0 +1,12 @@
+diff -up python3/Python-3.6.8/configure.old python3/Python-3.6.8/configure
+--- Python-3.6.8/configure.old	2019-10-01 12:56:35.074551835 +0200
++++ Python-3.6.8/configure	2019-10-01 12:56:44.240517798 +0200
+@@ -11438,7 +11438,7 @@ for ac_func in alarm accept4 setitimer g
+  sigaction sigaltstack siginterrupt sigpending sigrelse \
+  sigtimedwait sigwait sigwaitinfo snprintf strftime strlcpy symlinkat sync \
+  sysconf tcgetpgrp tcsetpgrp tempnam timegm times tmpfile tmpnam tmpnam_r \
+- truncate uname unlinkat unsetenv utimensat utimes waitid waitpid wait3 wait4 \
++ truncate uname unlinkat unsetenv utimes waitid waitpid wait3 wait4 \
+  wcscoll wcsftime wcsxfrm wmemcmp writev _getpty
+ do :
+   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
diff --git a/SOURCES/rhbz-1354671.patch b/SOURCES/rhbz-1354671.patch
deleted file mode 100644
index 7660f14..0000000
--- a/SOURCES/rhbz-1354671.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-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* result = mFrameArena.AllocateByFrameID(aID, aSize);
-     RecordAlloc(result);
-     return result;
diff --git a/SOURCES/rust-network-check.patch b/SOURCES/rust-network-check.patch
new file mode 100644
index 0000000..d18f2fe
--- /dev/null
+++ b/SOURCES/rust-network-check.patch
@@ -0,0 +1,105 @@
+diff -up firefox-68.0/config/makefiles/rust.mk.rust-network-check firefox-68.0/config/makefiles/rust.mk
+--- firefox-68.0/config/makefiles/rust.mk.rust-network-check	2019-06-06 10:29:18.984737603 +0200
++++ firefox-68.0/config/makefiles/rust.mk	2019-06-06 11:39:51.581028835 +0200
+@@ -127,7 +127,7 @@ export RUST_BACKTRACE=full
+ export MOZ_TOPOBJDIR=$(topobjdir)
+ 
+ target_rust_ltoable := force-cargo-library-build
+-target_rust_nonltoable := force-cargo-test-run force-cargo-library-check $(foreach b,build check,force-cargo-program-$(b))
++target_rust_nonltoable := force-cargo-test-run $(foreach b,build check,force-cargo-program-$(b))
+ 
+ $(target_rust_ltoable): RUSTFLAGS:=$(rustflags_override) $(RUSTFLAGS) $(if $(MOZ_LTO_RUST),-Clinker-plugin-lto)
+ $(target_rust_nonltoable): RUSTFLAGS:=$(rustflags_override) $(RUSTFLAGS)
+@@ -238,19 +238,9 @@ force-cargo-library-build:
+ 	$(call CARGO_BUILD) --lib $(cargo_target_flag) $(rust_features_flag) -- $(cargo_rustc_flags)
+ 
+ $(RUST_LIBRARY_FILE): force-cargo-library-build
+-# When we are building in --enable-release mode; we add an additional check to confirm
+-# that we are not importing any networking-related functions in rust code. This reduces
+-# the chance of proxy bypasses originating from rust code.
+-ifndef DEVELOPER_OPTIONS
+-ifndef MOZ_DEBUG_RUST
+-ifeq ($(OS_ARCH), Linux)
+-	$(call py_action,check_binary,--target --networking $@)
+-endif
+-endif
+-endif
+ 
+ force-cargo-library-check:
+-	$(call CARGO_CHECK) --lib $(cargo_target_flag) $(rust_features_flag)
++	@true
+ else
+ force-cargo-library-check:
+ 	@true
+diff -up firefox-68.0/python/mozbuild/mozbuild/action/check_binary.py.rust-network-check firefox-68.0/python/mozbuild/mozbuild/action/check_binary.py
+--- firefox-68.0/python/mozbuild/mozbuild/action/check_binary.py.rust-network-check	2019-05-20 18:17:57.000000000 +0200
++++ firefox-68.0/python/mozbuild/mozbuild/action/check_binary.py	2019-06-06 10:29:18.986737599 +0200
+@@ -250,43 +250,6 @@ def check_mozglue_order(target, binary):
+         raise RuntimeError('Could not parse readelf output?')
+ 
+ 
+-def check_networking(binary):
+-    retcode = 0
+-    networking_functions = set([
+-        # socketpair is not concerning; it is restricted to AF_UNIX
+-        "socket", "connect", "accept", "bind", "listen",
+-        "getsockname", "getsockopt", "setsockopt",
+-        "recv", "recvfrom",
+-        "send", "sendto",
+-        # We would be concerned by recvmsg and sendmsg; but we believe
+-        # they are okay as documented in 1376621#c23
+-        "gethostbyname", "gethostbyaddr", "gethostent", "sethostent", "endhostent",
+-        "gethostent_r", "gethostbyname2", "gethostbyaddr_r", "gethostbyname_r",
+-        "gethostbyname2_r",
+-        "getaddrinfo", "getservent", "getservbyname", "getservbyport", "setservent",
+-        "getprotoent", "getprotobyname", "getprotobynumber", "setprotoent",
+-        "endprotoent"])
+-    bad_occurences_names = set()
+-
+-    try:
+-        for sym in at_least_one(iter_symbols(binary)):
+-            if sym['addr'] == 0 and sym['name'] in networking_functions:
+-                bad_occurences_names.add(sym['name'])
+-    except Empty:
+-        raise RuntimeError('Could not parse llvm-objdump output?')
+-
+-    basename = os.path.basename(binary)
+-    if bad_occurences_names:
+-        s = 'TEST-UNEXPECTED-FAIL | check_networking | {} | Identified {} ' + \
+-            'networking function(s) being imported in the rust static library ({})'
+-        print(s.format(basename, len(bad_occurences_names),
+-            ",".join(sorted(bad_occurences_names))),
+-            file=sys.stderr)
+-        retcode = 1
+-    elif buildconfig.substs.get('MOZ_AUTOMATION'):
+-        print('TEST-PASS | check_networking | {}'.format(basename))
+-    return retcode
+-
+ def checks(target, binary):
+     # The clang-plugin is built as target but is really a host binary.
+     # Cheat and pretend we were passed the right argument.
+@@ -330,8 +293,6 @@ def main(args):
+                         help='Perform checks for a host binary')
+     parser.add_argument('--target', action='store_true',
+                         help='Perform checks for a target binary')
+-    parser.add_argument('--networking', action='store_true',
+-                        help='Perform checks for networking functions')
+ 
+     parser.add_argument('binary', metavar='PATH',
+                         help='Location of the binary to check')
+@@ -343,14 +304,7 @@ def main(args):
+               file=sys.stderr)
+         return 1
+ 
+-    if options.networking and options.host:
+-        print('--networking is only valid with --target',
+-               file=sys.stderr)
+-        return 1
+-
+-    if options.networking:
+-        return check_networking(options.binary)
+-    elif options.host:
++    if options.host:
+         return checks(HOST, options.binary)
+     elif options.target:
+         return checks(TARGET, options.binary)
diff --git a/SPECS/firefox.spec b/SPECS/firefox.spec
index 25b7f82..0f8a222 100644
--- a/SPECS/firefox.spec
+++ b/SPECS/firefox.spec
@@ -2,38 +2,52 @@
 %global disable_toolsets  0
 
 # Use system nspr/nss? FIXME
+%if 0%{?rhel} == 8
 %global system_nss        1
+%endif
+%if 0%{?rhel} == 7
+%global system_nss        1
+%endif
+%if 0%{?rhel} == 6
+%global system_nss        1
+%endif
 %define use_bundled_ffi   0
-%define use_bundled_python 1
+%if 0%{?rhel} == 8
+%define use_bundled_python_2 1
+%define use_bundled_python_3 0
+%else
+%define use_bundled_python_2 1
+%define use_bundled_python_3 1
+%endif
 %define bundle_gnome_extension 0
 
 # Don't use system hunspell for now
 %global system_hunspell   0
 %global system_sqlite     0
+%if 0%{?rhel} == 8
+%global use_llvmts        0
+%else
 %global use_llvmts        1
+%endif
 
 %if 0%{?rhel} > 6
 %global system_ffi        1
 %else
 %global system_ffi        0
-%global use_llvmts        0
 %endif
 %if 0%{?rhel} < 8
 %global use_dts           1
 %endif
 
-%if 0%{?rhel} == 7
-%define use_bundled_python 0
-%endif
-
-%if 0%{?rhel} < 8
 %global use_rustts        1
+%global dts_version       8
+%if 0%{?rhel} == 6
+%global dts_version       8
 %endif
-%global dts_version       7
-%global rst_version       7
-%global llvm_version      7
+%global rust_version         1.31
+%global rust_toolset_version 1.35
+%global llvm_version      7.0
 %if 0%{?rhel} == 8
-%global rst_version       1.26
 %global llvm_version      6.0
 %endif
 
@@ -83,12 +97,12 @@
 %endif
 
 %if %{?system_nss}
-%global nspr_version 4.19.0
+%global nspr_version 4.21
 # NSS/NSPR quite often ends in build override, so as requirement the version
 # we're building against could bring us some broken dependencies from time to time.
 #%global nspr_build_version %(pkg-config --silence-errors --modversion nspr 2>/dev/null || echo 65536)
 %global nspr_build_version %{nspr_version}
-%global nss_version 3.36.0
+%global nss_version 3.44
 #%global nss_build_version %(pkg-config --silence-errors --modversion nss 2>/dev/null || echo 65536)
 %global nss_build_version %{nss_version}
 %endif
@@ -99,11 +113,20 @@
 %global sqlite_build_version %(pkg-config --silence-errors --modversion sqlite3 2>/dev/null || echo 65536)
 %endif
 
-%define bundled_python_version 2.7.13
+%define bundled_python_version_2 2.7.13
+%define bundled_python_version_3 3.6.8
 %define use_bundled_yasm        1
+%define use_bundled_openssl     0
+%define use_bundled_nodejs      0
+%if 0%{?rhel} < 8
+%define use_bundled_nodejs      1
+%if 0%{?rhel} == 6
+%define use_bundled_openssl     1
+%endif
+%endif
 
 # GTK3 bundling
-%define avoid_bundled_rebuild 0
+%define avoid_bundled_rebuild   0
 %if 0%{?rhel} == 6
 %define bundle_gtk3             1
 # In-tree libffi is able to build on following platforms, we have to bundle it for the rest
@@ -128,6 +151,7 @@
 %global langpackdir   %{mozappdir}/distribution/extensions
 %global tarballdir    %{name}-%{version}
 %global pre_version   esr
+#global pre_tag       alpha
 
 %global official_branding       1
 %global build_langpacks         1
@@ -141,7 +165,7 @@
 
 Summary:        Mozilla Firefox Web browser
 Name:           firefox
-Version:        60.7.0
+Version:        68.3.0
 Release:        1%{?pre_tag}%{?dist}
 URL:            https://www.mozilla.org/firefox/
 License:        MPLv1.1 or GPLv2+ or LGPLv2+
@@ -154,8 +178,9 @@ 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}-20190515.tar.xz
+Source1:        firefox-langpacks-%{version}%{?pre_version}-20191127.tar.xz
 %endif
+Source2:        cbindgen-vendor.tar.xz
 Source10:       firefox-mozconfig
 Source12:       firefox-redhat-default-prefs.js
 Source20:       firefox.desktop
@@ -165,6 +190,7 @@ Source24:       mozilla-api-key
 Source25:       firefox-symbolic.svg
 Source26:       distribution.ini
 Source27:       google-api-key
+Source28:       node-stdout-nonblocking-wrapper
 
 Source200:      gtk3-private-%{gtk3_nvr}.el6.src.rpm
 Source201:      gtk3-private-%{gtk3_nvr}-post.inc
@@ -175,14 +201,31 @@ Source205:      gtk3-private-%{gtk3_nvr}-setup-flags-env.inc
 Source206:      gtk3-private-%{gtk3_nvr}-requires-provides-filter.inc
 Source301:      yasm-1.2.0-3.el5.src.rpm
 Source303:      libffi-3.0.13-18.el7_3.src.rpm
+Source304:      nodejs-8.11.4-1.3.fc27.src.rpm
+Source305:      openssl-1.0.2k-19.6.bundle.el7_7.src.rpm
 
-#Python 2.7
-Source100:      https://www.python.org/ftp/python/%{bundled_python_version}/Python-%{bundled_python_version}.tar.xz
+#Python
+%if 0%{?use_bundled_python_2}
+Source100:      https://www.python.org/ftp/python/%{bundled_python_version_2}/Python-%{bundled_python_version_2}.tar.xz
+%endif
+%if 0%{?use_bundled_python_3}
+Source101:      https://www.python.org/ftp/python/%{bundled_python_version_3}/Python-%{bundled_python_version_3}.tar.xz
+%endif
 # Build patches
+Patch1000:      python-2.7.patch
+Patch1001:      build-ppc64le-inline.patch
+Patch1002:      python-2.7-gcc8-fix.patch
+Patch1003:      python-missing-utimensat.patch
+# workaround for https://bugzilla.redhat.com/show_bug.cgi?id=1699374
+Patch1:         no-rust-lto.patch
+Patch2:         rust-network-check.patch
 Patch3:         mozilla-build-arm.patch
 Patch4:         build-mozconfig-fix.patch
 Patch5:         build-gdk-version.patch
 Patch6:         build-nss-version.patch
+Patch7:         firefox-debugedits-error.patch
+Patch8:         firefox-dont-check-binary.patch
+Patch9:         nss-build-mozilla-1564499.patch
 Patch26:        build-icu-big-endian.patch
 # Also fixes s390x: https://bugzilla.mozilla.org/show_bug.cgi?id=1376268
 Patch29:        build-big-endian.patch
@@ -192,7 +235,6 @@ 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
 Patch45:        build-disable-elfhack.patch
 
 # Fedora/RHEL specific patches
@@ -201,17 +243,21 @@ Patch219:        rhbz-1173156.patch
 Patch224:        mozilla-1170092.patch
 Patch225:        mozilla-1005640-accept-lang.patch
 #ARM run-time patch
-Patch226:        rhbz-1354671.patch
+#Patch226:        rhbz-1354671.patch
 Patch230:        rhbz-1503632-nss.patch
 Patch231:        firefox-pipewire.patch
-Patch232:        mozilla-526293.patch
+Patch232:        firefox-rhel6-hugepage.patch
+Patch233:        firefox-rhel6-nss-tls1.3.patch
 
 # Upstream patches
 Patch402:        mozilla-1196777.patch
 Patch406:        mozilla-256180.patch
-Patch413:        mozilla-1353817.patch
+#Patch413:        mozilla-1353817.patch
 Patch415:        mozilla-1436242.patch
 
+#Patch500:        debug.patch
+Patch501:        python-encode.patch
+
 # Debian patches
 
 %if %{?system_nss}
@@ -267,16 +313,21 @@ BuildRequires:  llvm-toolset-%{llvm_version}-llvm-devel
 %endif
 %endif
 
+BuildRequires:  scl-utils
+
 %if 0%{?rhel} == 8
 BuildRequires:  cargo
-BuildRequires:  rust >= 1.24
+BuildRequires:  rust >= %{rust_version}
 BuildRequires:  llvm >= %{llvm_version}
 BuildRequires:  llvm-devel >= %{llvm_version}
 BuildRequires:  clang >= %{llvm_version}
+BuildRequires:  clang-devel >= %{llvm_version}
+BuildRequires:  rustfmt >= %{rust_version}
+BuildRequires:  python3
+BuildRequires:  nodejs >= 8.11
 %else
 %if 0%{?use_rustts}
-BuildRequires:  rust-toolset-%{rst_version}-cargo
-BuildRequires:  rust-toolset-%{rst_version}-rust >= 1.24
+BuildRequires:  rust-toolset-%{rust_toolset_version}
 %endif
 %if 0%{?use_llvmts}
 BuildRequires:  llvm-toolset-%{llvm_version}
@@ -284,7 +335,7 @@ BuildRequires:  llvm-toolset-%{llvm_version}-llvm-devel
 %endif
 %endif
 
-%if 0%{?use_bundled_python}
+%if 0%{?use_bundled_python_2}
 #%if 0%{?rhel} == 6
 # Needed for Python in RHEL6
 BuildRequires:  openssl-devel
@@ -347,10 +398,6 @@ Requires:       nspr >= %{nspr_build_version}
 Requires:       nss >= %{nss_build_version}
 %endif
 
-%if 0%{?rhel} < 8
-BuildRequires:  python2-devel
-%endif
-
 BuildRequires:  desktop-file-utils
 BuildRequires:  system-bookmarks
 Requires:       redhat-indexhtml
@@ -423,8 +470,8 @@ Requires:       hicolor-icon-theme
 Requires:       mozilla-filesystem
 
 %description -n firefox-gnome-shell-extension
-Browser extension for Firefox and native host messaging connector that provides 
-integration with GNOME Shell and the corresponding extensions repository 
+Browser extension for Firefox and native host messaging connector that provides
+integration with GNOME Shell and the corresponding extensions repository
 https://extensions.gnome.org.
 
 %files -n firefox-gnome-shell-extension
@@ -432,57 +479,74 @@ https://extensions.gnome.org.
 %endif # bundle_gnome_extension
 
 %prep
-%setup -q -T -c -n python -a 100
+%if 0%{?use_bundled_python_2}
+%setup -q -T -c -n python2 -a 100
+%patch1000 -p0 -b .build
+%patch1002 -p0 -b .gcc8
+%endif
+%if 0%{?use_bundled_python_3}
+%setup -q -T -c -n python3 -a 101
+%if 0%{?rhel} == 6
+%patch1003 -p0 -b .missing-utimensat.patch
+%endif
+%endif
 %setup -q -n %{tarballdir}
 # Build patches, can't change backup suffix from default because during build
 # there is a compare of config and js/config directories and .orig suffix is
 # ignored during this compare.
-
-%patch29 -p1 -b .big-endian
-%patch37 -p1 -b .jit-atomic-lucky
-%patch40 -p1 -b .aarch64-skia
+%patch1 -p1 -b .no-rust-lto
+%patch2 -p1 -b .rust-network-check
+%patch7 -p1 -b .debugedits-error
+%ifarch %{ix86} %{arm} ppc
+# binary check fails OOM on 32bit arches
+%patch8 -p1 -b .dont-check-binary
+%endif
+%patch9 -p1 -b .nss-build-mozilla-1564499
+
+#%patch29 -p1 -b .big-endian
+#%patch37 -p1 -b .jit-atomic-lucky
+#%patch40 -p1 -b .aarch64-skia
 %if %{?debug_build}
 %patch41 -p1 -b .build-debug-qcms
 %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
+#%patch43 -p1 -b .jemalloc-ppc
+#%if 0%{?rhel} == 8
+#%patch45 -p1 -b .disable-elfhack
 #%endif
-%if 0%{?rhel} == 8
-%patch45 -p1 -b .disable-elfhack
-%endif
 
-%patch3  -p1 -b .arm
+#%patch3  -p1 -b .arm
 %patch4  -p1 -b .build-mozconfig-fix
-%patch5  -p1 -b .gdk-version
+#%patch5  -p1 -b .gdk-version
 %patch6  -p1 -b .nss-version
 
 # Fedora patches
 %patch215 -p1 -b .addons
 %patch219 -p1 -b .rhbz-1173156
-%patch224 -p1 -b .1170092
-%patch225 -p1 -b .1005640-accept-lang
+#%patch224 -p1 -b .1170092
+#%patch225 -p1 -b .1005640-accept-lang
 %if 0%{?rhel} == 8
 %patch231 -p1 -b .pipewire
 %endif
-%patch232 -p1 -b .mozilla-526293
+%if 0%{?rhel} == 6
+%patch232 -p1 -b .hugepage
+%patch233 -p1 -b .rhel6-nss-tls1.3
+%endif
 
 # This ensures no migration of certdb to sqlite on the RHEL6 and RHEL7.
 # This needs to stay for the future releases
 %if 0%{?rhel} < 8
-%patch230 -p1 -b .1503632-nss
+#%patch230 -p1 -b .1503632-nss
 %endif
 
 #ARM run-time patch
-%ifarch aarch64
-%patch226 -p1 -b .1354671
-%endif
+#%ifarch aarch64
+#%patch226 -p1 -b .1354671
+#%endif
 
 %patch402 -p1 -b .1196777
-%patch406 -p1 -b .256180
-%patch413 -p1 -b .1353817
-%patch415 -p1 -b .1436242
+#%patch406 -p1 -b .256180
+#%patch413 -p1 -b .1353817
+#%patch415 -p1 -b .1436242
 
 
 # Patch for big endian platforms only
@@ -490,6 +554,10 @@ https://extensions.gnome.org.
 %patch26 -p1 -b .icu
 %endif
 
+#%patch500 -p1 -b .debug
+%patch501 -p1 -b .python-encode
+%patch1001 -p1 -b .ppc64le-inline
+
 %{__rm} -f .mozconfig
 %{__cp} %{SOURCE10} .mozconfig
 %if %{official_branding}
@@ -525,14 +593,15 @@ echo "ac_add_options --enable-system-ffi" >> .mozconfig
 echo "ac_add_options --enable-system-ffi" >> .mozconfig
 %endif
 
-%ifarch %{arm}
+%ifarch %{arm} %{ix86} x86_64
 echo "ac_add_options --disable-elf-hack" >> .mozconfig
 %endif
 
 %if %{?system_hunspell}
 echo "ac_add_options --enable-system-hunspell" >> .mozconfig
 %else
-echo "ac_add_options --disable-system-hunspell" >> .mozconfig
+# not available?
+#echo "ac_add_options --disable-system-hunspell" >> .mozconfig
 %endif
 
 %if %{?debug_build}
@@ -596,12 +665,7 @@ echo "ac_add_options --without-system-icu" >> .mozconfig
 echo "ac_add_options --disable-ion" >> .mozconfig
 %endif
 
-%ifarch %{ix86}
-echo "ac_add_options --disable-stylo" >> .mozconfig
-%endif
-%if 0%{?rhel} == 6
-echo "ac_add_options --disable-stylo" >> .mozconfig
-%endif
+echo 'export NODEJS="%{_buildrootdir}/bin/node-stdout-nonblocking-wrapper"' >> .mozconfig
 
 # Remove executable bit to make brp-mangle-shebangs happy.
 chmod -x third_party/rust/itertools/src/lib.rs
@@ -609,8 +673,12 @@ chmod -x third_party/rust/itertools/src/lib.rs
 #---------------------------------------------------------------------
 
 %build
+set -e
+# Hack for missing shell when building in brew on RHEL6
+%if 0%{?rhel} == 6
+export SHELL=/bin/sh
+%endif
 
-#GTK3 >>
 %if ! 0%{?avoid_bundled_rebuild}
     rm -rf %{_buildrootdir}/*
 %endif
@@ -640,7 +708,7 @@ function build_bundled_package() {
   PACKAGE_RPM=$1
   PACKAGE_FILES=$2
   PACKAGE_SOURCE=$3
-  PACKAGE_DIR="%{_topdir}/RPMS"
+  export PACKAGE_DIR="%{_topdir}/RPMS"
 
   PACKAGE_ALREADY_BUILD=0
   %if %{?avoid_bundled_rebuild}
@@ -662,20 +730,27 @@ function build_bundled_package() {
     %ifarch i386 i686
     ARCH_STR="i?86"
     %endif
-    PACKAGE_DIR="$PACKAGE_DIR/$ARCH_STR"
+    export PACKAGE_DIR="$PACKAGE_DIR/$ARCH_STR"
   fi
   pushd $PACKAGE_DIR
+
   echo "Installing $PACKAGE_DIR/$PACKAGE_RPM"; echo "==============================="
-  rpm2cpio $PACKAGE_DIR/$PACKAGE_RPM | cpio -iduv
+  PACKAGE_LIST=$(echo $PACKAGE_DIR/$PACKAGE_RPM | tr " " "\n")
+  for PACKAGE in $PACKAGE_LIST
+  do
+      rpm2cpio $PACKAGE | cpio -iduv
+  done
+
+  PATH=$PACKAGE_DIR/usr/bin:$PATH
+  export PATH
+  LD_LIBRARY_PATH=$PACKAGE_DIR/usr/%{_lib}:$LD_LIBRARY_PATH
+  export LD_LIBRARY_PATH
+
   # Clean rpms to avoid including them to package
   %if ! 0%{?avoid_bundled_rebuild}
     rm -f $PACKAGE_FILES
   %endif
 
-  PATH=$PACKAGE_DIR/usr/bin:$PATH
-  export PATH
-  LD_LIBRARY_PATH=$PACKAGE_DIR/usr/%{_lib}
-  export LD_LIBRARY_PATH
   popd
 }
 
@@ -685,13 +760,11 @@ function build_bundled_package() {
   build_bundled_package 'yasm-1*.rpm' 'yasm-*.rpm' '%{SOURCE301}'
 %endif
 
-
 %if 0%{?bundle_gtk3}
    %if ! 0%{?avoid_bundled_rebuild}
     rpm -ivh %{SOURCE200}
     rpmbuild --nodeps --define '_prefix %{gtk3_install_path}' -ba %{_specdir}/gtk3-private.spec
    %endif
-   rm -rf %{_buildrootdir}/*
    pushd %{_buildrootdir}
    install_rpms_to_current_dir gtk3-private-%{gtk3_nvr}*.rpm
    install_rpms_to_current_dir gtk3-private-devel-%{gtk3_nvr}*.rpm
@@ -699,18 +772,6 @@ function build_bundled_package() {
    popd
 %endif
 
-# If needed build the bundled python 2.7 and put it in the PATH
-%if 0%{?use_bundled_python}
-    pushd %{_builddir}/python/Python-%{bundled_python_version}
-    #if ! 0%{?avoid_bundled_rebuild}
-        # Build Python 2.7 and set environment
-        # Pydebug set optimization to level 0, -O3 crashes on gcc 8 ATM
-        ./configure --with-pydebug --prefix="%{_buildrootdir}" --exec-prefix="%{_buildrootdir}" --libdir="%{_buildrootdir}/lib"
-    #endif
-    make %{?_smp_mflags} install V=1
-    popd
-%endif
-
 %if 0%{?bundle_gtk3}
 # gtk3-private-3.22.26.el6-1-requires-provides-filter.inc
 %include_file %{SOURCE206}
@@ -726,17 +787,53 @@ function build_bundled_package() {
 %endif
 %filter_setup
 
-# GTK3 <<
+# If needed build the bundled python 2.7 and 3.6 and put it in the PATH
+%if 0%{?use_bundled_python_3}
+    pushd %{_builddir}/python3/Python-%{bundled_python_version_3}
+    ./configure --prefix="%{_buildrootdir}" --exec-prefix="%{_buildrootdir}" --libdir="%{_buildrootdir}/lib" --with-pydebug
+    make %{?_smp_mflags} install V=1 -j1
+    cp Tools/scripts/pathfix.py %{_buildrootdir}/bin
+    popd
+%endif
+%if 0%{?use_bundled_python_2}
+    pushd %{_builddir}/python2/Python-%{bundled_python_version_2}
+    ./configure --prefix="%{_buildrootdir}" --exec-prefix="%{_buildrootdir}" --libdir="%{_buildrootdir}/lib"
+    make %{?_smp_mflags} install V=1
+    popd
+%endif
 
-%if %{?system_sqlite}
-# Do not proceed with build if the sqlite require would be broken:
-# make sure the minimum requirement is non-empty, ...
-sqlite_version=$(expr "%{sqlite_version}" : '\([0-9]*\.\)[0-9]*\.') || exit 1
-# ... and that major number of the computed build-time version matches:
-case "%{sqlite_build_version}" in
-  "$sqlite_version"*) ;;
-  *) exit 1 ;;
-esac
+function replace_prefix() {
+  FILE_NAME=$1
+  PKG_CONFIG_PREFIX=$2
+
+  cat $FILE_NAME | tail -n +2 > tmp.txt
+  echo "$PKG_CONFIG_PREFIX" > $FILE_NAME
+  cat tmp.txt >> $FILE_NAME
+  rm -rf tmp.txt
+}
+
+# Build and install local openssl if needed
+# =========================================
+%if 0%{?use_bundled_openssl}
+  rpm -ivh %{SOURCE305}
+  rpmbuild --nodeps -ba %{_specdir}/openssl.spec
+  pushd %{_buildrootdir}
+  install_rpms_to_current_dir openssl-1.0.2k*.rpm
+  install_rpms_to_current_dir openssl-libs-1.0.2k*.rpm
+  install_rpms_to_current_dir openssl-devel-1.0.2k*.rpm
+  install_rpms_to_current_dir openssl-static-1.0.2k*.rpm
+  # openssl is installed to %{_buildrootdir}/usr/lib(64)/...
+  export PKG_CONFIG_PATH=%{_buildrootdir}/%{_libdir}/pkgconfig/:$PKG_CONFIG_PATH
+  replace_prefix %{_buildrootdir}/%{_libdir}/pkgconfig/libcrypto.pc prefix=%{_buildrootdir}/usr
+  replace_prefix %{_buildrootdir}/%{_libdir}/pkgconfig/libssl.pc prefix=%{_buildrootdir}/usr
+  replace_prefix %{_buildrootdir}/%{_libdir}/pkgconfig/openssl.pc prefix=%{_buildrootdir}/usr
+  cat  %{_buildrootdir}/%{_libdir}/pkgconfig/libcrypto.pc
+  cat  %{_buildrootdir}/%{_libdir}/pkgconfig/libssl.pc
+  cat  %{_buildrootdir}/%{_libdir}/pkgconfig/openssl.pc
+  pushd %{_rpmdir}
+  rm -f openssl-*.rpm
+  popd
+  popd
 %endif
 
 # We need to disable exit on error temporarily for the following scripts:
@@ -745,22 +842,59 @@ set +e
 source scl_source enable devtoolset-%{dts_version}
 %endif
 %if 0%{?use_rustts}
-source scl_source enable rust-toolset-%{rst_version}
+source scl_source enable rust-toolset-%{rust_toolset_version}
 %endif
 
-set -e
-# Hack for missing shell when building in brew on RHEL6
-%if 0%{?rhel} == 6
-export SHELL=/bin/sh
+# Build and install local node if needed
+# ======================================
+%if %{use_bundled_nodejs}
+  build_bundled_package 'nodejs-8*.rpm' 'nodejs-*.rpm' %{SOURCE304}
+  export MOZ_NODEJS=$PACKAGE_DIR/usr/bin/node
+%else
+  export MOZ_NODEJS=/usr/bin/node
+%endif
+
+mkdir -p my_rust_vendor
+cd my_rust_vendor
+%{__tar} xf %{SOURCE2}
+cd -
+mkdir -p .cargo
+cat > .cargo/config <<EOL
+[source.crates-io]
+replace-with = "vendored-sources"
+
+[source.vendored-sources]
+directory = "`pwd`/my_rust_vendor"
+EOL
+
+export CARGO_HOME=.cargo
+cargo install cbindgen
+export PATH=`pwd`/.cargo/bin:$PATH
+export CBINDGEN=`pwd`/.cargo/bin/cbindgen
+
+
+%if %{?system_sqlite}
+# Do not proceed with build if the sqlite require would be broken:
+# make sure the minimum requirement is non-empty, ...
+sqlite_version=$(expr "%{sqlite_version}" : '\([0-9]*\.\)[0-9]*\.') || exit 1
+# ... and that major number of the computed build-time version matches:
+case "%{sqlite_build_version}" in
+  "$sqlite_version"*) ;;
+  *) exit 1 ;;
+esac
 %endif
 
-echo "Generate big endian version of config/external/icu/data/icud58l.dat"
 %if 0%{?big_endian}
-  ./mach python intl/icu_sources_data.py .
-  ls -l config/external/icu/data
-  rm -f config/external/icu/data/icudt*l.dat
+echo "Generate big endian version of config/external/icu/data/icud64l.dat"
+# ./mach python intl/icu_sources_data.py .
+# rm -f config/external/icu/data/icudt*l.dat
+ mv config/external/icu/data/icudt64l.dat config/external/icu/data/icudt64b.dat
+ ls -l config/external/icu/data
 %endif
 
+mkdir %{_buildrootdir}/bin || :
+cp %{SOURCE28} %{_buildrootdir}/bin || :
+
 # Update the various config.guess to upstream release for aarch64 support
 find ./ -name config.guess -exec cp /usr/lib/rpm/config.guess {} ';'
 
@@ -808,10 +942,16 @@ export LDFLAGS=$MOZ_LINK_FLAGS
 
 export PREFIX='%{_prefix}'
 export LIBDIR='%{_libdir}'
+export CC=gcc
+export CXX=g++
 
 MOZ_SMP_FLAGS=-j1
-# On x86 architectures, Mozilla can build up to 4 jobs at once in parallel,
-# however builds tend to fail on other arches when building in parallel.
+# More than two build tasks can lead to OOM gcc crash.
+%if 0%{?rhel} < 8
+[ -z "$RPM_BUILD_NCPUS" ] && \
+     RPM_BUILD_NCPUS="`/usr/bin/getconf _NPROCESSORS_ONLN`"
+[ "$RPM_BUILD_NCPUS" -ge 2 ] && MOZ_SMP_FLAGS=-j2
+%else
 %ifarch %{ix86} x86_64 ppc ppc64 ppc64le aarch64
 [ -z "$RPM_BUILD_NCPUS" ] && \
      RPM_BUILD_NCPUS="`/usr/bin/getconf _NPROCESSORS_ONLN`"
@@ -819,19 +959,16 @@ MOZ_SMP_FLAGS=-j1
 [ "$RPM_BUILD_NCPUS" -ge 4 ] && MOZ_SMP_FLAGS=-j4
 [ "$RPM_BUILD_NCPUS" -ge 8 ] && MOZ_SMP_FLAGS=-j8
 %endif
+%endif
 
 %if 0%{?bundle_gtk3}
 # gtk3-private-setup-flags-env.inc
 %include_file %{SOURCE205}
 %endif
 
-#make -f client.mk build STRIP="/bin/true" MOZ_MAKE_FLAGS="$MOZ_SMP_FLAGS" MOZ_SERVICES_SYNC="1"
 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
@@ -1027,7 +1164,6 @@ echo "%%lang($language_short) %{langpackdir}/langpack-$language_short@firefox.mo
 
 # Table of fallbacks for each language
 # please file a bug at bugzilla.redhat.com if the assignment is incorrect
-create_default_langpack "bn-IN" "bn"
 create_default_langpack "es-AR" "es"
 create_default_langpack "fy-NL" "fy"
 create_default_langpack "ga-IE" "ga"
@@ -1114,6 +1250,8 @@ rm -rf %{_srcrpmdir}/gtk3-private-%{gtk3_nvr}*.src.rpm
 find %{_rpmdir} -name "gtk3-private-*%{gtk3_nvr}*.rpm" -delete
 rm -rf %{_srcrpmdir}/libffi*.src.rpm
 find %{_rpmdir} -name "libffi*.rpm" -delete
+rm -rf %{_srcrpmdir}/openssl*.src.rpm
+find %{_rpmdir} -name "openssl*.rpm" -delete
 
 %post
 update-desktop-database &> /dev/null || :
@@ -1161,10 +1299,10 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 %{mozappdir}/browser/features/*.xpi
 %{mozappdir}/distribution/distribution.ini
 # That's Windows only
-%ghost %{mozappdir}/browser/features/aushelper@mozilla.org.xpi
+#%exclude %{mozappdir}/browser/features/aushelper@mozilla.org.xpi
 %attr(644, root, root) %{mozappdir}/browser/blocklist.xml
-%dir %{mozappdir}/browser/extensions
-%{mozappdir}/browser/extensions/*
+#%dir %{mozappdir}/browser/extensions
+#%{mozappdir}/browser/extensions/*
 %if %{build_langpacks}
 %dir %{langpackdir}
 %endif
@@ -1197,7 +1335,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 %{mozappdir}/platform.ini
 %{mozappdir}/plugin-container
 %{mozappdir}/gmp-clearkey
-%{mozappdir}/fonts/EmojiOneMozilla.ttf
+%{mozappdir}/fonts/*.ttf
 %if !%{?system_libicu}
 #%{mozappdir}/icudt*.dat
 %endif
@@ -1221,20 +1359,51 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 #---------------------------------------------------------------------
 
 %changelog
-* Wed May 15 2019 Martin Stransky <stransky@redhat.com> - 60.7.0-1
-- Updated to 60.7.0 ESR
+* Wed Nov 27 2019 Martin Stransky <stransky@redhat.com> - 68.3.0-1
+- Update to 68.3.0 ESR
+
+* Thu Oct 24 2019 Martin Stransky <stransky@redhat.com> - 68.2.0-4
+- Added patch for TLS 1.3 support.
+
+* Wed Oct 23 2019 Martin Stransky <stransky@redhat.com> - 68.2.0-3
+- Rebuild
+
+* Mon Oct 21 2019 Martin Stransky <stransky@redhat.com> - 68.2.0-2
+- Rebuild
+
+* Thu Oct 17 2019 Martin Stransky <stransky@redhat.com> - 68.2.0-1
+- Update to 68.2.0 ESR
+
+* Thu Oct 10 2019 Martin Stransky <stransky@redhat.com> - 68.1.0-6
+- Enable system nss on RHEL6
+
+* Thu Sep  5 2019 Jan Horak <jhorak@redhat.com> - 68.1.0-2
+- Enable building langpacks
+
+* Wed Aug 28 2019 Jan Horak <jhorak@redhat.com> - 68.1.0-1
+- Update to 68.1.0 ESR
+
+* Mon Aug 5 2019 Martin Stransky <stransky@redhat.com> - 68.0.1-4
+- Enable system nss
+
+* Mon Jul 29 2019 Martin Stransky <stransky@redhat.com> - 68.0.1-3
+- Enable official branding
+
+* Fri Jul 26 2019 Martin Stransky <stransky@redhat.com> - 68.0.1-2
+- Enabled PipeWire on RHEL8
 
-* Thu May 9 2019 Martin Stransky <stransky@redhat.com> - 60.6.3-1
-- Updated to 60.6.3 ESR
+* Fri Jul 26 2019 Martin Stransky <stransky@redhat.com> - 68.0.1-1
+- Updated to 68.0.1 ESR
 
-* Tue May 7 2019 Martin Stransky <stransky@redhat.com> - 60.6.2-1
-- Updated to 60.6.2 ESR
+* Tue Jul 16 2019 Jan Horak <jhorak@redhat.com> - 68.0-0.11
+- Update to 68.0 ESR
 
-* Mon Mar 27 2019 Martin Stransky <stransky@redhat.com> - 60.6.1-2
-- Added fix for mozbz#526293 - show remote locations on file chooser dialog.
+* Tue Jun 25 2019 Martin Stransky <stransky@redhat.com> - 68.0-0.10
+- Updated to 68.0 alpha 13
+- Enabled second arches
 
-* Mon Mar 25 2019 Martin Stransky <stransky@redhat.com> - 60.6.1-1
-- Update to 60.6.1 ESR (Build 1)
+* Fri Mar 22 2019 Martin Stransky <stransky@redhat.com> - 68.0-0.1
+- Updated to 68.0 alpha
 
 * Fri Mar 15 2019 Martin Stransky <stransky@redhat.com> - 60.6.0-3
 - Added Google API keys (mozbz#1531176)