diff --git a/.firefox.metadata b/.firefox.metadata
index dc7cb38..a130477 100644
--- a/.firefox.metadata
+++ b/.firefox.metadata
@@ -1,7 +1,10 @@
 18a8f30a0356c751b8d0ea6f76e764cab13ee046 SOURCES/Python-2.7.13.tar.xz
-616f8afdee741f0bea607a671b8515ef13c68b4a SOURCES/firefox-60.9.0esr.source.tar.xz
-7d8b2115d943bbfbe923ce0417414b8b54627660 SOURCES/firefox-langpacks-60.9.0esr-20190902.tar.xz
+ee55acedef049268307633cbc9c7ff0610d1244f SOURCES/Python-3.6.8.tar.xz
+e86c38c48960b95353503b78e1de9ddca1ed34d7 SOURCES/cbindgen-vendor.tar.xz
+c24f8036294edba40fd36f52a9dbe2cfe30cd229 SOURCES/firefox-68.1.0esr.source.tar.xz
+8b0d140fb0841d3d11d364044688b1200205f268 SOURCES/firefox-langpacks-68.1.0esr-20190828.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
+cd7cbb8925956da9d83ddfd989e725f036a56e44 SOURCES/nodejs-8.11.4-1.fc27.src.rpm
 77fd30f7ebc12a629a31c1e252cec06af55a71fe SOURCES/yasm-1.2.0-3.el5.src.rpm
diff --git a/.gitignore b/.gitignore
index 1a0405d..3af2f7a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,10 @@
 SOURCES/Python-2.7.13.tar.xz
-SOURCES/firefox-60.9.0esr.source.tar.xz
-SOURCES/firefox-langpacks-60.9.0esr-20190902.tar.xz
+SOURCES/Python-3.6.8.tar.xz
+SOURCES/cbindgen-vendor.tar.xz
+SOURCES/firefox-68.1.0esr.source.tar.xz
+SOURCES/firefox-langpacks-68.1.0esr-20190828.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.fc27.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/Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch b/SOURCES/Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch
deleted file mode 100644
index b551e1b..0000000
--- a/SOURCES/Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up firefox-60.0/mfbt/LinuxSignal.h.mozilla-1238661 firefox-60.0/mfbt/LinuxSignal.h
---- firefox-60.0/mfbt/LinuxSignal.h.mozilla-1238661	2018-04-27 08:55:38.848241768 +0200
-+++ firefox-60.0/mfbt/LinuxSignal.h	2018-04-27 09:06:47.946769859 +0200
-@@ -22,7 +22,7 @@ __attribute__((naked)) void SignalTrampo
-                                              void* aContext) {
-   asm volatile("nop; nop; nop; nop" : : : "memory");
- 
--  asm volatile("b %0" : : "X"(H) : "memory");
-+  asm volatile("bx %0" : : "r"(H), "l"(aSignal), "l"(aInfo), "l"(aContext) : "memory");
- }
- 
- #define MOZ_SIGNAL_TRAMPOLINE(h) (mozilla::SignalTrampoline<h>)
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 0c3add5..e7132c1 100644
--- a/SOURCES/build-nss-version.patch
+++ b/SOURCES/build-nss-version.patch
@@ -1,12 +1,14 @@
-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.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/old-configure.in.old firefox-68.0/old-configure.in
+--- firefox-68.0/old-configure.in.old	2019-07-25 21:39:10.458338754 +0200
++++ firefox-68.0/old-configure.in	2019-07-25 21:39:17.316311409 +0200
+@@ -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.8, [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.1, [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/distribution.ini b/SOURCES/distribution.ini
index 0a0429e..8bf461e 100644
--- a/SOURCES/distribution.ini
+++ b/SOURCES/distribution.ini
@@ -1,7 +1,7 @@
 [Global]
 id=redhat
 version=1.0
-about=Mozilla Firefox for CentOS Linux
+about=Mozilla Firefox for Red Hat Enterprise Linux
 
 [Preferences]
 app.distributor=redhat
diff --git a/SOURCES/firefox-centos-default-prefs.js b/SOURCES/firefox-centos-default-prefs.js
deleted file mode 100644
index ea10021..0000000
--- a/SOURCES/firefox-centos-default-prefs.js
+++ /dev/null
@@ -1,35 +0,0 @@
-pref("app.update.auto",                     false);
-pref("app.update.enabled",                  false);
-pref("app.update.autoInstallEnabled",       false);
-pref("general.smoothScroll",                true);
-pref("intl.locale.matchOS",                 true);
-pref("toolkit.storage.synchronous",         0);
-pref("toolkit.networkmanager.disable",      false);
-pref("offline.autoDetect",                  true);
-pref("browser.backspace_action",            2);
-pref("browser.display.use_system_colors",   true);
-pref("browser.download.folderList",         1);
-pref("browser.link.open_external",          3);
-pref("browser.shell.checkDefaultBrowser",   false);
-pref("network.manage-offline-status",       true);
-pref("extensions.shownSelectionUI",         true);
-pref("ui.SpellCheckerUnderlineStyle",       1);
-pref("startup.homepage_override_url",       "http://www.centos.org");
-pref("startup.homepage_welcome_url",        "http://www.centos.org");
-pref("browser.startup.homepage",            "data:text/plain,browser.startup.homepage=file:///usr/share/doc/HTML/index.html");
-pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
-pref("media.gmp-gmpopenh264.provider.enabled",false);
-pref("media.gmp-gmpopenh264.autoupdate",false);
-pref("media.gmp-gmpopenh264.enabled",false);
-pref("media.gmp-gmpopenh264.enabled",false);
-pref("plugins.notifyMissingFlash", false);
-/* See https://bugzilla.redhat.com/show_bug.cgi?id=1226489 */
-pref("browser.display.use_system_colors", false);
-pref("layers.use-image-offscreen-surfaces", false);
-/* Allow sending credetials to all https:// sites */
-pref("network.negotiate-auth.trusted-uris", "https://");
-pref("security.use_sqldb", false);
-/* Use OS settings for UI language */
-pref("intl.locale.requested", "");
-/* See https://bugzilla.redhat.com/show_bug.cgi?id=1672424 */
-pref("storage.nfs_filesystem", true);
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-redhat-default-prefs.js b/SOURCES/firefox-redhat-default-prefs.js
new file mode 100644
index 0000000..607a132
--- /dev/null
+++ b/SOURCES/firefox-redhat-default-prefs.js
@@ -0,0 +1,35 @@
+pref("app.update.auto",                     false);
+pref("app.update.enabled",                  false);
+pref("app.update.autoInstallEnabled",       false);
+pref("general.smoothScroll",                true);
+pref("intl.locale.matchOS",                 true);
+pref("toolkit.storage.synchronous",         0);
+pref("toolkit.networkmanager.disable",      false);
+pref("offline.autoDetect",                  true);
+pref("browser.backspace_action",            2);
+pref("browser.display.use_system_colors",   true);
+pref("browser.download.folderList",         1);
+pref("browser.link.open_external",          3);
+pref("browser.shell.checkDefaultBrowser",   false);
+pref("network.manage-offline-status",       true);
+pref("extensions.shownSelectionUI",         true);
+pref("ui.SpellCheckerUnderlineStyle",       1);
+pref("startup.homepage_override_url",       "http://www.redhat.com");
+pref("startup.homepage_welcome_url",        "http://www.redhat.com");
+pref("browser.startup.homepage",            "data:text/plain,browser.startup.homepage=file:///usr/share/doc/HTML/index.html");
+pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
+pref("media.gmp-gmpopenh264.provider.enabled",false);
+pref("media.gmp-gmpopenh264.autoupdate",false);
+pref("media.gmp-gmpopenh264.enabled",false);
+pref("media.gmp-gmpopenh264.enabled",false);
+pref("plugins.notifyMissingFlash", false);
+/* See https://bugzilla.redhat.com/show_bug.cgi?id=1226489 */
+pref("browser.display.use_system_colors", false);
+pref("layers.use-image-offscreen-surfaces", false);
+/* Allow sending credetials to all https:// sites */
+pref("network.negotiate-auth.trusted-uris", "https://");
+pref("security.use_sqldb", false);
+/* Use OS settings for UI language */
+pref("intl.locale.requested", "");
+/* See https://bugzilla.redhat.com/show_bug.cgi?id=1672424 */
+pref("storage.nfs_filesystem", true);
\ No newline at end of file
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.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/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 be1f3d5..b38cadc 100644
--- a/SPECS/firefox.spec
+++ b/SPECS/firefox.spec
@@ -1,16 +1,37 @@
+# Fails with internal compiler error
+# ExcludeArch: s390x
+
 # Set for local builds only
 %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        0
+%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
@@ -22,18 +43,12 @@
 %global use_dts           1
 %endif
 
-%if 0%{?rhel} == 7
-%define use_bundled_python 0
-%endif
-
-%if 0%{?rhel} < 8
 %global use_rustts        1
-%endif
-%global dts_version       7
-%global rst_version       7
-%global llvm_version      7
+%global dts_version       8
+%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 +98,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 +114,17 @@
 %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
+%if 0%{?rhel} < 8
+%define use_bundled_nodejs      1
+%else
+%define use_bundled_nodejs      0
+%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 +149,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,8 +163,8 @@
 
 Summary:        Mozilla Firefox Web browser
 Name:           firefox
-Version:        60.9.0
-Release:        1%{?pre_tag}%{?dist}
+Version:        68.1.0
+Release:        2%{?pre_tag}%{?dist}
 URL:            https://www.mozilla.org/firefox/
 License:        MPLv1.1 or GPLv2+ or LGPLv2+
 %if 0%{?rhel} == 7
@@ -154,10 +176,11 @@ 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}-20190902.tar.xz
+Source1:        firefox-langpacks-%{version}%{?pre_version}-20190828.tar.xz
 %endif
+Source2:        cbindgen-vendor.tar.xz
 Source10:       firefox-mozconfig
-Source12:       firefox-centos-default-prefs.js
+Source12:       firefox-redhat-default-prefs.js
 Source20:       firefox.desktop
 Source21:       firefox.sh.in
 Source23:       firefox.1
@@ -165,6 +188,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 +199,28 @@ 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.fc27.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
+# 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 +230,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,18 +238,18 @@ 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
 
 # Upstream patches
 Patch402:        mozilla-1196777.patch
 Patch406:        mozilla-256180.patch
-Patch413:        mozilla-1353817.patch
+#Patch413:        mozilla-1353817.patch
 Patch415:        mozilla-1436242.patch
 
-Patch1000:       Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch
+#Patch500:        debug.patch
+Patch501:        python-encode.patch
 
 # Debian patches
 
@@ -269,16 +306,20 @@ 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}
+#FIXME 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}
@@ -286,7 +327,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
@@ -349,10 +390,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
@@ -425,8 +462,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
@@ -434,67 +471,77 @@ 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
+%endif
+%if 0%{?use_bundled_python_3}
+%setup -q -T -c -n python3 -a 101
+%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
 
 # 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
 
-%ifarch %{arm}
-%patch1000 -p1 -b .mozilla-1238661
-%endif 
 
 # Patch for big endian platforms only
 %if 0%{?big_endian}
 %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}
@@ -530,14 +577,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}
@@ -601,12 +649,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
@@ -614,6 +657,11 @@ 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}
@@ -645,7 +693,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}
@@ -667,7 +715,7 @@ 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 "==============================="
@@ -684,13 +732,37 @@ function build_bundled_package() {
   popd
 }
 
+
+# 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"
+    make %{?_smp_mflags} install V=1
+    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
+
+# 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
+
 # Build and install local yasm if needed
 # ======================================
 %if %{use_bundled_yasm}
   build_bundled_package 'yasm-1*.rpm' 'yasm-*.rpm' '%{SOURCE301}'
 %endif
 
-
 %if 0%{?bundle_gtk3}
    %if ! 0%{?avoid_bundled_rebuild}
     rpm -ivh %{SOURCE200}
@@ -704,18 +776,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}
@@ -733,6 +793,34 @@ function build_bundled_package() {
 
 # GTK3 <<
 
+# We need to disable exit on error temporarily for the following scripts:
+set +e
+%if 0%{?use_dts}
+source scl_source enable devtoolset-%{dts_version}
+%endif
+%if 0%{?use_rustts}
+source scl_source enable rust-toolset-%{rust_toolset_version}
+%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, ...
@@ -744,28 +832,17 @@ case "%{sqlite_build_version}" in
 esac
 %endif
 
-# We need to disable exit on error temporarily for the following scripts:
-set +e
-%if 0%{?use_dts}
-source scl_source enable devtoolset-%{dts_version}
-%endif
-%if 0%{?use_rustts}
-source scl_source enable rust-toolset-%{rst_version}
-%endif
-
-set -e
-# Hack for missing shell when building in brew on RHEL6
-%if 0%{?rhel} == 6
-export SHELL=/bin/sh
-%endif
-
-echo "Generate big endian version of config/external/icu/data/icud58l.dat"
+echo "Generate big endian version of config/external/icu/data/icud64l.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
+# ./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 {} ';'
 
@@ -813,6 +890,8 @@ 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,
@@ -830,13 +909,9 @@ MOZ_SMP_FLAGS=-j1
 %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
@@ -1032,7 +1107,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"
@@ -1168,8 +1242,8 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 # That's Windows only
 %ghost %{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
@@ -1202,7 +1276,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
@@ -1226,32 +1300,33 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 #---------------------------------------------------------------------
 
 %changelog
-* Mon Sep  2 2019 Jan Horak <jhorak@redhat.com> - 60.9.0-1
-- Update to 60.9.0 ESR
+* Thu Sep  5 2019 Jan Horak <jhorak@redhat.com> - 68.1.0-2
+- Enable building langpacks
 
-* Wed Jul 3 2019 Jan Horak <jhorak@redhat.com> - 60.8.0-1
-- Update to 60.8.0 ESR
+* Wed Aug 28 2019 Jan Horak <jhorak@redhat.com> - 68.1.0-1
+- Update to 68.1.0 ESR
 
-* Thu Jun 20 2019 Jan Horak <jhorak@redhat.com> - 60.7.2-3
-- Update to 60.7.2 ESR
+* Mon Aug 5 2019 Martin Stransky <stransky@redhat.com> - 68.0.1-4
+- Enable system nss
 
-* Wed Jun 19 2019 Martin Stransky <stransky@redhat.com> - 60.7.1-1
-- Updated to 60.7.1 ESR
+* Mon Jul 29 2019 Martin Stransky <stransky@redhat.com> - 68.0.1-3
+- Enable official branding
 
-* Wed May 15 2019 Martin Stransky <stransky@redhat.com> - 60.7.0-1
-- Updated to 60.7.0 ESR
+* 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)