summaryrefslogtreecommitdiff
path: root/Tools/gtk
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Tools/gtk
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Tools/gtk')
-rw-r--r--Tools/gtk/GNUmakefile.am153
-rwxr-xr-xTools/gtk/check-for-webkitdom-api-breaks78
-rw-r--r--Tools/gtk/common.py52
-rwxr-xr-xTools/gtk/generate-feature-defines-files58
-rwxr-xr-xTools/gtk/generate-gtkdoc64
-rwxr-xr-xTools/gtk/generate-inspector-gresource-manifest.py14
-rw-r--r--Tools/gtk/gtkdoc.py28
-rwxr-xr-xTools/gtk/install-dependencies479
-rw-r--r--Tools/gtk/jhbuild.modules628
-rw-r--r--Tools/gtk/jhbuildrc44
-rwxr-xr-xTools/gtk/make-dist.py333
-rw-r--r--Tools/gtk/manifest.txt.in106
-rw-r--r--Tools/gtk/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch30
-rw-r--r--Tools/gtk/patches/fontconfig-fix-osx-cache.diff207
-rw-r--r--Tools/gtk/patches/freetype6-2.4.11-truetype-font-height-fix.patch39
-rw-r--r--Tools/gtk/patches/gdate-suppress-string-format-literal-warning.patch29
-rw-r--r--Tools/gtk/patches/glib-warning-fix.patch34
-rw-r--r--Tools/gtk/patches/gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch236
-rw-r--r--Tools/gtk/patches/gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch37
-rw-r--r--Tools/gtk/patches/gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch156
-rw-r--r--Tools/gtk/patches/gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch61
-rw-r--r--Tools/gtk/patches/gst-plugins-good-0003-rtpbin-receive-bundle-support.patch1018
-rw-r--r--Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch320
-rw-r--r--Tools/gtk/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch133
-rw-r--r--Tools/gtk/patches/gst-plugins-good-use-the-tfdt-decode-time.patch89
-rw-r--r--Tools/gtk/patches/gstreamer-0001-protection-added-function-to-filter-system-ids.patch77
-rw-r--r--Tools/gtk/patches/gtk+-configure-fix-detecting-CUPS-2.x.patch11
-rw-r--r--Tools/gtk/patches/icudata-stdlibs.patch15
-rw-r--r--Tools/gtk/patches/libnice-0001-TURN-allow-REALM-to-be-empty.patch50
-rw-r--r--Tools/gtk/patches/libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch253
-rw-r--r--Tools/gtk/patches/librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch1581
-rw-r--r--Tools/gtk/patches/libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch130
-rw-r--r--Tools/gtk/patches/libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch114
-rw-r--r--Tools/gtk/patches/mesa-gallivm-Fix-build-after-LLVM-commit-211259.patch29
-rw-r--r--Tools/gtk/patches/openh264-configure.patch12
-rw-r--r--Tools/gtk/patches/rtspsrc-timeout-on-udpsrc-is-in-nanoseconds.patch27
-rw-r--r--Tools/gtk/patches/shared-mime-info-xht-glob.patch21
-rw-r--r--Tools/gtk/patches/shared-mime-info-xhtml-magic.patch26
-rw-r--r--Tools/gtk/patches/udpsrc-improve-timeouts.patch53
-rw-r--r--Tools/gtk/patches/xserver-remove-bogus-dependencies.patch43
-rw-r--r--Tools/gtk/patches/xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch84
-rwxr-xr-xTools/gtk/webkitdom.py285
-rw-r--r--Tools/gtk/ycm_extra_conf.py132
43 files changed, 6699 insertions, 670 deletions
diff --git a/Tools/gtk/GNUmakefile.am b/Tools/gtk/GNUmakefile.am
deleted file mode 100644
index 61cff0134..000000000
--- a/Tools/gtk/GNUmakefile.am
+++ /dev/null
@@ -1,153 +0,0 @@
-EXTRA_DIST += \
- Tools/gtk/check-for-webkitdom-api-breaks \
- Tools/gtk/common.py \
- Tools/gtk/generate-feature-defines-files \
- Tools/gtk/generate-gtkdoc \
- Tools/gtk/generate-inspector-gresource-manifest.py \
- Tools/gtk/gtkdoc.py \
- Tools/gtk/webkitdom.py
-
-docs: docs-build.stamp
-.PHONY : docs
-DISTCLEANFILES += docs-build.stamp
-
-docs_build_dependencies = \
- Source/WebKit/gtk/docs/webkitenvironment.xml
-
-if ENABLE_WEBKIT1
-docs_build_dependencies += \
- libwebkitgtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \
- Source/WebKit/gtk/docs/webkitgtk-docs.sgml \
- Source/WebKit/gtk/docs/webkitgtk-sections.txt \
- gtkdoc-webkitgtk.cfg
-endif
-
-if ENABLE_WEBKIT2
-docs_build_dependencies += \
- libwebkit2gtk-@WEBKITGTK_API_MAJOR_VERSION@.@WEBKITGTK_API_MINOR_VERSION@.la \
- Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml \
- Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt \
- gtkdoc-webkit2gtk.cfg
-endif
-
-docs_build_dependencies += \
- libGObjectDOMBindings.la \
- gtkdoc-webkitdom.cfg
-
-docs-build.stamp: $(docs_build_dependencies)
- CC=$(CC) $(PYTHON) $(srcdir)/Tools/gtk/generate-gtkdoc
- @touch docs-build.stamp
-
-clean-local: doc-clean-local
-doc-clean-local:
- @rm -f Documentation/webkitgtk/*~ Documentation/webkitgtk*.bak
- @rm -f Documentation/webkit2gtk/*~ Documentation/webkit2gtk*.bak
- @rm -f Documentation/webkitdomgtk/*~ Documentation/webkitdomgtk*.bak
-
-distclean-local: doc-distclean-local
-doc-distclean-local:
- @rm -rf Documentation
-maintainer-clean-local: doc-maintainer-clean-local
-doc-maintainer-clean-local: clean
- @rm -rf Documentation/webkitgtk Documentation/webkit2gtk Documentation/webkitdomgtk
- -@rmdir Documentation
-
-install-data-local:
-if ENABLE_WEBKIT1
- @installfiles=`echo ./Documentation/webkitgtk/html/*`; \
- if test "$$installfiles" = './Documentation/webkitgtk/html/*'; \
- then echo 1>&2 'No documentation to install' ; \
- else \
- DOC_MODULE_VERSION=`cat ./Documentation/webkitgtk/version.xml`; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- installdir="$(DESTDIR)$(HTML_DIR)/webkitgtk-$(DOC_MODULE_VERSION)"; \
- else \
- installdir="$(DESTDIR)$(HTML_DIR)/webkitgtk"; \
- fi; \
- $(mkinstalldirs) $${installdir} ; \
- for i in $$installfiles; do \
- echo ' $(INSTALL_DATA) '$$i ; \
- $(INSTALL_DATA) $$i $${installdir}; \
- done; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- mv -f $${installdir}/webkitgtk.devhelp2 \
- $${installdir}/webkitgtk-$(DOC_MODULE_VERSION).devhelp2; \
- fi; \
- fi
-endif
-if ENABLE_WEBKIT2
- @installfiles=`echo ./Documentation/webkit2gtk/html/*`; \
- if test "$$installfiles" = './Documentation/webkit2gtk/html/*'; \
- then echo 1>&2 'No documentation to install' ; \
- else \
- DOC_MODULE_VERSION=`cat ./Documentation/webkit2gtk/version.xml`; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- installdir="$(DESTDIR)$(HTML_DIR)/webkit2gtk-$(DOC_MODULE_VERSION)"; \
- else \
- installdir="$(DESTDIR)$(HTML_DIR)/webkit2gtk"; \
- fi; \
- $(mkinstalldirs) $${installdir} ; \
- for i in $$installfiles; do \
- echo ' $(INSTALL_DATA) '$$i ; \
- $(INSTALL_DATA) $$i $${installdir}; \
- done; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- mv -f $${installdir}/webkit2gtk.devhelp2 \
- $${installdir}/webkit2gtk-$(DOC_MODULE_VERSION).devhelp2; \
- fi; \
- fi
-endif
- @installfiles=`echo ./Documentation/webkitdomgtk/html/*`; \
- if test "$$installfiles" = './Documentation/webkitdomgtk/html/*'; \
- then echo 1>&2 'No documentation to install' ; \
- else \
- DOC_MODULE_VERSION=`cat ./Documentation/webkitdomgtk/version.xml`; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- installdir="$(DESTDIR)$(HTML_DIR)/webkitdomgtk-$(DOC_MODULE_VERSION)"; \
- else \
- installdir="$(DESTDIR)$(HTML_DIR)/webkitdomgtk"; \
- fi; \
- $(mkinstalldirs) $${installdir} ; \
- for i in $$installfiles; do \
- echo ' $(INSTALL_DATA) '$$i ; \
- $(INSTALL_DATA) $$i $${installdir}; \
- done; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- mv -f $${installdir}/webkitdomgtk.devhelp2 \
- $${installdir}/webkitdomgtk-$(DOC_MODULE_VERSION).devhelp2; \
- fi; \
- fi
-if ENABLE_GTK_DOC
- @$(AM_V_GEN) PKG_CONFIG=$(PKG_CONFIG) $(PYTHON) $(srcdir)/Tools/gtk/generate-gtkdoc --rebase --virtual-root=$${DESTDIR}
-endif
-
-uninstall-local:
-if ENABLE_WEBKIT1
- @DOC_MODULE_VERSION=`cat ./Documentation/webkitgtk/version.xml`; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- installdir="$(DESTDIR)$(HTML_DIR)/webkitgtk-$(DOC_MODULE_VERSION)"; \
- else \
- installdir="$(DESTDIR)$(HTML_DIR)/webkitgtk"; \
- fi; \
- rm -rf $${installdir}
-endif
-if ENABLE_WEBKIT2
- @DOC_MODULE_VERSION=`cat ./Documentation/webkit2gtk/version.xml`; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- installdir="$(DESTDIR)$(HTML_DIR)/webkit2gtk-$(DOC_MODULE_VERSION)"; \
- else \
- installdir="$(DESTDIR)$(HTML_DIR)/webkit2gtk"; \
- fi; \
- rm -rf $${installdir}
-endif
- @DOC_MODULE_VERSION=`cat ./Documentation/webkitdomgtk/version.xml`; \
- if test -n "$(DOC_MODULE_VERSION)"; then \
- installdir="$(DESTDIR)$(HTML_DIR)/webkitdomgtk-$(DOC_MODULE_VERSION)"; \
- else \
- installdir="$(DESTDIR)$(HTML_DIR)/webkitdomgtk"; \
- fi; \
- rm -rf $${installdir}
-if ENABLE_GTK_DOC
-noinst_DATA += docs-build.stamp
-endif
-
diff --git a/Tools/gtk/check-for-webkitdom-api-breaks b/Tools/gtk/check-for-webkitdom-api-breaks
deleted file mode 100755
index 2f4237b51..000000000
--- a/Tools/gtk/check-for-webkitdom-api-breaks
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2013, 2014 Igalia S.L.
-# Copyright (C) 2013 Gustavo Noronha Silva <gns@gnome.org>
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import argparse
-import common
-import os
-import sys
-import webkitdom
-
-EXPECTED_API_PATH = common.top_level_path('Source', 'WebCore', 'bindings', 'gobject', 'webkitdom.symbols')
-
-def read_built_api():
- apis = set()
- for file_path in webkitdom.get_all_webkitdom_symbol_files():
- with open(file_path) as file_handle:
- apis.update(set(file_handle.readlines()))
- return apis
-
-def read_expected_api():
- with open(EXPECTED_API_PATH) as file_handle:
- return set(file_handle.readlines())
-
-def write_expected_api(new_expected_api):
- with open(EXPECTED_API_PATH, 'w') as file_handle:
- file_handle.writelines(new_expected_api)
-
-def check_api(options, expected_api, built_api):
- missing_api = expected_api.difference(built_api)
- new_api = built_api.difference(expected_api)
-
- if missing_api:
- sys.stderr.write("Missing API (API break!) detected in GObject DOM bindings\n")
- sys.stderr.write(" %s\n" % " ".join(missing_api))
- sys.stderr.flush()
-
- if new_api:
- sys.stdout.write("New API detected in GObject DOM bindings\n")
- sys.stdout.write(" %s\n" % " ".join(new_api))
-
- if missing_api:
- # This test can give false positives because the GObject
- # DOM bindings API varies depending on the compilation options.
- # So this shouldn't be made fatal until we figure out a way to handle it.
- # See https://bugs.webkit.org/show_bug.cgi?id=121481
- sys.stderr.write("Re-add the missing API and rerun the %s.\n" % __file__)
- return 0
-
- if new_api:
- if options.reset_results:
- sys.stdout.write("Resetting expected API\n")
- write_expected_api(built_api)
- else:
- sys.stdout.write("API compatible changes found in GObject DOM bindings.\n")
- sys.stdout.write("To update the symbols file, run %s --reset-results.\n" % __file__)
-
- return 0
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='Detect API breakage in the WebKitGTK+ GObject DOM bindings.')
- parser.add_argument('--reset-results', action='store_true',
- help='When specified, rest the expected results file with the built results.')
- options = parser.parse_args()
- sys.exit(check_api(options, read_expected_api(), read_built_api()))
diff --git a/Tools/gtk/common.py b/Tools/gtk/common.py
index 02f8b6541..f53cc95aa 100644
--- a/Tools/gtk/common.py
+++ b/Tools/gtk/common.py
@@ -24,8 +24,7 @@ import sys
top_level_dir = None
build_dir = None
library_build_dir = None
-tests_library_build_dir = None
-is_cmake = None
+binary_build_dir = None
build_types = ('Release', 'Debug')
@@ -41,41 +40,18 @@ def set_build_types(new_build_types):
build_types = new_build_types
-def is_cmake_build():
- global is_cmake
- if is_cmake is None:
- is_cmake = os.path.exists(build_path('CMakeCache.txt'))
- return is_cmake
-
-
def library_build_path(*args):
global library_build_dir
if not library_build_dir:
- if is_cmake_build():
- library_build_dir = build_path('lib', *args)
- else:
- library_build_dir = build_path('.libs', *args)
+ library_build_dir = build_path('lib', *args)
return library_build_dir
-def tests_library_build_path(*args):
- if is_cmake_build():
- return library_build_path(*args)
-
- global tests_library_build_dir
- if not tests_library_build_dir:
- tests_library_build_dir = build_path('Libraries', *args)
- return tests_library_build_dir
-
-
def binary_build_path(*args):
- global library_build_dir
- if not library_build_dir:
- if is_cmake_build():
- library_build_dir = build_path('bin', *args)
- else:
- library_build_dir = build_path('Programs', *args)
- return library_build_dir
+ global binary_build_dir
+ if not binary_build_dir:
+ binary_build_dir = build_path('bin', *args)
+ return binary_build_dir
def get_build_path(fatal=True):
@@ -84,11 +60,7 @@ def get_build_path(fatal=True):
return build_dir
def is_valid_build_directory(path):
- return os.path.exists(os.path.join(path, 'GNUmakefile')) or \
- os.path.exists(os.path.join(path, 'Programs', 'GtkLauncher')) or \
- os.path.exists(os.path.join(path, 'Programs', 'MiniBrowser')) or \
- os.path.exists(os.path.join(path, 'CMakeCache.txt')) or \
- os.path.exists(os.path.join(path, 'bin/GtkLauncher')) or \
+ return os.path.exists(os.path.join(path, 'CMakeCache.txt')) or \
os.path.exists(os.path.join(path, 'bin/MiniBrowser'))
if len(sys.argv[1:]) > 1 and os.path.exists(sys.argv[-1]) and is_valid_build_directory(sys.argv[-1]):
@@ -144,16 +116,6 @@ def prefix_of_pkg_config_file(package):
return pkg_config_file_variable(package, 'prefix')
-def gtk_version_of_pkg_config_file(pkg_config_path):
- process = subprocess.Popen(['pkg-config', pkg_config_path, '--print-requires'],
- stdout=subprocess.PIPE)
- stdout = process.communicate()[0].decode("utf-8")
-
- if 'gtk+-3.0' in stdout:
- return 3
- return 2
-
-
def parse_output_lines(fd, parse_line_callback):
output = ''
read_set = [fd]
diff --git a/Tools/gtk/generate-feature-defines-files b/Tools/gtk/generate-feature-defines-files
deleted file mode 100755
index 17d52e65a..000000000
--- a/Tools/gtk/generate-feature-defines-files
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-from __future__ import with_statement
-import os
-import re
-import sys
-
-def read_feature_defines_override(feature_defines):
- feature_defines_overriding_file = 'WebKitFeatureOverrides.txt'
- if not os.path.exists(feature_defines_overriding_file):
- return
-
- print("The following feature defines were overriden:")
- with open(feature_defines_overriding_file) as f:
- match_iter = re.findall(r"((?:ENABLE_)\w+)=(0|1)", f.read())
-
- for match in match_iter:
- feature = match[0]
- value = int(match[1])
-
- if feature in feature_defines and value != feature_defines[feature]:
- print("\t{0}: {1} => {2}".format(feature, feature_defines[feature], value))
- feature_defines[feature] = value
-
-def write_file_if_contents_changed(filename, contents):
- if os.path.exists(filename):
- with open(filename, 'r') as f:
- old_contents = f.read()
- if old_contents == contents:
- return
- with open(filename, 'w') as f:
- f.write(contents)
-
-def write_feature_defines_header(feature_defines):
- contents = ''
- for (feature, value) in feature_defines.items():
- contents += '#define {0} {1}\n'.format(feature, value)
- write_file_if_contents_changed("WebKitFeatures.h", contents)
-
-def write_flattened_feature_defines_file(feature_defines):
- contents = ''
- for (feature, value) in feature_defines.items():
- contents += '{0}={1}\n'.format(feature, value)
- write_file_if_contents_changed("WebKitFeatures.txt", contents)
-
-def generate_feature_defines_files(default_features):
- build_dir = os.getcwd()
- feature_defines = {}
-
- for feature_define in default_features:
- (feature, value) = feature_define.split("=")
- feature_defines[feature] = int(value)
-
- read_feature_defines_override(feature_defines)
- write_feature_defines_header(feature_defines)
- write_flattened_feature_defines_file(feature_defines)
-
-if __name__=='__main__':
- generate_feature_defines_files(sys.argv[1:])
diff --git a/Tools/gtk/generate-gtkdoc b/Tools/gtk/generate-gtkdoc
index 37eeee94c..33b2824f8 100755
--- a/Tools/gtk/generate-gtkdoc
+++ b/Tools/gtk/generate-gtkdoc
@@ -19,13 +19,16 @@ from __future__ import print_function
from ConfigParser import SafeConfigParser
import argparse
+import codecs
import common
import glob
import gtkdoc
import logging
import os.path
import sys
-import webkitdom
+
+sys.stdout = codecs.getwriter("utf-8")(sys.stdout)
+sys.stderr = codecs.getwriter("utf-8")(sys.stderr)
def configure_logging(verbose):
level = logging.DEBUG if verbose else logging.INFO
@@ -39,16 +42,13 @@ def configure_logging(verbose):
else:
handler.setFormatter(logging.Formatter('%(message)s'))
-def get_gtkdoc_module_paths(gtk_version):
+def get_gtkdoc_module_paths(cross_reference_deps):
dependent_packages = {
'glib-2.0' : ['glib', 'gobject', 'gio'],
'libsoup-2.4' : ['libsoup-2.4'],
- 'gdk-pixbuf-2.0': ['gdk-pixbuf']
+ 'gdk-pixbuf-2.0': ['gdk-pixbuf'],
+ 'gtk+-3.0' : ['gtk3', 'gdk3']
}
- if gtk_version == 3:
- dependent_packages.update({'gtk+-3.0' : ['gtk3', 'gdk3']})
- else:
- dependent_packages.update({'gtk+-2.0' : ['gtk', 'gdk']})
paths = []
html_dir = os.path.join('share', 'gtk-doc', 'html')
@@ -58,9 +58,9 @@ def get_gtkdoc_module_paths(gtk_version):
continue
for module in modules:
paths.append(os.path.join(prefix, html_dir, module))
- # This technically is not needed for the GObject DOM bindings documentation itself,
- # but adding it doesn't hurt and allows us to avoid a check here.
- paths.append(common.build_path('Documentation', 'webkitdomgtk', 'html'))
+
+ for local_dep in cross_reference_deps:
+ paths.append(common.build_path('Documentation', local_dep, 'html'))
return paths
def print_missing_api(generator):
@@ -91,13 +91,13 @@ def files_to_ignore(source_dirs, headers_with_gtkdoc):
if os.path.splitext(file)[1] not in ['.h', '.c', '.cpp', '.cc']:
return False # These files are ignored anyway.
if not os.path.isfile(file):
- return False
+ return True
return os.path.abspath(file) not in implementation_files
all_files = sum([[os.path.join(dir, file) for file in os.listdir(dir)] for dir in source_dirs], [])
return filter(file_should_be_ignored, all_files)
-def get_generator_for_config(config_file, virtual_root):
+def get_generator_for_config(config_file, virtual_root, cross_reference_deps = []):
if not os.path.isfile(config_file):
return None
@@ -105,7 +105,6 @@ def get_generator_for_config(config_file, virtual_root):
config.read(config_file)
module_name = config.sections()[0]
pkgconfig_file = config.get(module_name, 'pkgconfig_file')
- gtk_version = common.gtk_version_of_pkg_config_file(pkgconfig_file)
if not os.path.isfile(pkgconfig_file):
return None
@@ -121,37 +120,32 @@ def get_generator_for_config(config_file, virtual_root):
'namespace': config.get(module_name, 'namespace'),
'doc_dir': config.get(module_name, 'doc_dir'),
'output_dir': common.build_path('Documentation', module_name),
+ 'main_sgml_file': config.get(module_name, 'main_sgml_file'),
'source_dirs': source_dirs,
'headers': headers,
'cflags': " ".join(config.get(module_name, 'cflags').split()),
- 'cross_reference_deps': get_gtkdoc_module_paths(gtk_version),
+ 'cross_reference_deps': get_gtkdoc_module_paths(cross_reference_deps),
'ignored_files': files_to_ignore(source_dirs, headers),
})
def generate_doc(generator, skip_html):
- print("\nGenerating {0} documentation...".format(generator.module_name))
generator.generate(not skip_html)
if generator.saw_warnings:
print_missing_api(generator)
return generator.saw_warnings
def rebase_doc(generator):
- print("\nRebasing {0} documentation...".format(generator.module_name))
try:
generator.rebase_installed_docs()
except Exception:
print("Rebase did not happen, likely no documentation is present.")
-def generate_documentation_for_config(config_file):
- generator = get_generator_for_config(config_file, arguments.virtual_root)
- if not generator:
- print("{0} does not exist! Skipping that documentation.".format(os.path.basename(config_file)))
- return
-
+def generate_documentation(generator):
if not arguments.rebase:
return generate_doc(generator, arguments.skip_html)
rebase_doc(generator)
+ return False
def prepare_environment_for_gtkdoc_generation():
# We need to add the JavaScriptCore build directory to the PKG_CONFIG_PATH
@@ -174,10 +168,6 @@ def prepare_environment_for_gtkdoc_generation():
cflags += ' -Wno-cast-align'
os.environ['CFLAGS'] = cflags
- # Clang can be noisy, throwing unnecessary warnings for unused arguments.
- if os.environ.get('CC') == "clang":
- os.environ['CFLAGS'] += ' -Qunused-arguments'
-
# Paths from the GNUmakefile generated configuration files are relative to the build directory.
os.chdir(common.build_path())
@@ -200,10 +190,18 @@ if __name__ == "__main__":
prepare_environment_for_gtkdoc_generation()
- webkitdom.write_doc_files()
- generate_documentation_for_config(common.build_path('gtkdoc-webkitdom.cfg'))
-
- saw_webkit1_warnings = generate_documentation_for_config(common.build_path('gtkdoc-webkitgtk.cfg'))
- saw_webkit2_warnings = generate_documentation_for_config(common.build_path('gtkdoc-webkit2gtk.cfg'))
-
- sys.exit(saw_webkit1_warnings or saw_webkit2_warnings)
+ webkitdom_generator = get_generator_for_config(common.build_path('gtkdoc-webkitdom.cfg'), arguments.virtual_root)
+ if not webkitdom_generator:
+ print("gtkdoc-webkitdom.cfg does not exist! Skipping that documentation")
+ sys.exit(1)
+ saw_warnings = generate_documentation(webkitdom_generator)
+ if saw_warnings:
+ sys.exit(saw_warnings)
+
+ webkit2_generator = get_generator_for_config(common.build_path('gtkdoc-webkit2gtk.cfg'), arguments.virtual_root, [webkitdom_generator.module_name])
+ if not webkit2_generator:
+ print("gtkdoc-webkit2gtk.cfg does not exist! Skipping that documentation")
+ sys.exit(1)
+ saw_warnings = generate_documentation(webkit2_generator)
+
+ sys.exit(saw_warnings)
diff --git a/Tools/gtk/generate-inspector-gresource-manifest.py b/Tools/gtk/generate-inspector-gresource-manifest.py
index d319eba0c..03060cfa2 100755
--- a/Tools/gtk/generate-inspector-gresource-manifest.py
+++ b/Tools/gtk/generate-inspector-gresource-manifest.py
@@ -33,8 +33,8 @@ def get_filenames(args):
base_dir_index = filename.rfind(BASE_DIR)
if base_dir_index != -1:
name = filename[base_dir_index + len(BASE_DIR):]
- # The result should use forward slashes, thus make sure any os-specific
- # separator, added by the glob.glob() call, is properly replaced
+ # The result should use forward slashes, thus make sure any os-specific
+ # separator, added by the glob.glob() call, is properly replaced
if os.sep != '/':
name = name.replace(os.sep, '/')
filenames.append(name)
@@ -55,13 +55,13 @@ if __name__ == "__main__":
args = parser.parse_args(sys.argv[1:])
args.output.write(\
-"""<?xml version=1.0 encoding=UTF-8?>
-<gresources>
- <gresource prefix="/org/webkitgtk/inspector">
+ """<?xml version=1.0 encoding=UTF-8?>
+ <gresources>
+ <gresource prefix="/org/webkitgtk/inspector">
""")
for filename in get_filenames(args.filenames):
- line = ' <file'
+ line = ' <file'
if is_compressible(filename):
line += ' compressed="true"'
if 'Images/gtk/' in filename:
@@ -71,7 +71,7 @@ if __name__ == "__main__":
args.output.write(line)
args.output.write(\
-""" </gresource>
+ """ </gresource>
</gresources>
""")
diff --git a/Tools/gtk/gtkdoc.py b/Tools/gtk/gtkdoc.py
index 5aff6fc9b..48f862a31 100644
--- a/Tools/gtk/gtkdoc.py
+++ b/Tools/gtk/gtkdoc.py
@@ -141,7 +141,6 @@ class GTKDoc(object):
self._write_version_xml()
self._run_gtkdoc_scan()
self._run_gtkdoc_scangobj()
- self._run_gtkdoc_mktmpl()
self._run_gtkdoc_mkdb()
if not html:
@@ -185,7 +184,7 @@ class GTKDoc(object):
def _run_command(self, args, env=None, cwd=None, print_output=True, ignore_warnings=False):
if print_output:
- self.logger.info("Running %s", args[0])
+ self.logger.debug("Running %s", args[0])
self.logger.debug("Full command args: %s", str(args))
process = subprocess.Popen(args, env=env, cwd=cwd,
@@ -195,9 +194,15 @@ class GTKDoc(object):
if print_output:
if stdout:
- sys.stdout.write(stdout.encode("utf-8"))
+ try:
+ sys.stdout.write(stdout.encode("utf-8"))
+ except UnicodeDecodeError:
+ sys.stdout.write(stdout)
if stderr:
- sys.stderr.write(stderr.encode("utf-8"))
+ try:
+ sys.stderr.write(stderr.encode("utf-8"))
+ except UnicodeDecodeError:
+ sys.stderr.write(stderr)
if process.returncode != 0:
raise Exception('%s produced a non-zero return code %i'
@@ -238,14 +243,14 @@ class GTKDoc(object):
copy_file_replacing_existing(os.path.join(src, path),
os.path.join(dest, path))
- self.logger.info('Copying template files to output directory...')
+ self.logger.debug('Copying template files to output directory...')
self._create_directory_if_nonexistent(self.output_dir)
copy_all_files_in_directory(self.doc_dir, self.output_dir)
if not html:
return
- self.logger.info('Copying HTML files to output directory...')
+ self.logger.debug('Copying HTML files to output directory...')
html_src_dir = os.path.join(self.doc_dir, 'html')
html_dest_dir = os.path.join(self.output_dir, 'html')
self._create_directory_if_nonexistent(html_dest_dir)
@@ -307,7 +312,11 @@ class GTKDoc(object):
env = os.environ
ldflags = self.ldflags
if self.library_path:
- ldflags = ' "-L%s" ' % self.library_path + ldflags
+ additional_ldflags = ''
+ for arg in env.get('LDFLAGS', '').split(' '):
+ if arg.startswith('-L'):
+ additional_ldflags = '%s %s' % (additional_ldflags, arg)
+ ldflags = ' "-L%s" %s ' % (self.library_path, additional_ldflags) + ldflags
current_ld_library_path = env.get('LD_LIBRARY_PATH')
if current_ld_library_path:
env['RUN'] = 'LD_LIBRARY_PATH="%s:%s" ' % (self.library_path, current_ld_library_path)
@@ -328,10 +337,6 @@ class GTKDoc(object):
self._run_command(['gtkdoc-scangobj', '--module=%s' % self.module_name],
env=env, cwd=self.output_dir)
- def _run_gtkdoc_mktmpl(self):
- args = ['gtkdoc-mktmpl', '--module=%s' % self.module_name]
- self._run_command(args, cwd=self.output_dir)
-
def _run_gtkdoc_mkdb(self):
sgml_file = os.path.join(self.output_dir, self.main_sgml_file)
self._raise_exception_if_file_inaccessible(sgml_file)
@@ -373,6 +378,7 @@ class GTKDoc(object):
def _run_gtkdoc_fixxref(self):
args = ['gtkdoc-fixxref',
+ '--module=%s' % self.module_name,
'--module-dir=html',
'--html-dir=html']
args.extend(['--extra-dir=%s' % extra_dir for extra_dir in self.cross_reference_deps])
diff --git a/Tools/gtk/install-dependencies b/Tools/gtk/install-dependencies
new file mode 100755
index 000000000..71582b729
--- /dev/null
+++ b/Tools/gtk/install-dependencies
@@ -0,0 +1,479 @@
+#!/bin/bash
+
+# This script needs to be run with root rights.
+if [ $UID -ne 0 ]; then
+ sudo $0
+ exit 0
+fi
+
+function printNotSupportedMessageAndExit() {
+ echo
+ echo "Currently this script only works for distributions supporting apt-get and yum."
+ echo "Please add support for your distribution: http://webkit.org/b/110693"
+ echo
+ exit 1
+}
+
+function checkInstaller {
+ # apt-get - Debian based distributions
+ apt-get --version &> /dev/null
+ if [ $? -eq 0 ]; then
+ installDependenciesWithApt
+ exit 0
+ fi
+
+ # dnf - Fedora
+ dnf --version &> /dev/null
+ if [ $? -eq 0 ]; then
+ installDependenciesWithDnf
+ exit 0
+ fi
+
+ # pacman - Arch Linux
+ # pacman --version and pacman --help both return non-0
+ pacman -Ss &> /dev/null
+ if [ $? -eq 0 ]; then
+ installDependenciesWithPacman
+ exit 0
+ fi
+
+ if [ `uname` -eq "Darwin" ]; then
+ installDependenciesWithBrew
+ exit 0
+ fi
+
+ printNotSupportedMessageAndExit
+}
+
+function installDependenciesWithBrew {
+ brew &> /dev/null
+ if [ $? -gt 1 ]; then
+ echo "Please install HomeBrew. Instructions on http://brew.sh"
+ exit 1
+ fi
+
+ brew install autoconf \
+ automake \
+ bison \
+ cmake \
+ enchant \
+ flex \
+ gettext \
+ gobject-introspection \
+ intltool \
+ itstool \
+ libcroco \
+ libgcrypt \
+ libgpg-error \
+ libtiff \
+ libtool \
+ ninja \
+ pango \
+ pkg-config \
+ sqlite \
+ webp \
+ xz
+}
+
+# If the package $1 is available, prints it. Otherwise prints $2.
+# Useful for handling when a package is renamed on new versions of Debian/Ubuntu.
+function aptIfElse {
+ if apt-cache show $1 &>/dev/null; then
+ echo $1
+ else
+ echo $2
+ fi
+}
+
+function installDependenciesWithApt {
+ # These are dependencies necessary for building WebKitGTK+.
+ packages=" \
+ autoconf \
+ automake \
+ autopoint \
+ autotools-dev \
+ bison \
+ cmake \
+ flex \
+ gawk \
+ geoclue-2.0 \
+ gnome-common \
+ gperf \
+ gtk-doc-tools \
+ intltool \
+ itstool \
+ libatk1.0-dev \
+ libedit-dev \
+ libenchant-dev \
+ libfaad-dev \
+ $(aptIfElse libgcrypt20-dev libgcrypt11-dev) \
+ $(aptIfElse libgeoclue-2-dev libgeoclue-dev) \
+ libgirepository1.0-dev \
+ libgl1-mesa-dev \
+ libgl1-mesa-glx \
+ libgtk2.0-dev \
+ libgtk-3-dev \
+ libgstreamer1.0-dev \
+ libgstreamer-plugins-base1.0-dev \
+ libgudev-1.0-dev \
+ libhyphen-dev \
+ libjpeg-dev \
+ libmpg123-dev \
+ libnotify-dev \
+ libopus-dev \
+ libpango1.0-dev \
+ $(aptIfElse libpng-dev libpng12-dev) \
+ libpulse-dev \
+ librsvg2-dev \
+ libsecret-1-dev \
+ libsoup2.4-dev \
+ libsqlite3-dev \
+ libtheora-dev \
+ libtool \
+ libvorbis-dev \
+ libwebp-dev \
+ libxcomposite-dev \
+ libxt-dev \
+ libxtst-dev \
+ libxslt1-dev \
+ libwayland-dev \
+ ninja-build \
+ patch \
+ ruby \
+ xfonts-utils"
+
+ # These are dependencies necessary for running tests.
+ packages="$packages \
+ apache2 \
+ curl \
+ dbus-x11 \
+ gdb \
+ libapache2-mod-bw \
+ $(aptIfElse libapache2-mod-php7.0 libapache2-mod-php5) \
+ libgpg-error-dev \
+ psmisc \
+ pulseaudio-utils \
+ python-gi \
+ python-psutil \
+ ruby \
+ ruby-json \
+ ruby-highline \
+ weston \
+ xvfb"
+
+ # These are dependencies necessary for building the jhbuild.
+ packages="$packages \
+ git \
+ gobject-introspection \
+ gsettings-desktop-schemas-dev \
+ icon-naming-utils \
+ libcroco3-dev \
+ libdrm-dev \
+ libegl1-mesa-dev \
+ libepoxy-dev \
+ libevdev-dev \
+ libexpat1-dev \
+ libgbm-dev \
+ libgles2-mesa-dev \
+ libgnutls28-dev \
+ libgpg-error-dev \
+ libjson-glib-dev \
+ libinput-dev \
+ libmtdev-dev \
+ libp11-kit-dev \
+ libpciaccess-dev \
+ libproxy-dev \
+ libssl-dev \
+ libtiff5-dev \
+ libv4l-dev \
+ libxcb-composite0-dev \
+ libxcb-xfixes0-dev \
+ $(aptIfElse libxfont1-dev libxfont-dev) \
+ libxkbfile-dev \
+ libtool-bin \
+ libudev-dev \
+ python-dev \
+ ragel \
+ x11proto-bigreqs-dev \
+ x11proto-composite-dev \
+ x11proto-gl-dev \
+ x11proto-input-dev \
+ x11proto-randr-dev \
+ x11proto-resource-dev \
+ x11proto-scrnsaver-dev \
+ x11proto-video-dev \
+ x11proto-xcmisc-dev \
+ x11proto-xf86dri-dev \
+ xfonts-utils \
+ xtrans-dev \
+ xutils-dev \
+ yasm"
+
+ # These are dependencies necessary for using webkit-patch
+ packages="$packages \
+ git-svn \
+ subversion"
+
+ apt-get install $packages
+}
+
+function installDependenciesWithPacman {
+ # These are dependencies necessary for building WebKitGTK+.
+ packages=" \
+ autoconf \
+ automake \
+ bison \
+ cmake \
+ libedit \
+ file \
+ findutils \
+ flex \
+ gawk \
+ gcc \
+ gettext \
+ gnome-common \
+ gperf \
+ grep \
+ groff \
+ gstreamer \
+ gst-plugins-base-libs \
+ gzip \
+ hyphen \
+ libtool \
+ m4 \
+ make \
+ patch \
+ pkg-config \
+ sed \
+ texinfo \
+ util-linux \
+ which \
+ gtk-doc \
+ intltool \
+ itstool \
+ atk \
+ enchant \
+ faad2 \
+ geoclue \
+ gobject-introspection \
+ mesa \
+ mesa-libgl \
+ gtk2 \
+ gtk3 \
+ libsystemd \
+ libjpeg-turbo \
+ mpg123 \
+ opus \
+ pango \
+ libgcrypt \
+ libnotify \
+ libpng \
+ libpulse \
+ librsvg \
+ libsecret \
+ libsoup \
+ sqlite \
+ libtheora \
+ libtool \
+ libvorbis \
+ libwebp \
+ libxcomposite \
+ libxt \
+ libxslt \
+ libxtst \
+ ninja \
+ ruby \
+ xorg-font-utils \
+ wayland"
+
+ # These are dependencies necessary for running tests.
+ # Note: apache-mod_bw is available in the AUR, but the main repos
+ # could not find ruby-json
+ packages="$packages \
+ apache \
+ curl \
+ gdb \
+ hunspell \
+ hunspell-en \
+ php-apache \
+ libgpg-error \
+ psmisc \
+ pulseaudio \
+ python-gobject \
+ python2-psutil \
+ ruby \
+ ruby-highline \
+ weston \
+ xorg-server-xvfb"
+
+ # These are dependencies necessary for building the jhbuild.
+ # Note: Could not find libegl-mesa
+ packages="$packages \
+ expat \
+ git \
+ gnutls \
+ gobject-introspection \
+ gsettings-desktop-schemas \
+ icon-naming-utils \
+ libcroco \
+ libdrm \
+ libepoxy \
+ libevdev \
+ libgpg-error \
+ libinput \
+ p11-kit \
+ libpciaccess \
+ libproxy \
+ libtiff \
+ libxfixes \
+ libxfont \
+ libxcb \
+ libxkbfile \
+ mtdev \
+ python2 \
+ python2-lxml \
+ ragel \
+ bigreqsproto \
+ compositeproto \
+ glproto \
+ inputproto \
+ randrproto \
+ resourceproto \
+ scrnsaverproto \
+ videoproto \
+ xcmiscproto \
+ xf86driproto \
+ xorg-font-utils \
+ xorg-util-macros \
+ xtrans \
+ xorg-utils \
+ yasm"
+
+ # These are dependencies necessary for using webkit-patch
+ packages="$packages \
+ svn"
+ pacman -S --needed $packages
+
+ echo "You will also need to follow the instructions on the Arch Wiki to make"
+ echo "'python' call python2 in the webkit folder"
+ echo "https://wiki.archlinux.org/index.php/Python#Dealing_with_version_problem_in_build_scripts"
+}
+
+function installDependenciesWithDnf {
+ # These are dependencies necessary for building WebKitGTK+.
+ packages=" \
+ atk-devel \
+ autoconf \
+ automake \
+ bison \
+ cairo-devel \
+ cmake \
+ enchant-devel \
+ flex \
+ gcc-c++ \
+ geoclue2-devel \
+ gettext-devel \
+ gobject-introspection-devel \
+ gperf \
+ gstreamer1-devel \
+ gstreamer1-plugins-base-devel \
+ gtk-doc \
+ gtk2-devel \
+ gtk3-devel \
+ hyphen-devel \
+ intltool \
+ json-glib-devel \
+ libXt-devel \
+ libXtst-devel \
+ libxslt-devel \
+ libedit-devel \
+ libgcrypt-devel \
+ libgudev1-devel \
+ libjpeg-turbo-devel \
+ libnotify-devel \
+ libpng-devel \
+ libsecret-devel \
+ libsoup-devel \
+ libv4l-devel \
+ libwebp-devel \
+ libwayland-client-devel \
+ libwayland-server-devel \
+ mesa-libGL-devel \
+ ninja-build \
+ openssl-devel \
+ patch \
+ pcre-devel \
+ perl-Switch \
+ perl-version \
+ pulseaudio-libs-devel \
+ python-devel \
+ redhat-rpm-config \
+ ruby \
+ sqlite-devel"
+
+ # These are dependencies necessary for running tests.
+ packages="$packages \
+ curl \
+ dbus-x11 \
+ gdb \
+ hunspell-en \
+ httpd \
+ libgpg-error-devel \
+ mod_bw \
+ mod_ssl \
+ perl-CGI \
+ php \
+ psmisc \
+ pulseaudio-utils \
+ pygobject3-base \
+ python2-psutil \
+ ruby \
+ rubygem-json \
+ rubygem-highline \
+ weston-devel \
+ xorg-x11-server-Xvfb"
+
+ # These are dependencies necessary for building the jhbuild.
+ packages="$packages \
+ expat-devel \
+ docbook-utils \
+ docbook-utils-pdf \
+ git \
+ gobject-introspection \
+ gnutls-devel \
+ gsettings-desktop-schemas-devel \
+ icon-naming-utils \
+ itstool \
+ libXfont-devel \
+ libcroco-devel \
+ libdrm-devel \
+ libepoxy-devel \
+ libevdev-devel
+ libgpg-error-devel \
+ libinput-devel \
+ libp11-devel \
+ libpciaccess-devel \
+ libproxy-devel \
+ libtiff-devel \
+ libxcb-devel \
+ libxkbfile-devel \
+ mesa-libEGL-devel \
+ mtdev-devel \
+ ragel \
+ systemd-devel \
+ xorg-x11-font-utils \
+ xorg-x11-proto-devel \
+ xorg-x11-util-macros \
+ xorg-x11-xtrans-devel \
+ yasm"
+
+ # These are dependencies necessary for using webkit-patch
+ packages="$packages
+ git-svn \
+ subversion"
+
+ dnf install $packages
+}
+
+checkInstaller
+
diff --git a/Tools/gtk/jhbuild.modules b/Tools/gtk/jhbuild.modules
new file mode 100644
index 000000000..e7762fac8
--- /dev/null
+++ b/Tools/gtk/jhbuild.modules
@@ -0,0 +1,628 @@
+<?xml version="1.0"?>
+<!DOCTYPE moduleset SYSTEM "moduleset.dtd">
+<?xml-stylesheet type="text/xsl" href="moduleset.xsl"?>
+<moduleset>
+
+ <metamodule id="webkitgtk-testing-dependencies">
+ <dependencies>
+ <dep package="cairo"/>
+ <dep package="fonts"/>
+ <dep package="dicts"/>
+ <dep package="fontconfig"/>
+ <dep package="freetype6"/>
+ <dep package="harfbuzz"/>
+ <dep package="libxml2"/>
+ <dep package="libxslt"/>
+ <dep package="gdk-pixbuf"/>
+ <dep package="gtk+"/>
+ <dep package="glib"/>
+ <dep package="glib-networking"/>
+ <dep package="gnome-icon-theme"/>
+ <dep package="gnome-icon-theme-symbolic"/>
+ <dep package="gnome-themes-standard"/>
+ <dep package="gtk-doc"/>
+ <dep package="icu"/>
+ <dep package="libsoup"/>
+ <dep package="atk"/>
+ <dep package="gstreamer"/>
+ <dep package="gst-plugins-base"/>
+ <dep package="gst-plugins-good"/>
+ <dep package="gst-plugins-bad"/>
+ <dep package="gst-libav"/>
+ <dep package="openwebrtc"/>
+ <dep package="llvm"/>
+ <dep package="shared-mime-info"/>
+ <if condition-set="linux">
+ <dep package="xserver"/>
+ <dep package="mesa"/>
+ <dep package="at-spi2-core"/>
+ <dep package="at-spi2-atk"/>
+ <dep package="weston"/>
+ </if>
+ <if condition-set="macos">
+ <dep package="gsettings-desktop-schemas"/>
+ </if>
+ </dependencies>
+ </metamodule>
+
+ <!-- Please use http/https to access repositories to be friendly to users stuck behind firewalls. -->
+ <repository type="git" name="github.com"
+ href="https://github.com"/>
+ <repository type="tarball" name="github-tarball"
+ href="https://github.com/"/>
+ <repository type="tarball" name="sourceware.org-mirror"
+ href="http://mirrors.kernel.org/sources.redhat.com/"/>
+ <repository type="tarball" name="ftp.gnome.org"
+ href="http://ftp.gnome.org"/>
+ <repository type="git" name="git.gnome.org"
+ href="https://git.gnome.org/browse/"/>
+ <repository type="tarball" name="cairographics.org"
+ href="http://cairographics.org"/>
+ <repository type="tarball" name="freedesktop.org"
+ href="http://www.freedesktop.org"/>
+ <repository type="tarball" name="xorg"
+ href="http://xorg.freedesktop.org"/>
+ <repository type="tarball" name="xmlsoft.org"
+ href="http://xmlsoft.org"/>
+ <repository type="tarball" name="gstreamer"
+ href="http://gstreamer.freedesktop.org/src/"/>
+ <repository type="tarball" name="savannah.gnu.org"
+ href="http://download.savannah.gnu.org/releases/"/>
+ <repository type="git" name="freedesktop-git"
+ href="http://anongit.freedesktop.org/git"/>
+ <repository type="tarball" name="dri.freedesktop.org"
+ href="http://dri.freedesktop.org"/>
+ <repository type="tarball" name="people.freedesktop.org"
+ href="http://people.freedesktop.org"/>
+ <repository type="tarball" name="wayland.freedesktop.org"
+ href="http://wayland.freedesktop.org"/>
+ <repository type="tarball" name="llvm.org"
+ href="http://llvm.org"/>
+ <repository type="tarball" name="webkitgtk-jhbuild-mirror"
+ href="http://webkitgtk.org/jhbuild_mirror/"/>
+
+ <autotools id="cairo">
+ <if condition-set="linux">
+ <autogenargs value="--enable-gl=yes --enable-egl=yes --enable-glx=yes"/>
+ </if>
+ <if condition-set="macos">
+ <autogenargs value="ac_cv_func_rsvg_pixbuf_from_file=no --disable-lto"/>
+ </if>
+ <dependencies>
+ <dep package="fontconfig"/>
+ <dep package="pixman"/>
+ <dep package="glib"/>
+ </dependencies>
+ <branch module="releases/cairo-1.14.2.tar.xz" version="1.14.2"
+ repo="cairographics.org"
+ hash="sha1:c8da68aa66ca0855b5d0ff552766d3e8679e1d24"/>
+ </autotools>
+
+ <!-- FIXME: Pixman 0.32.6 isn't buildable with Clang, but disable-mmx option fixes
+ the build. This workaround can be removed once the original bug is fixed.
+ Details can be found here: https://bugs.webkit.org/show_bug.cgi?id=151441 -->
+ <!-- FIXME: Pixman 0.32.6 ARM iwMMXt fast path isn't buildable with GCC 4.9 and
+ ARM traditional instruction set. It causes a build failure on Raspbian.
+ This workaround can be removed once we raise the minimum GCC version
+ for WebKitGTK+ above 4.9 -->
+ <autotools id="pixman" autogen-sh="configure"
+ autogenargs="--enable-gtk=no --disable-mmx --disable-arm-iwmmxt">
+ <branch module="releases/pixman-0.32.6.tar.gz" version="0.32.6"
+ repo="cairographics.org"
+ hash="sha256:3dfed13b8060eadabf0a4945c7045b7793cc7e3e910e748a8bb0f0dc3e794904"
+ md5sum="3a30859719a41bd0f5cccffbfefdd4c2">
+ </branch>
+ </autotools>
+
+ <autotools id="fonts" supports-non-srcdir-builds="no"
+ skip-autogen="true">
+ <branch repo="github.com" module="mrobinson/webkitgtk-test-fonts.git" checkoutdir="webkitgtk-test-fonts" tag="0.0.5"/>
+ </autotools>
+
+ <autotools id="dicts" supports-non-srcdir-builds="no"
+ skip-autogen="true">
+ <branch repo="github.com" module="mrobinson/webkitgtk-test-dicts.git" checkoutdir="webkitgtk-test-dicts" tag="0.0.1"/>
+ </autotools>
+
+ <autotools id="freetype6" autogen-sh="configure">
+ <branch module="freetype/freetype-2.4.11.tar.bz2" version="2.4.11"
+ repo="savannah.gnu.org"
+ hash="sha256:ef9d0bcb64647d9e5125dc7534d7ca371c98310fec87677c410f397f71ffbe3f"
+ md5sum="b93435488942486c8d0ca22e8f768034">
+ <patch file="freetype6-2.4.11-truetype-font-height-fix.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="harfbuzz" autogen-sh="configure">
+ <dependencies>
+ <dep package="icu"/>
+ </dependencies>
+ <branch module="software/harfbuzz/release/harfbuzz-1.3.3.tar.bz2"
+ version="1.3.3"
+ checkoutdir="harfbuzz-1.3.3"
+ repo="freedesktop.org"
+ hash="sha256:2620987115a4122b47321610dccbcc18f7f121115fd7b88dc8a695c8b66cb3c9"
+ md5sum="97ae15a72a93f1f27324a2b8d9bd3b1d">
+ </branch>
+ </autotools>
+
+ <autotools id="libffi" autogen-sh="configure">
+ <branch module="libffi/libffi-3.1.tar.gz" version="3.1"
+ repo="sourceware.org-mirror"
+ hash="sha256:97feeeadca5e21870fa4433bc953d1b3af3f698d5df8a428f68b73cd60aef6eb"
+ md5sum="f5898b29bbfd70502831a212d9249d10"/>
+ </autotools>
+
+ <autotools id="gdk-pixbuf" autogen-sh="configure"
+ autogenargs="--disable-introspection">
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/gdk-pixbuf/2.30/gdk-pixbuf-2.30.8.tar.xz" version="2.30.8"
+ repo="ftp.gnome.org"
+ hash="sha256:4853830616113db4435837992c0aebd94cbb993c44dc55063cee7f72a7bef8be"/>
+ </autotools>
+
+ <autotools id="librsvg" autogen-sh="configure"
+ autogenargs="--disable-introspection --enable-pixbuf-loader --disable-gtk-theme">
+ <if condition-set="macos">
+ <autogenargs value="--disable-Bsymbolic"/>
+ </if>
+ <dependencies>
+ <dep package="gdk-pixbuf"/>
+ <dep package="glib"/>
+ <dep package="cairo"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/librsvg/2.36/librsvg-2.36.1.tar.xz" version="2.36.1"
+ repo="ftp.gnome.org"
+ hash="sha256:786b95e1a091375c5ef2997a21c69ff24d7077afeff18197355f54d9dcbcd8c5"
+ md5sum="89d483f30a7c77245b7ee02faaea5a5a">
+ <patch file="librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="gtk+" autogen-sh="configure"
+ autogenargs="--disable-introspection">
+ <if condition-set="macos">
+ <autogenargs value="--enable-x11-backend=no --enable-quartz-backend" />
+ <makeargs value="-j1" />
+ </if>
+ <dependencies>
+ <dep package="glib"/>
+ <dep package="cairo"/>
+ <dep package="atk"/>
+ <if condition-set="linux">
+ <dep package="at-spi2-atk"/>
+ <dep package="wayland"/>
+ </if>
+ <dep package="gdk-pixbuf"/>
+ <dep package="pango"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/gtk+/3.16/gtk+-3.16.4.tar.xz" version="3.16.4"
+ repo="ftp.gnome.org"
+ hash="sha256:1ee5dbd7a4cb81a91eaa1b7ae64ba5a3eab6a3c0a764155583ab96524590fc8e">
+ <patch file="gtk+-configure-fix-detecting-CUPS-2.x.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="glib"
+ autogen-sh="configure"
+ autogenargs="--disable-dtrace">
+ <dependencies>
+ <dep package="libffi"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/glib/2.44/glib-2.44.1.tar.xz" version="2.44.1"
+ repo="ftp.gnome.org"
+ hash="sha256:8811deacaf8a503d0a9b701777ea079ca6a4277be10e3d730d2112735d5eca07">
+ <patch file="glib-warning-fix.patch" strip="1"/>
+ <patch file="gdate-suppress-string-format-literal-warning.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="glib-networking">
+ <if condition-set="macos">
+ <autogenargs value="--with-ca-certificates='/usr/local/etc/openssl/cert.pem' --without-pkcs11"/>
+ </if>
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/glib-networking/2.41/glib-networking-2.41.4.tar.xz" version="2.41.4"
+ repo="ftp.gnome.org"
+ hash="sha256:930ad618865dcf81765d0f48cb6f13e22d76203efa59d30604aed0384ce80fd7"
+ md5sum="f88e163322c0834f9781d6224771ab2e"/>
+ </autotools>
+
+ <autotools id="libsoup"
+ autogenargs="--without-gnome --disable-introspection">
+ <if condition-set="macos">
+ <autogenargs value="--disable-tls-check"/>
+ </if>
+ <dependencies>
+ <dep package="glib-networking"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/libsoup/2.57/libsoup-2.57.1.tar.xz" version="2.57.1"
+ repo="ftp.gnome.org"
+ hash="sha256:ca1ca037e89e8bc7b782559f3ec5d89c9d0b836f505b2f95e008ed517fd6658f">
+ <patch file="libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch" strip="1"/>
+ <patch file="libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="fontconfig"
+ autogen-sh="configure"
+ autogenargs="--enable-libxml2">
+ <if condition-set="macos">
+ <autogenargs value="--with-add-fonts=/System/Library/Fonts,/Library/Fonts,~/Library/Fonts"/>
+ </if>
+ <dependencies>
+ <dep package="freetype6"/>
+ <dep package="libxml2"/>
+ </dependencies>
+ <branch module="software/fontconfig/release/fontconfig-2.11.1.tar.gz" version="2.11.1"
+ repo="freedesktop.org"
+ hash="sha256:b6b066c7dce3f436fdc0dfbae9d36122b38094f4f53bd8dffd45e195b0540d8d"
+ md5sum="e75e303b4f7756c2b16203a57ac87eba">
+ <patch file="fontconfig-fix-osx-cache.diff" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="gnome-icon-theme" autogen-sh="configure">
+ <dependencies>
+ <dep package="gtk+"/>
+ </dependencies>
+ <branch module="pub/GNOME/sources/gnome-icon-theme/3.2/gnome-icon-theme-3.2.1.tar.xz" version="3.2.1"
+ repo="ftp.gnome.org"
+ hash="sha256:a7f0a8b17e91ac338fdbc01ac59a8738e9c1e201de492c070d43aacf291a8959"
+ md5sum="40be1e5a6eae11181311a6fc432cf892">
+ </branch>
+ </autotools>
+
+ <autotools id="gnome-icon-theme-symbolic" supports-non-srcdir-builds="no" autogen-sh="configure">
+ <dependencies>
+ <dep package="gtk+"/>
+ </dependencies>
+ <branch module="pub/GNOME/sources/gnome-icon-theme-symbolic/3.2/gnome-icon-theme-symbolic-3.2.1.tar.xz" version="3.2.1"
+ repo="ftp.gnome.org"
+ hash="sha256:a558af2f87f761f00421f49c1addd2149b70228158e09327fa861219ac1a63cb"
+ md5sum="94137d3c256f2cc80298a9bef15d68c4">
+ </branch>
+ </autotools>
+
+ <autotools id="gnome-themes-standard" autogen-sh="configure">
+ <dependencies>
+ <dep package="gtk+"/>
+ <dep package="librsvg"/>
+ </dependencies>
+ <branch module="pub/GNOME/sources/gnome-themes-standard/3.6/gnome-themes-standard-3.6.0.tar.xz" version="3.6.0"
+ repo="ftp.gnome.org"
+ hash="sha256:d832fd38f7659f470df5ddc52131a59f989c75f3a70f8b3a514f89d90d4f43ec">
+ </branch>
+ </autotools>
+
+ <autotools id="atk"
+ autogen-sh="configure"
+ autogenargs="--disable-introspection">
+ <branch module="pub/GNOME/sources/atk/2.15/atk-2.15.4.tar.xz" version="2.15.4"
+ repo="ftp.gnome.org"
+ hash="sha256:0dddfa73a02178ca21a8de172c86d699aa887b4efeec736b4c8721eee4ac349c"/>
+ </autotools>
+
+ <autotools id="at-spi2-core"
+ autogenargs="--disable-introspection">
+ <branch module="pub/GNOME/sources/at-spi2-core/2.15/at-spi2-core-2.15.4.tar.xz" version="2.15.4"
+ repo="ftp.gnome.org"
+ hash="sha256:0e3b01af6ba06d98faf7b85891ece394897fe145b0760b7846e810b57f1b809f">
+ </branch>
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="at-spi2-atk">
+ <branch module="pub/GNOME/sources/at-spi2-atk/2.15/at-spi2-atk-2.15.4.tar.xz" version="2.15.4"
+ repo="ftp.gnome.org"
+ hash="sha256:3283aa5207b81e4c77d24c4e8b1c0abe6c850b11a2e62cd873cc07af0b403501">
+ </branch>
+ <dependencies>
+ <dep package="glib"/>
+ <dep package="atk"/>
+ <dep package="at-spi2-core"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="libxml2" supports-non-srcdir-builds="no"
+ autogen-sh="./autogen.sh; ./configure --with-python=no">
+ <branch module="/sources/libxml2-2.9.1.tar.gz" version="2.9.1"
+ repo="xmlsoft.org"
+ hash="sha256:fd3c64cb66f2c4ea27e934d275904d92cec494a8e8405613780cbc8a71680fdb"
+ md5sum="9c0cfef285d5c4a5c80d00904ddab380"/>
+ </autotools>
+
+ <autotools id="libxslt">
+ <branch module="/sources/libxslt-${version}.tar.gz" version="1.1.29"
+ repo="xmlsoft.org"
+ hash="sha256:b5976e3857837e7617b29f2249ebb5eeac34e249208d31f1fbf7a6ba7a4090ce"/>
+ <dependencies>
+ <dep package="libxml2"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="orc" autogenargs="--disable-gtk-doc" autogen-sh="configure">
+ <branch module="orc/orc-0.4.17.tar.gz" version="0.4.17"
+ repo="gstreamer"
+ hash="sha256:4fc7cca48c59fff23afee78fb642cdbde001f56401c8f47b95a16578d1d5d7e8"
+ md5sum="af1bf3dab9e69f3c36f389285e2a12a1"/>
+ </autotools>
+
+ <autotools id="gstreamer" autogen-sh="configure" autogenargs="--disable-gtk-doc">
+ <if condition-set="macos">
+ <autogenargs value="--disable-introspection"/>
+ </if>
+ <dependencies>
+ <dep package="orc"/>
+ </dependencies>
+ <branch module="gstreamer/gstreamer-${version}.tar.xz" version="1.8.0"
+ repo="gstreamer"
+ hash="sha256:947a314a212b5d94985d89b43440dbe66b696e12bbdf9a2f78967b98d74abedc"
+ md5sum="6846d7289ec323c38c49b818171e955a">
+ <patch file="gstreamer-0001-protection-added-function-to-filter-system-ids.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="gst-plugins-base"
+ autogen-sh="configure"
+ autogenargs="--disable-examples --disable-gtk-doc">
+ <if condition-set="macos">
+ <autogenargs value="--disable-introspection"/>
+ </if>
+ <dependencies>
+ <dep package="gstreamer"/>
+ </dependencies>
+ <branch module="gst-plugins-base/gst-plugins-base-${version}.tar.xz" version="1.8.0"
+ repo="gstreamer"
+ hash="sha256:abc0acc1d15b4b9c97c65cd9689bd6400081853b9980ea428d3c8572dd791522"
+ md5sum="20cc8231609318310f2a55f64c86cbb4"/>
+ </autotools>
+
+ <autotools id="gst-plugins-good" autogen-sh="configure" autogenargs="--disable-examples --disable-soup --disable-gtk-doc">
+ <if condition-set="macos">
+ <autogenargs value="--disable-introspection"/>
+ </if>
+ <dependencies>
+ <dep package="gst-plugins-base"/>
+ <dep package="libvpx"/>
+ </dependencies>
+
+ <branch module="gst-plugins-good/gst-plugins-good-${version}.tar.xz" version="1.8.0"
+ repo="gstreamer"
+ hash="sha256:c20c134d47dbc238d921707a3b66da709c2b4dd89f9d267cec13d1ddf16e9f4d"
+ md5sum="91ed4649c7c2e43a61f731d144f6f6d0">
+ <patch file="gst-plugins-good-use-the-tfdt-decode-time.patch" strip="1"/>
+ <patch file="gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch" strip="1"/>
+ <patch file="gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch" strip="1"/>
+ <patch file="gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch" strip="1"/>
+ <patch file="gst-plugins-good-0003-rtpbin-receive-bundle-support.patch" strip="1"/>
+ <patch file="gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="gst-plugins-bad" autogen-sh="configure" autogenargs="--disable-examples --disable-gtk-doc">
+ <if condition-set="macos">
+ <autogenargs value="--disable-introspection"/>
+ </if>
+ <dependencies>
+ <dep package="gst-plugins-base"/>
+ <dep package="openh264"/>
+ </dependencies>
+ <branch module="gst-plugins-bad/gst-plugins-bad-${version}.tar.xz" version="1.8.0"
+ repo="gstreamer"
+ hash="sha256:116376dd1085082422e0b21b0ecd3d1cb345c469c58e32463167d4675f4ca90e"
+ md5sum="1c2d797bb96a81e9ef570c7a0a37203e">
+ <patch file="gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch" strip="1"/>
+ <patch file="gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="gst-libav" autogen-sh="configure" autogenargs="--with-libav-extra-configure='--disable-yasm' --disable-gtk-doc">
+ <dependencies>
+ <dep package="gst-plugins-base"/>
+ </dependencies>
+ <branch module="gst-libav/gst-libav-${version}.tar.xz" version="1.8.0"
+ repo="gstreamer"
+ hash="sha256:5a1ce28876aee93cb4f3d090f0e807915a5d9bc1325e3480dd302b85aeb4291c"
+ md5sum="361638fa45466c5050bcde6bfe10fa46"/>
+ </autotools>
+
+ <autotools id="xserver" autogenargs="--disable-xinerama --enable-glx --enable-composite --disable-xorg --disable-dmx --disable-xnest --disable-xquartz --disable-xwin --disable-xephyr --disable-xfake --disable-xfbdev --disable-install-setuid --disable-unit-tests --disable-present --enable-unix-transport --enable-tcp-transport --disable-local-transport --with-xkb-path=/usr/share/X11/xkb --with-xkb-output=/var/lib/xkb --with-xkb-bin-directory=/usr/bin --without-dtrace">
+ <dependencies>
+ <dep package="pixman"/>
+ </dependencies>
+ <branch module="/releases/individual/xserver/xorg-server-1.16.4.tar.bz2" version="1.16.4"
+ repo="xorg"
+ hash="sha256:abb6e1cc9213a9915a121f48576ff6739a0b8cdb3d32796f9a7743c9a6efc871"
+ md5sum="80d140f631d862b76dc67ae983151c77">
+ <patch file="xserver-remove-bogus-dependencies.patch" strip="1"/>
+ <patch file="xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="wayland" autogenargs="--disable-documentation">
+ <pkg-config>wayland-server.pc</pkg-config>
+ <dependencies>
+ <dep package="libffi"/>
+ </dependencies>
+ <branch module="releases/wayland-1.8.1.tar.xz"
+ version="1.8.1"
+ repo="wayland.freedesktop.org"
+ hash="sha256:f17c938d1c24fd0a10f650a623a2775d329db3168b5732e498b08388ec776fc8"
+ md5sum="6e877877c3e04cfb865cfcd0733c9ab1">
+ </branch>
+ </autotools>
+
+ <autotools id="weston" autogenargs="--enable-x11-compositor --disable-rpi-compositor --disable-fbdev-compositor --disable-setuid-install --disable-ivi-shell --disable-weston-launch --with-cairo=gl">
+ <pkg-config>weston.pc</pkg-config>
+ <dependencies>
+ <dep package="wayland"/>
+ <dep package="libdrm"/>
+ <dep package="xserver"/>
+ <dep package="cairo"/>
+ <dep package="libinput"/>
+ </dependencies>
+ <branch module="releases/weston-1.8.0.tar.xz"
+ version="1.8.0"
+ repo="wayland.freedesktop.org"
+ hash="sha256:8963e69f328e815cec42c58046c4af721476c7541bb7d9edc71740fada5ad312"
+ md5sum="24cb8a7ed0535b4fc3642643988dab36">
+ </branch>
+ </autotools>
+
+ <autotools id="gtk-doc" autogen-sh="configure">
+ <if condition-set="macos">
+ <autogenargs value="--with-xml-catalog=/usr/local/etc/xml/catalog"/>
+ </if>
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/gtk-doc/${version}/gtk-doc-${version}.tar.xz" version="1.25"
+ repo="ftp.gnome.org"
+ hash="sha256:1ea46ed400e6501f975acaafea31479cea8f32f911dca4dff036f59e6464fd42"/>
+ </autotools>
+
+ <autotools id="libdrm" autogen-sh="configure">
+ <pkg-config>libdrm.pc</pkg-config>
+ <branch module="/libdrm/libdrm-2.4.65.tar.bz2" version="2.4.65"
+ repo="dri.freedesktop.org"
+ hash="sha256:71960ac8bde7d710992b1bc8879935e8300a870c36bd06f22412d0447e3d96c4"/>
+ </autotools>
+
+ <autotools id="mesa"
+ autogen-template="%(srcdir)s/%(autogen-sh)s --prefix %(prefix)s/softGL %(autogenargs)s"
+ autogenargs="--disable-dri3 --enable-dri --enable-glx --enable-egl --with-egl-platforms=x11,wayland --with-dri-drivers=swrast --with-gallium-drivers=swrast">
+ <!--- WARNING: At jhbuildrc, when we define the path to the Gallium llvmpipe software rasterizer (needed by XvfbDriver),
+ we assume that the directory is named "Mesa". So, don't change the checkoutdir name even if you update the version. -->
+ <branch module="/~brianp/mesa/older-versions/11.x/11.0.6/mesa-11.0.6.tar.xz" version="11.0.6"
+ checkoutdir="Mesa"
+ repo="people.freedesktop.org"
+ hash="sha256:8340e64cdc91999840404c211496f3de38e7b4cb38db34e2f72f1642c5134760">
+ </branch>
+ <dependencies>
+ <dep package="llvm"/>
+ <dep package="libdrm"/>
+ <dep package="wayland"/>
+ </dependencies>
+ </autotools>
+
+ <autotools id="libusrsctp" supports-non-srcdir-builds="no" autogen-sh="./bootstrap; ./configure --disable-warnings-as-errors">
+ <branch repo="github.com" module="sctplab/usrsctp.git" checkoutdir="usrsctp" tag="078ff3252f73327e0ac11d6fd5eff62011f6646e"/>
+ </autotools>
+
+ <autotools id="openh264" supports-non-srcdir-builds="no" autogen-sh="pseudo-configure">
+ <branch module="cisco/openh264/archive/v${version}.tar.gz" version="1.5.0"
+ checkoutdir="openh264-${version}" repo="github-tarball">
+ <patch file="openh264-configure.patch" strip="0"/>
+ </branch>
+ </autotools>
+
+ <autotools id="libvpx"
+ autogen-template="%(srcdir)s/configure --prefix=%(prefix)s --enable-pic --as=yasm --disable-unit-tests --size-limit=16384x16384 --enable-postproc --enable-multi-res-encoding --enable-temporal-denoising --enable-vp9-temporal-denoising --enable-vp9-postproc --enable-shared">
+ <branch repo="github.com" module="webmproject/libvpx.git" version="1.6.0" checkoutdir="libvpx-1.6.0">
+ </branch>
+ </autotools>
+
+ <autotools id="gst-plugins-openwebrtc" supports-parallel-builds="no" supports-non-srcdir-builds="no" autogen-sh="./autogen.sh; ./configure">
+ <dependencies>
+ <dep package="gst-plugins-base"/>
+ <dep package="libusrsctp"/>
+ </dependencies>
+ <branch repo="github.com" module="Igalia/openwebrtc-gst-plugins.git" checkoutdir="gst-plugins-openwebrtc" tag="9b2199ea970369dbf1d9ca2f8e61c95f21db2b6e"/>
+ </autotools>
+
+ <autotools id="libnice" supports-non-srcdir-builds="no">
+ <dependencies>
+ <dep package="gstreamer"/>
+ </dependencies>
+ <branch module="libnice/libnice/archive/${version}.tar.gz" version="2803a0b4b70af9684e05ef5ed3f0c2fbca4b6c93"
+ checkoutdir="libnice-${version}" repo="github-tarball">
+ <patch file="libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch" strip="1"/>
+ <patch file="libnice-0001-TURN-allow-REALM-to-be-empty.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="openwebrtc" autogenargs="--enable-bridge=no --enable-owr-gst=yes">
+ <dependencies>
+ <dep package="gst-plugins-openwebrtc"/>
+ <dep package="gst-plugins-bad"/>
+ <dep package="libnice"/>
+ </dependencies>
+ <branch repo="github.com" module="Igalia/openwebrtc.git" checkoutdir="openwebrtc" tag="7f3d23e034818893db198f4b56e41609abd8847b"/>
+ </autotools>
+
+ <autotools id="llvm"
+ autogenargs="--enable-optimized --disable-terminfo --disable-zlib --enable-targets=host --disable-backtraces --disable-crash-overrides --disable-expensive-checks --disable-debug-runtime --disable-assertions --enable-shared --enable-bindings=none">
+ <branch repo="llvm.org"
+ module="/releases/3.7.0/llvm-3.7.0.src.tar.xz" version="3.7.0" checkoutdir="llvm-3.7.0"
+ hash="sha256:ab45895f9dcdad1e140a3a79fd709f64b05ad7364e308c0e582c5b02e9cc3153"/>
+ </autotools>
+
+ <autotools id="gsettings-desktop-schemas" autogen-sh="configure">
+ <dependencies>
+ <dep package="glib"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/gsettings-desktop-schemas/3.16/gsettings-desktop-schemas-3.16.1.tar.xz" version="3.16.1"
+ repo="ftp.gnome.org"
+ hash="sha256:74fe9fdad510c8a6666febeceb7ebafc581ef990b3afcc8c1e8b5d90b24b3461">
+ </branch>
+ </autotools>
+
+ <autotools id="shared-mime-info"
+ autogenargs="--disable-default-make-check">
+ <dependencies>
+ <dep package="libxml2"/>
+ <dep package="glib"/>
+ </dependencies>
+ <branch module="/~hadess/shared-mime-info-${version}.tar.xz" version="1.5"
+ repo="freedesktop.org"
+ hash="sha256:d6412840eb265bf36e61fd7b6fc6bea21b0f58cb22bed16f2ccccdd54bea4180">
+ <patch file="shared-mime-info-xht-glob.patch" strip="1"/>
+ <patch file="shared-mime-info-xhtml-magic.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <autotools id="icu"
+ autogen-sh="./source/configure"
+ autogenargs="--disable-samples --enable-weak-threads">
+ <branch module="icu4c-55_1-src.tgz" version="55.1" checkoutdir="icu"
+ repo="webkitgtk-jhbuild-mirror"
+ hash="sha256:e16b22cbefdd354bec114541f7849a12f8fc2015320ca5282ee4fd787571457b">
+ <patch file="icudata-stdlibs.patch" strip="1"/>
+ </branch>
+ </autotools>
+
+ <!-- Dependencies listed below this point are not thought to affect test results, and are only
+ included because they themselves depend on other dependencies built by jhbuild. -->
+
+ <autotools id="pango" autogen-sh="configure"
+ autogenargs="--enable-cairo">
+ <dependencies>
+ <dep package="cairo"/>
+ <dep package="fontconfig"/>
+ </dependencies>
+ <branch module="/pub/GNOME/sources/pango/1.36/pango-1.36.8.tar.xz" version="1.36.8"
+ repo="ftp.gnome.org"
+ hash="sha256:18dbb51b8ae12bae0ab7a958e7cf3317c9acfc8a1e1103ec2f147164a0fc2d07">
+ </branch>
+ </autotools>
+
+ <!-- libinput is only included because the version of libinput shipped with Debian Jessie
+ os too old for building Weston 1.8. This may be removed after Debian Strech is released -->
+ <autotools id="libinput" autogen-sh="configure" autogenargs="--disable-libwacom --disable-tests --disable-documentation">
+ <pkg-config>libinput.pc</pkg-config>
+ <branch module="software/libinput/libinput-1.2.4.tar.xz"
+ version="1.2.4"
+ repo="freedesktop.org"
+ hash="sha256:aee3650ad2a864ab9a10e7e63df543cc2b475f6bf3974751037a2df325dabbb1"
+ md5sum="1cbaa34f04a336f2703906d564e0a37a">
+ </branch>
+ </autotools>
+
+</moduleset>
diff --git a/Tools/gtk/jhbuildrc b/Tools/gtk/jhbuildrc
new file mode 100644
index 000000000..3ed2c9da7
--- /dev/null
+++ b/Tools/gtk/jhbuildrc
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# Copyright (C) 2011-2014 Igalia S.L.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import sys
+import os
+
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), "../jhbuild") )
+import jhbuildrc_common
+jhbuildrc_common.init(globals(), "gtk")
+
+__gtk_tools_directory = os.path.abspath(os.path.dirname(__file__))
+sys.path = [__gtk_tools_directory] + sys.path
+import common
+
+# LLVM requires that builddir != srcdir, and it's not possible to do that in jhbuild only
+# for a module, so we do it here globally since it's a good idea for all other modules as well.
+buildroot = os.path.join(os.path.dirname(checkoutroot), "Build")
+
+# For the layout tests: path where llvmpipe/software-only mesa libraries are installed.
+os.environ['LLVMPIPE_LIBGL_PATH'] = os.path.abspath(os.path.join(prefix, 'softGL', 'lib'))
+
+# We only want to export this when bulding the JHBuild, but not when building WebKit.
+# When the build-webkit script is used, we end executing 'jhbuild [...] run cmake [...]'.
+# But when the JHBuild gets built, we end executing 'jhbuild [...] build'.
+# So we can know if we are building the JHBuild by checking that 'run' is not an argument.
+if 'run' not in sys.argv:
+ os.environ['CFLAGS'] = '-Wno-error -O2 -g1'
+ os.environ['CXXFLAGS'] = '-Wno-error -O2 -g1'
+ # For building gstreamer plugins on the Mac.
+ os.environ['OBJCFLAGS'] = '-Wno-error -O2 -g1'
diff --git a/Tools/gtk/make-dist.py b/Tools/gtk/make-dist.py
new file mode 100755
index 000000000..4f0c4d589
--- /dev/null
+++ b/Tools/gtk/make-dist.py
@@ -0,0 +1,333 @@
+#!/usr/bin/env python
+# Copyright (C) 2014 Igalia S.L.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from __future__ import print_function
+from contextlib import closing
+
+import argparse
+import errno
+import multiprocessing
+import os
+import re
+import shutil
+import subprocess
+import tarfile
+
+
+def enum(**enums):
+ return type('Enum', (), enums)
+
+
+class Rule(object):
+ Result = enum(INCLUDE=1, EXCLUDE=2, NO_MATCH=3)
+
+ def __init__(self, type, pattern):
+ self.type = type
+ self.original_pattern = pattern
+ self.pattern = re.compile(pattern)
+
+ def test(self, file):
+ if not(self.pattern.search(file)):
+ return Rule.Result.NO_MATCH
+ return self.type
+
+
+class Ruleset(object):
+ _global_rules = None
+
+ def __init__(self):
+ # By default, accept all files.
+ self.rules = [Rule(Rule.Result.INCLUDE, '.*')]
+
+ @classmethod
+ def global_rules(cls):
+ if not cls._global_rules:
+ cls._global_rules = Ruleset()
+ return cls._global_rules
+
+ @classmethod
+ def add_global_rule(cls, rule):
+ cls.global_rules().add_rule(rule)
+
+ def add_rule(self, rule):
+ self.rules.append(rule)
+
+ def passes(self, file):
+ allowed = False
+ for rule in self.rules:
+ result = rule.test(file)
+ if result == Rule.Result.NO_MATCH:
+ continue
+ allowed = Rule.Result.INCLUDE == result
+ return allowed
+
+
+class File(object):
+ def __init__(self, source_root, tarball_root):
+ self.source_root = source_root
+ self.tarball_root = tarball_root
+
+ def should_skip_file(self, path):
+ # Do not skip files explicitly added from the manifest.
+ return False
+
+ def get_files(self):
+ yield (self.source_root, self.tarball_root)
+
+
+class Directory(object):
+ def __init__(self, source_root, tarball_root):
+ self.source_root = source_root
+ self.tarball_root = tarball_root
+ self.rules = Ruleset()
+
+ self.files_in_version_control = self.list_files_in_version_control()
+
+ def add_rule(self, rule):
+ self.rules.add_rule(rule)
+
+ def get_tarball_path(self, filename):
+ return filename.replace(self.source_root, self.tarball_root, 1)
+
+ def list_files_in_version_control(self):
+ # FIXME: Only git is supported for now.
+ p = subprocess.Popen(['git', 'ls-tree', '-r', '--name-only', 'HEAD', self.source_root], stdout=subprocess.PIPE)
+ out = p.communicate()[0]
+ if not out:
+ return []
+ return out.rstrip('\n').split('\n')
+
+ def should_skip_file(self, path):
+ return path not in self.files_in_version_control
+
+ def get_files(self):
+ for root, dirs, files in os.walk(self.source_root):
+
+ def passes_all_rules(entry):
+ return Ruleset.global_rules().passes(entry) and self.rules.passes(entry)
+
+ to_keep = filter(passes_all_rules, dirs)
+ del dirs[:]
+ dirs.extend(to_keep)
+
+ for file in files:
+ file = os.path.join(root, file)
+ if not passes_all_rules(file):
+ continue
+ yield (file, self.get_tarball_path(file))
+
+
+class Manifest(object):
+ def __init__(self, manifest_filename, source_root, build_root, tarball_root='/'):
+ self.current_directory = None
+ self.directories = []
+ self.tarball_root = tarball_root
+ self.source_root = source_root
+ self.build_root = build_root
+
+ # Normalize the tarball root so that it starts and ends with a slash.
+ if not self.tarball_root.endswith('/'):
+ self.tarball_root = self.tarball_root + '/'
+ if not self.tarball_root.startswith('/'):
+ self.tarball_root = '/' + self.tarball_root
+
+ with open(manifest_filename, 'r') as file:
+ for line in file.readlines():
+ self.process_line(line)
+
+ def add_rule(self, rule):
+ if self.current_directory is not None:
+ self.current_directory.add_rule(rule)
+ else:
+ Ruleset.add_global_rule(rule)
+
+ def add_directory(self, directory):
+ self.current_directory = directory
+ self.directories.append(directory)
+
+ def get_full_source_path(self, source_path):
+ if not os.path.exists(source_path):
+ source_path = os.path.join(self.source_root, source_path)
+ if not os.path.exists(source_path):
+ raise Exception('Could not find directory %s' % source_path)
+ return source_path
+
+ def get_full_tarball_path(self, path):
+ return self.tarball_root + path
+
+ def get_source_and_tarball_paths_from_parts(self, parts):
+ full_source_path = self.get_full_source_path(parts[1])
+ if len(parts) > 2:
+ full_tarball_path = self.get_full_tarball_path(parts[2])
+ else:
+ full_tarball_path = self.get_full_tarball_path(parts[1])
+ return (full_source_path, full_tarball_path)
+
+ def process_line(self, line):
+ parts = line.split()
+ if not parts:
+ return
+ if parts[0].startswith("#"):
+ return
+
+ if parts[0] == "directory" and len(parts) > 1:
+ self.add_directory(Directory(*self.get_source_and_tarball_paths_from_parts(parts)))
+ elif parts[0] == "file" and len(parts) > 1:
+ self.add_directory(File(*self.get_source_and_tarball_paths_from_parts(parts)))
+ elif parts[0] == "exclude" and len(parts) > 1:
+ self.add_rule(Rule(Rule.Result.EXCLUDE, parts[1]))
+ elif parts[0] == "include" and len(parts) > 1:
+ self.add_rule(Rule(Rule.Result.INCLUDE, parts[1]))
+ else:
+ raise Exception('Line does not begin with a correct rule:\n\t' + line)
+
+ def should_skip_file(self, directory, filename):
+ # Only allow files that are not in version control when they are explicitly included in the manifest from the build dir.
+ if filename.startswith(self.build_root):
+ return False
+
+ return directory.should_skip_file(filename)
+
+ def get_files(self):
+ for directory in self.directories:
+ for file_tuple in directory.get_files():
+ if self.should_skip_file(directory, file_tuple[0]):
+ continue
+ yield file_tuple
+
+ def create_tarfile(self, output):
+ count = 0
+ for file_tuple in self.get_files():
+ count = count + 1
+
+ with closing(tarfile.open(output, 'w')) as tarball:
+ for i, (file_path, tarball_path) in enumerate(self.get_files(), start=1):
+ print('Tarring file {0} of {1}'.format(i, count).ljust(40), end='\r')
+ tarball.add(file_path, tarball_path)
+ print("Wrote {0}".format(output).ljust(40))
+
+
+class Distcheck(object):
+ BUILD_DIRECTORY_NAME = "_build"
+ INSTALL_DIRECTORY_NAME = "_install"
+
+ def __init__(self, source_root, build_root):
+ self.source_root = source_root
+ self.build_root = build_root
+
+ def extract_tarball(self, tarball_path):
+ with closing(tarfile.open(tarball_path, 'r')) as tarball:
+ tarball.extractall(self.build_root)
+
+ def configure(self, dist_dir, build_dir, install_dir, port):
+ def create_dir(directory, directory_type):
+ try:
+ os.mkdir(directory)
+ except OSError, e:
+ if e.errno != errno.EEXIST or not os.path.isdir(directory):
+ raise Exception("Could not create %s dir at %s: %s" % (directory_type, directory, str(e)))
+
+ create_dir(build_dir, "build")
+ create_dir(install_dir, "install")
+
+ command = ['cmake', '-DPORT=%s' % port, '-DCMAKE_INSTALL_PREFIX=%s' % install_dir, '-DCMAKE_BUILD_TYPE=Release', dist_dir]
+ subprocess.check_call(command, cwd=build_dir)
+
+ def build(self, build_dir):
+ command = ['make']
+ make_args = os.getenv('MAKE_ARGS')
+ if make_args:
+ command.extend(make_args.split(' '))
+ else:
+ command.append('-j%d' % multiprocessing.cpu_count())
+ subprocess.check_call(command, cwd=build_dir)
+
+ def install(self, build_dir):
+ subprocess.check_call(['make', 'install'], cwd=build_dir)
+
+ def clean(self, dist_dir):
+ shutil.rmtree(dist_dir)
+
+ def check(self, tarball, port):
+ tarball_name, ext = os.path.splitext(os.path.basename(tarball))
+ dist_dir = os.path.join(self.build_root, tarball_name)
+ build_dir = os.path.join(dist_dir, self.BUILD_DIRECTORY_NAME)
+ install_dir = os.path.join(dist_dir, self.INSTALL_DIRECTORY_NAME)
+
+ self.extract_tarball(tarball)
+ self.configure(dist_dir, build_dir, install_dir, port)
+ self.build(build_dir)
+ self.install(build_dir)
+ self.clean(dist_dir)
+
+if __name__ == "__main__":
+ class FilePathAction(argparse.Action):
+ def __call__(self, parser, namespace, values, option_string=None):
+ setattr(namespace, self.dest, os.path.abspath(values))
+
+ def ensure_version_if_possible(arguments):
+ if arguments.version is not None:
+ return
+
+ pkgconfig_file = os.path.join(arguments.build_dir, "Source/WebKit2/webkit2gtk-4.0.pc")
+ if os.path.isfile(pkgconfig_file):
+ p = subprocess.Popen(['pkg-config', '--modversion', pkgconfig_file], stdout=subprocess.PIPE)
+ version = p.communicate()[0]
+ if version:
+ arguments.version = version.rstrip('\n')
+
+
+ def get_tarball_root_and_output_filename_from_arguments(arguments):
+ tarball_root = arguments.tarball_name
+ if arguments.version is not None:
+ tarball_root += '-' + arguments.version
+
+ output_filename = os.path.join(arguments.build_dir, tarball_root + ".tar")
+ return tarball_root, output_filename
+
+ parser = argparse.ArgumentParser(description='Build a distribution bundle.')
+ parser.add_argument('-c', '--check', action='store_true',
+ help='Check the tarball')
+ parser.add_argument('-s', '--source-dir', type=str, action=FilePathAction, default=os.getcwd(),
+ help='The top-level directory of the source distribution. ' + \
+ 'Directory for relative paths. Defaults to current directory.')
+ parser.add_argument('--version', type=str, default=None,
+ help='The version of the tarball to generate')
+ parser.add_argument('-b', '--build-dir', type=str, action=FilePathAction, default=os.getcwd(),
+ help='The top-level path of directory of the build root. ' + \
+ 'By default is the current directory.')
+ parser.add_argument('-t', '--tarball-name', type=str, default='webkitgtk',
+ help='Base name of tarball. Defaults to "webkitgtk".')
+ parser.add_argument('-p', '--port', type=str, default='GTK',
+ help='Port to be built in tarball check. Defaults to "GTK".')
+ parser.add_argument('manifest_filename', metavar="manifest", type=str, action=FilePathAction, help='The path to the manifest file.')
+
+ arguments = parser.parse_args()
+
+ # Paths in the manifest are relative to the source directory, and this script assumes that
+ # current working directory is the source directory, so change the current working directory
+ # to be the source directory.
+ os.chdir(arguments.source_dir)
+
+ ensure_version_if_possible(arguments)
+ tarball_root, output_filename = get_tarball_root_and_output_filename_from_arguments(arguments)
+
+ manifest = Manifest(arguments.manifest_filename, arguments.source_dir, arguments.build_dir, tarball_root)
+ manifest.create_tarfile(output_filename)
+
+ if arguments.check:
+ Distcheck(arguments.source_dir, arguments.build_dir).check(output_filename, arguments.port)
diff --git a/Tools/gtk/manifest.txt.in b/Tools/gtk/manifest.txt.in
new file mode 100644
index 000000000..09531e39e
--- /dev/null
+++ b/Tools/gtk/manifest.txt.in
@@ -0,0 +1,106 @@
+# Global rules
+exclude #$
+exclude ChangeLog
+exclude CMakeLists.txt.user
+exclude Makefile
+exclude PlatformAppleWin.cmake
+exclude PlatformEfl.cmake
+exclude PlatformMac.cmake
+exclude PlatformWin.cmake
+exclude PlatformWinCairo.cmake
+exclude tags$
+exclude ~$
+exclude \.#$
+exclude \.bak$
+exclude \.cproject$
+exclude \.git$
+exclude \.gitattributes$
+exclude \.gitignore$
+exclude \.icns$
+exclude \.lproj$
+exclude \.m$
+exclude \.mm$
+exclude \.nib$
+exclude \.o$
+exclude \.order$
+exclude \.orig$
+exclude \.pdf$
+exclude \.plist$
+exclude \.project$
+exclude \.props$
+exclude \.pyc$
+exclude \.pyo$
+exclude \.rej$
+exclude \.rtf$
+exclude \.sb$
+exclude \.sb\.in$
+exclude \.settings$
+exclude \.svn$
+exclude \.sw[a-p]$
+exclude \.vcxproj$
+exclude \.xib$
+exclude \.xcconfig$
+exclude \.xcodeproj$
+
+# Exclude directories from other ports
+exclude .*\/(Configurations|mac|ios|cf|cg|cocoa|Cocoa|objc|avfoundation|ca|curl|efl|win)\/.*$
+
+directory Source
+exclude Source/JavaScriptCore/tests
+exclude Source/ThirdParty/libwebrtc
+exclude Source/ThirdParty/qunit
+exclude Source/WebCore/platform/audio/resources
+exclude Source/WebCore/bindings/scripts/test
+exclude Source/WebCore/platform/efl/DefaultTheme
+exclude Source/WebCore/Resources
+exclude Source/WebKit/.*
+exclude Source/cmake/EFLHelpers.cmake$
+exclude Source/cmake/OptionsWinCairo.cmake$
+exclude Source/cmake/OptionsWindows.cmake$
+exclude Source/cmake/OptionsAppleWin.cmake$
+exclude Source/cmake/OptionsEfl.cmake$
+exclude Source/cmake/eflsymbols.filter$
+exclude Source/WebInspectorUI/Tools
+exclude Source/WebInspectorUI/UserInterface/Images
+
+exclude Source/WebKit2/Resources
+exclude Source/WebKit2/gtk/NEWS$
+
+# We do want to include the NEWS, but we want it to be in the root of the archive.
+file Source/WebKit2/gtk/NEWS NEWS
+
+directory Source/WebInspectorUI/UserInterface/Images/gtk
+file Source/WebCore/English.lproj/mediaControlsLocalizedStrings.js Source/WebCore/English.lproj/mediaControlsLocalizedStrings.js
+file Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
+
+# Include only the resources we actually build
+file Source/WebCore/Resources/missingImage.png
+file Source/WebCore/Resources/missingImage@2x.png
+file Source/WebCore/Resources/panIcon.png
+file Source/WebCore/Resources/plugIns.js
+file Source/WebCore/Resources/textAreaResizeCorner.png
+file Source/WebCore/Resources/textAreaResizeCorner@2x.png
+file Source/WebCore/Resources/urlIcon.png
+file Source/WebCore/platform/audio/resources/Composite.wav
+
+directory Tools/gtk
+directory Tools/ImageDiff
+directory Tools/MiniBrowser
+directory Tools/TestWebKitAPI
+
+directory Tools/DumpRenderTree
+exclude Tools/DumpRenderTree/fonts
+
+directory Tools/WebKitTestRunner
+exclude Tools/WebKitTestRunner/fonts/
+
+file CMakeLists.txt
+file Tools/CMakeLists.txt
+file Tools/Scripts/VCSUtils.pm
+file Tools/Scripts/run-gtk-tests
+file Tools/Scripts/webkit-build-directory
+file Tools/Scripts/webkitdirs.pm
+file Tools/jhbuild/jhbuildutils.py
+
+directory ${CMAKE_BINARY_DIR}/Documentation/webkit2gtk-${WEBKITGTK_API_VERSION}/html Documentation/webkit2gtk-${WEBKITGTK_API_VERSION}/html
+directory ${CMAKE_BINARY_DIR}/Documentation/webkitdomgtk-${WEBKITGTK_API_VERSION}/html Documentation/webkitdomgtk-${WEBKITGTK_API_VERSION}/html
diff --git a/Tools/gtk/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch b/Tools/gtk/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch
new file mode 100644
index 000000000..b4e0a541d
--- /dev/null
+++ b/Tools/gtk/patches/fontconfig-C-11-requires-a-space-between-literal-and-identifier.patch
@@ -0,0 +1,30 @@
+From 7069d717e982adcf8e1d300cbd10eec6322a65c9 Mon Sep 17 00:00:00 2001
+From: Akira TAGOH <akira@tagoh.org>
+Date: Sun, 22 Apr 2012 21:40:44 +0900
+Subject: [PATCH] C++11 requires a space between literal and identifier
+
+Reported by Buganini
+---
+ fontconfig/fontconfig.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
+index 0e2ca50..b27ccb5 100644
+--- a/fontconfig/fontconfig.h
++++ b/fontconfig/fontconfig.h
+@@ -112,9 +112,9 @@ typedef int FcBool;
+ #define FC_DECORATIVE "decorative" /* Bool - true if style is a decorative variant */
+ #define FC_LCD_FILTER "lcdfilter" /* Int */
+
+-#define FC_CACHE_SUFFIX ".cache-"FC_CACHE_VERSION
+-#define FC_DIR_CACHE_FILE "fonts.cache-"FC_CACHE_VERSION
+-#define FC_USER_CACHE_FILE ".fonts.cache-"FC_CACHE_VERSION
++#define FC_CACHE_SUFFIX ".cache-" FC_CACHE_VERSION
++#define FC_DIR_CACHE_FILE "fonts.cache-" FC_CACHE_VERSION
++#define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION
+
+ /* Adjust outline rasterizer */
+ #define FC_CHAR_WIDTH "charwidth" /* Int */
+--
+1.8.3.2
+
diff --git a/Tools/gtk/patches/fontconfig-fix-osx-cache.diff b/Tools/gtk/patches/fontconfig-fix-osx-cache.diff
new file mode 100644
index 000000000..2c71bc83a
--- /dev/null
+++ b/Tools/gtk/patches/fontconfig-fix-osx-cache.diff
@@ -0,0 +1,207 @@
+diff --git a/fc-cache/fc-cache.c b/fc-cache/fc-cache.c
+index 99e0e9f..bf3b6b4 100644
+--- a/fc-cache/fc-cache.c
++++ b/fc-cache/fc-cache.c
+@@ -187,13 +187,8 @@ scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force,
+
+ if (!cache)
+ {
+- if (!recursive)
+- cache = FcDirCacheRescan (dir, config);
+- else
+- {
+- (*changed)++;
+- cache = FcDirCacheRead (dir, FcTrue, config);
+- }
++ (*changed)++;
++ cache = FcDirCacheRead (dir, FcTrue, config);
+ if (!cache)
+ {
+ fprintf (stderr, "%s: error scanning\n", dir);
+@@ -391,7 +386,6 @@ main (int argc, char **argv)
+ ret += scanDirs (list, config, FcTrue, really_force, verbose, FcFalse, &changed, NULL);
+ FcStrListDone (list);
+ }
+- FcStrSetDestroy (updateDirs);
+
+ /*
+ * Try to create CACHEDIR.TAG anyway.
+diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
+index 2258251..d0b4e9e 100644
+--- a/fontconfig/fontconfig.h
++++ b/fontconfig/fontconfig.h
+@@ -541,9 +541,6 @@ FcDirSave (FcFontSet *set, FcStrSet *dirs, const FcChar8 *dir);
+
+ FcPublic FcCache *
+ FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file);
+-
+-FcPublic FcCache *
+-FcDirCacheRescan (const FcChar8 *dir, FcConfig *config);
+
+ FcPublic FcCache *
+ FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config);
+diff --git a/src/fccache.c b/src/fccache.c
+index 5173e0b..10eacff 100644
+--- a/src/fccache.c
++++ b/src/fccache.c
+@@ -828,19 +828,6 @@ bail1:
+ return NULL;
+ }
+
+-FcCache *
+-FcDirCacheRebuild (FcCache *cache, struct stat *dir_stat, FcStrSet *dirs)
+-{
+- FcCache *new;
+- FcFontSet *set = FcFontSetDeserialize (FcCacheSet (cache));
+- const FcChar8 *dir = FcCacheDir (cache);
+-
+- new = FcDirCacheBuild (set, dir, dir_stat, dirs);
+- FcFontSetDestroy (set);
+-
+- return new;
+-}
+-
+ /* write serialized state to the cache file */
+ FcBool
+ FcDirCacheWrite (FcCache *cache, FcConfig *config)
+diff --git a/src/fcdir.c b/src/fcdir.c
+index 3bcd0b8..b040a28 100644
+--- a/src/fcdir.c
++++ b/src/fcdir.c
+@@ -130,12 +130,7 @@ FcFileScanConfig (FcFontSet *set,
+ if (FcFileIsDir (file))
+ return FcStrSetAdd (dirs, file);
+ else
+- {
+- if (set)
+- return FcFileScanFontConfig (set, blanks, file, config);
+- else
+- return FcTrue;
+- }
++ return FcFileScanFontConfig (set, blanks, file, config);
+ }
+
+ FcBool
+@@ -311,45 +306,6 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
+ return cache;
+ }
+
+-FcCache *
+-FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
+-{
+- FcCache *cache = FcDirCacheLoad (dir, config, NULL);
+- FcCache *new = NULL;
+- struct stat dir_stat;
+- FcStrSet *dirs;
+-
+- if (!cache)
+- return NULL;
+- if (FcStatChecksum (dir, &dir_stat) < 0)
+- goto bail;
+- dirs = FcStrSetCreate ();
+- if (!dirs)
+- goto bail;
+-
+- /*
+- * Scan the dir
+- */
+- if (!FcDirScanConfig (NULL, dirs, NULL, dir, FcTrue, config))
+- goto bail1;
+- /*
+- * Rebuild the cache object
+- */
+- new = FcDirCacheRebuild (cache, &dir_stat, dirs);
+- if (!new)
+- goto bail1;
+- FcDirCacheUnload (cache);
+- /*
+- * Write out the cache file, ignoring any troubles
+- */
+- FcDirCacheWrite (new, config);
+-
+-bail1:
+- FcStrSetDestroy (dirs);
+-bail:
+- return new;
+-}
+-
+ /*
+ * Read (or construct) the cache for a directory
+ */
+diff --git a/src/fcfs.c b/src/fcfs.c
+index 21c6c7c..941abba 100644
+--- a/src/fcfs.c
++++ b/src/fcfs.c
+@@ -122,28 +122,6 @@ FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s)
+
+ return s_serialize;
+ }
+-
+-FcFontSet *
+-FcFontSetDeserialize (const FcFontSet *set)
+-{
+- int i;
+- FcFontSet *new = FcFontSetCreate ();
+-
+- if (!new)
+- return NULL;
+- for (i = 0; i < set->nfont; i++)
+- {
+- if (!FcFontSetAdd (new, FcPatternDuplicate (FcFontSetFont (set, i))))
+- goto bail;
+- }
+-
+- return new;
+-bail:
+- FcFontSetDestroy (new);
+-
+- return NULL;
+-}
+-
+ #define __fcfs__
+ #include "fcaliastail.h"
+ #undef __fcfs__
+diff --git a/src/fcint.h b/src/fcint.h
+index cdf2dab..362ea6f 100644
+--- a/src/fcint.h
++++ b/src/fcint.h
+@@ -567,9 +567,6 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config);
+ FcPrivate FcCache *
+ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcStrSet *dirs);
+
+-FcPrivate FcCache *
+-FcDirCacheRebuild (FcCache *cache, struct stat *dir_stat, FcStrSet *dirs);
+-
+ FcPrivate FcBool
+ FcDirCacheWrite (FcCache *cache, FcConfig *config);
+
+@@ -841,9 +838,6 @@ FcFontSetSerializeAlloc (FcSerialize *serialize, const FcFontSet *s);
+ FcPrivate FcFontSet *
+ FcFontSetSerialize (FcSerialize *serialize, const FcFontSet * s);
+
+-FcPrivate FcFontSet *
+-FcFontSetDeserialize (const FcFontSet *set);
+-
+ /* fchash.c */
+ FcPrivate FcChar8 *
+ FcHashGetSHA256Digest (const FcChar8 *input_strings,
+diff --git a/src/fcpat.c b/src/fcpat.c
+index 986cca3..0614ac2 100644
+--- a/src/fcpat.c
++++ b/src/fcpat.c
+@@ -33,7 +33,6 @@ FcPatternCreate (void)
+ p = (FcPattern *) malloc (sizeof (FcPattern));
+ if (!p)
+ return 0;
+- memset (p, 0, sizeof (FcPattern));
+ p->num = 0;
+ p->size = 0;
+ p->elts_offset = FcPtrToOffset (p, NULL);
+@@ -1311,7 +1310,6 @@ FcValueListSerialize (FcSerialize *serialize, const FcValueList *vl)
+ }
+ return head_serialized;
+ }
+-
+ #define __fcpat__
+ #include "fcaliastail.h"
+ #include "fcftaliastail.h" \ No newline at end of file
diff --git a/Tools/gtk/patches/freetype6-2.4.11-truetype-font-height-fix.patch b/Tools/gtk/patches/freetype6-2.4.11-truetype-font-height-fix.patch
new file mode 100644
index 000000000..0ffe76b4e
--- /dev/null
+++ b/Tools/gtk/patches/freetype6-2.4.11-truetype-font-height-fix.patch
@@ -0,0 +1,39 @@
+From e0469372be3870a5ad60b2c4586e9c281357bd28 Mon Sep 17 00:00:00 2001
+From: Werner Lemberg <wl@gnu.org>
+Date: Tue, 22 Jan 2013 10:07:07 +0000
+Subject: [truetype] Fix font height.
+
+* src/truetype/ttobjs.c (tt_size_reset): The Windows rendering
+engine uses rounded values of the ascender and descender to compute
+the TrueType font height.
+---
+diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
+index c61b218..590b66c 100644
+--- a/src/truetype/ttobjs.c
++++ b/src/truetype/ttobjs.c
+@@ -4,7 +4,7 @@
+ /* */
+ /* Objects manager (body). */
+ /* */
+-/* Copyright 1996-2012 */
++/* Copyright 1996-2013 */
+ /* David Turner, Robert Wilhelm, and Werner Lemberg. */
+ /* */
+ /* This file is part of the FreeType project, and may only be used, */
+@@ -1177,11 +1177,12 @@
+ FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
+ metrics->descender =
+ FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
+- metrics->height =
+- FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
+ metrics->max_advance =
+ FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
+ metrics->x_scale ) );
++
++ /* the height is derived from rounded values */
++ metrics->height = metrics->ascender - metrics->descender;
+ }
+
+ /* compute new transformation */
+--
+cgit v0.9.0.2
diff --git a/Tools/gtk/patches/gdate-suppress-string-format-literal-warning.patch b/Tools/gtk/patches/gdate-suppress-string-format-literal-warning.patch
new file mode 100644
index 000000000..90cb951a1
--- /dev/null
+++ b/Tools/gtk/patches/gdate-suppress-string-format-literal-warning.patch
@@ -0,0 +1,29 @@
+From 3a7efd598d39366c2c9de0def2fdfb35e5e9f2a1 Mon Sep 17 00:00:00 2001
+From: coypu <coypu@sdf.org>
+Date: Mon, 8 Feb 2016 00:06:06 +0200
+Subject: [PATCH 1/1] gdate: Suppress string format literal warning
+
+Newer versions of GCC emit an error here, but we know it's safe.
+https://bugzilla.gnome.org/761550
+---
+ glib/gdate.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/glib/gdate.c b/glib/gdate.c
+index 4aece02..cdc735c 100644
+--- a/glib/gdate.c
++++ b/glib/gdate.c
+@@ -2494,7 +2494,10 @@ g_date_strftime (gchar *s,
+ * recognize whether strftime actually failed or just returned "".
+ */
+ tmpbuf[0] = '\1';
++ #pragma GCC diagnostic push
++ #pragma GCC diagnostic ignored "-Wformat-nonliteral"
+ tmplen = strftime (tmpbuf, tmpbufsize, locale_format, &tm);
++ #pragma GCC diagnostic pop
+
+ if (tmplen == 0 && tmpbuf[0] != '\0')
+ {
+--
+2.7.0
+
diff --git a/Tools/gtk/patches/glib-warning-fix.patch b/Tools/gtk/patches/glib-warning-fix.patch
new file mode 100644
index 000000000..8faf4d11f
--- /dev/null
+++ b/Tools/gtk/patches/glib-warning-fix.patch
@@ -0,0 +1,34 @@
+From 9f90ee5eeccd47f39c7a03dcd786b125a19c195d Mon Sep 17 00:00:00 2001
+From: Michael Catanzaro <mcatanzaro@gnome.org>
+Date: Sat, 13 Jun 2015 22:52:33 -0500
+Subject: [PATCH] genmarshal: silence register storage class warnings
+
+Using the register keyword triggers warnings on noteworthy compilers
+(clang), since it's deprecated in C++ and at danger of being removed
+from the language. There is no reason to use it since it isn't 1980
+anymore.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=750918
+---
+ gobject/glib-genmarshal.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gobject/glib-genmarshal.c b/gobject/glib-genmarshal.c
+index be4151a..ca78a6f 100644
+--- a/gobject/glib-genmarshal.c
++++ b/gobject/glib-genmarshal.c
+@@ -412,9 +412,9 @@ generate_marshal (const gchar *signame,
+ g_fprintf (fout, "%s%s data2);\n", indent (ind), pad ("gpointer"));
+
+ /* cfile marshal variables */
+- g_fprintf (fout, " register GMarshalFunc_%s callback;\n", signame);
+- g_fprintf (fout, " register GCClosure *cc = (GCClosure*) closure;\n");
+- g_fprintf (fout, " register gpointer data1, data2;\n");
++ g_fprintf (fout, " GMarshalFunc_%s callback;\n", signame);
++ g_fprintf (fout, " GCClosure *cc = (GCClosure*) closure;\n");
++ g_fprintf (fout, " gpointer data1, data2;\n");
+ if (sig->rarg->setter)
+ g_fprintf (fout, " %s v_return;\n", sig->rarg->ctype);
+
+--
+2.4.2 \ No newline at end of file
diff --git a/Tools/gtk/patches/gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch b/Tools/gtk/patches/gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch
new file mode 100644
index 000000000..5d1064ed5
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-bad-0001-dtls-port-to-OpenSSL-1.1.0.patch
@@ -0,0 +1,236 @@
+From e938933167c494cdca443334f658b02a03c4486b Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <dueno@redhat.com>
+Date: Wed, 26 Oct 2016 14:51:01 +0200
+Subject: [PATCH] dtls: port to OpenSSL 1.1.0
+
+Changes are:
+
+- Use the wrapper functions to access opaque data types. To preserve
+ backward compatibility, define fallback definitions
+
+- Remove the use of idiom "pqueue_size(ssl->d1->sent_messages)", since
+ there is no replacement
+
+- Use RSA_generate_key_ex instead of the deprecated RSA_generate_key
+
+https://bugzilla.gnome.org/show_bug.cgi?id=773540
+---
+ ext/dtls/gstdtlscertificate.c | 15 ++++++++
+ ext/dtls/gstdtlsconnection.c | 87 ++++++++++++++++++++++++++++++++++++++-----
+ 2 files changed, 93 insertions(+), 9 deletions(-)
+
+diff --git a/ext/dtls/gstdtlscertificate.c b/ext/dtls/gstdtlscertificate.c
+index 95fbb83..c1c9602 100644
+--- a/ext/dtls/gstdtlscertificate.c
++++ b/ext/dtls/gstdtlscertificate.c
+@@ -199,7 +199,22 @@ init_generated (GstDtlsCertificate * self)
+ priv->private_key = NULL;
+ return;
+ }
++
++ /* XXX: RSA_generate_key is actually deprecated in 0.9.8 */
++#if OPENSSL_VERSION_NUMBER < 0x10100001L
+ rsa = RSA_generate_key (2048, RSA_F4, NULL, NULL);
++#else
++ rsa = RSA_new ();
++ if (rsa != NULL) {
++ BIGNUM *e = BN_new ();
++ if (e != NULL && BN_set_word (e, RSA_F4)
++ && RSA_generate_key_ex (rsa, 2048, e, NULL)) {
++ RSA_free (rsa);
++ rsa = NULL;
++ }
++ BN_free (e);
++ }
++#endif
+
+ if (!rsa) {
+ GST_WARNING_OBJECT (self, "failed to generate RSA");
+diff --git a/ext/dtls/gstdtlsconnection.c b/ext/dtls/gstdtlsconnection.c
+index 36f6d63..728f5a7 100644
+--- a/ext/dtls/gstdtlsconnection.c
++++ b/ext/dtls/gstdtlsconnection.c
+@@ -42,6 +42,8 @@
+ #include <openssl/err.h>
+ #include <openssl/ssl.h>
+
++#include <string.h>
++
+ GST_DEBUG_CATEGORY_STATIC (gst_dtls_connection_debug);
+ #define GST_CAT_DEFAULT gst_dtls_connection_debug
+ G_DEFINE_TYPE_WITH_CODE (GstDtlsConnection, gst_dtls_connection, G_TYPE_OBJECT,
+@@ -216,6 +218,38 @@ gst_dtls_connection_finalize (GObject * gobject)
+ G_OBJECT_CLASS (gst_dtls_connection_parent_class)->finalize (gobject);
+ }
+
++#if OPENSSL_VERSION_NUMBER < 0x10100001L
++static void
++BIO_set_data (BIO * bio, void *ptr)
++{
++ bio->ptr = ptr;
++}
++
++static void *
++BIO_get_data (BIO * bio)
++{
++ return bio->ptr;
++}
++
++static void
++BIO_set_shutdown (BIO * bio, int shutdown)
++{
++ bio->shutdown = shutdown;
++}
++
++static void
++BIO_set_init (BIO * bio, int init)
++{
++ bio->init = init;
++}
++
++static X509 *
++X509_STORE_CTX_get0_cert (X509_STORE_CTX * ctx)
++{
++ return ctx->cert;
++}
++#endif
++
+ static void
+ gst_dtls_connection_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+@@ -239,7 +273,7 @@ gst_dtls_connection_set_property (GObject * object, guint prop_id,
+ priv->bio = BIO_new (BIO_s_gst_dtls_connection ());
+ g_return_if_fail (priv->bio);
+
+- priv->bio->ptr = self;
++ BIO_set_data (priv->bio, self);
+ SSL_set_bio (priv->ssl, priv->bio, priv->bio);
+
+ SSL_set_verify (priv->ssl,
+@@ -573,6 +607,7 @@ log_state (GstDtlsConnection * self, const gchar * str)
+ states |= (! !SSL_want_write (priv->ssl) << 20);
+ states |= (! !SSL_want_read (priv->ssl) << 24);
+
++#if OPENSSL_VERSION_NUMBER < 0x10100001L
+ GST_LOG_OBJECT (self, "%s: role=%s buf=(%d,%p:%d/%d) %x|%x %s",
+ str,
+ priv->is_client ? "client" : "server",
+@@ -581,6 +616,15 @@ log_state (GstDtlsConnection * self, const gchar * str)
+ priv->bio_buffer_offset,
+ priv->bio_buffer_len,
+ states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
++#else
++ GST_LOG_OBJECT (self, "%s: role=%s buf=(%p:%d/%d) %x|%x %s",
++ str,
++ priv->is_client ? "client" : "server",
++ priv->bio_buffer,
++ priv->bio_buffer_offset,
++ priv->bio_buffer_len,
++ states, SSL_get_state (priv->ssl), SSL_state_string_long (priv->ssl));
++#endif
+ }
+
+ static void
+@@ -737,7 +781,7 @@ openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx)
+ self = SSL_get_ex_data (ssl, connection_ex_index);
+ g_return_val_if_fail (GST_IS_DTLS_CONNECTION (self), FALSE);
+
+- pem = _gst_dtls_x509_to_pem (x509_ctx->cert);
++ pem = _gst_dtls_x509_to_pem (X509_STORE_CTX_get0_cert (x509_ctx));
+
+ if (!pem) {
+ GST_WARNING_OBJECT (self,
+@@ -749,7 +793,8 @@ openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx)
+ gint len;
+
+ len =
+- X509_NAME_print_ex (bio, X509_get_subject_name (x509_ctx->cert), 1,
++ X509_NAME_print_ex (bio,
++ X509_get_subject_name (X509_STORE_CTX_get0_cert (x509_ctx)), 1,
+ XN_FLAG_MULTILINE);
+ BIO_read (bio, buffer, len);
+ buffer[len] = '\0';
+@@ -777,6 +822,7 @@ openssl_verify_callback (int preverify_ok, X509_STORE_CTX * x509_ctx)
+ ######## #### #######
+ */
+
++#if OPENSSL_VERSION_NUMBER < 0x10100001L
+ static BIO_METHOD custom_bio_methods = {
+ BIO_TYPE_BIO,
+ "stream",
+@@ -795,11 +841,34 @@ BIO_s_gst_dtls_connection (void)
+ {
+ return &custom_bio_methods;
+ }
++#else
++static BIO_METHOD *custom_bio_methods;
++
++static BIO_METHOD *
++BIO_s_gst_dtls_connection (void)
++{
++ if (custom_bio_methods != NULL)
++ return custom_bio_methods;
++
++ custom_bio_methods = BIO_meth_new (BIO_TYPE_BIO, "stream");
++ if (custom_bio_methods == NULL
++ || !BIO_meth_set_write (custom_bio_methods, bio_method_write)
++ || !BIO_meth_set_read (custom_bio_methods, bio_method_read)
++ || !BIO_meth_set_ctrl (custom_bio_methods, bio_method_ctrl)
++ || !BIO_meth_set_create (custom_bio_methods, bio_method_new)
++ || !BIO_meth_set_destroy (custom_bio_methods, bio_method_free)) {
++ BIO_meth_free (custom_bio_methods);
++ return NULL;
++ }
++
++ return custom_bio_methods;
++}
++#endif
+
+ static int
+ bio_method_write (BIO * bio, const char *data, int size)
+ {
+- GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);
++ GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
+
+ GST_LOG_OBJECT (self, "BIO: writing %d", size);
+
+@@ -824,7 +893,7 @@ bio_method_write (BIO * bio, const char *data, int size)
+ static int
+ bio_method_read (BIO * bio, char *out_buffer, int size)
+ {
+- GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);
++ GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
+ GstDtlsConnectionPrivate *priv = self->priv;
+ guint internal_size;
+ gint copy_size;
+@@ -868,7 +937,7 @@ bio_method_read (BIO * bio, char *out_buffer, int size)
+ static long
+ bio_method_ctrl (BIO * bio, int cmd, long arg1, void *arg2)
+ {
+- GstDtlsConnection *self = GST_DTLS_CONNECTION (bio->ptr);
++ GstDtlsConnection *self = GST_DTLS_CONNECTION (BIO_get_data (bio));
+ GstDtlsConnectionPrivate *priv = self->priv;
+
+ switch (cmd) {
+@@ -916,8 +985,8 @@ bio_method_new (BIO * bio)
+ {
+ GST_LOG_OBJECT (NULL, "BIO: new");
+
+- bio->shutdown = 0;
+- bio->init = 1;
++ BIO_set_shutdown (bio, 0);
++ BIO_set_init (bio, 1);
+
+ return 1;
+ }
+@@ -930,6 +999,6 @@ bio_method_free (BIO * bio)
+ return 0;
+ }
+
+- GST_LOG_OBJECT (GST_DTLS_CONNECTION (bio->ptr), "BIO free");
++ GST_LOG_OBJECT (GST_DTLS_CONNECTION (BIO_get_data (bio)), "BIO free");
+ return 0;
+ }
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch b/Tools/gtk/patches/gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch
new file mode 100644
index 000000000..c66877370
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-bad-0002-dtlscertificate-Fix-error-checking-in-RSA_generate_k.patch
@@ -0,0 +1,37 @@
+From 3a069193e25364ebdacac86f4b03022c151ea29c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
+Date: Mon, 14 Nov 2016 11:32:17 +0200
+Subject: [PATCH] dtlscertificate: Fix error checking in RSA_generate_key_ex()
+ usage
+
+Was broken during the port for OpenSSL 1.1.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=774328
+---
+ ext/dtls/gstdtlscertificate.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/ext/dtls/gstdtlscertificate.c b/ext/dtls/gstdtlscertificate.c
+index c1c9602..c2d9bb2 100644
+--- a/ext/dtls/gstdtlscertificate.c
++++ b/ext/dtls/gstdtlscertificate.c
+@@ -207,12 +207,13 @@ init_generated (GstDtlsCertificate * self)
+ rsa = RSA_new ();
+ if (rsa != NULL) {
+ BIGNUM *e = BN_new ();
+- if (e != NULL && BN_set_word (e, RSA_F4)
+- && RSA_generate_key_ex (rsa, 2048, e, NULL)) {
++ if (e == NULL || !BN_set_word (e, RSA_F4)
++ || !RSA_generate_key_ex (rsa, 2048, e, NULL)) {
+ RSA_free (rsa);
+ rsa = NULL;
+ }
+- BN_free (e);
++ if (e)
++ BN_free (e);
+ }
+ #endif
+
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch b/Tools/gtk/patches/gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch
new file mode 100644
index 000000000..f0f90d104
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-0001-rtpbin-pipeline-gets-an-EOS-when-any-rtpsources-byes.patch
@@ -0,0 +1,156 @@
+From eeea2a7fe88a17b15318d5b6ae6e190b2f777030 Mon Sep 17 00:00:00 2001
+From: "Alejandro G. Castro" <alex@igalia.com>
+Date: Wed, 26 Oct 2016 13:21:29 +0200
+Subject: [PATCH] rtpbin: pipeline gets an EOS when any rtpsources byes
+
+Instead of sending EOS when a source byes we have to wait for
+all the sources to be gone, which means they already sent BYE and
+were removed from the session. We now handle the EOS in the rtcp
+loop checking the amount of sources in the session.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=773218
+---
+ gst/rtpmanager/gstrtpsession.c | 29 +++++++++++++++++++----------
+ gst/rtpmanager/rtpsession.c | 6 +-----
+ gst/rtpmanager/rtpsession.h | 3 +--
+ 3 files changed, 21 insertions(+), 17 deletions(-)
+
+diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c
+index 3688e85..fd1f2b1 100644
+--- a/gst/rtpmanager/gstrtpsession.c
++++ b/gst/rtpmanager/gstrtpsession.c
+@@ -293,7 +293,7 @@ static GstFlowReturn gst_rtp_session_process_rtp (RTPSession * sess,
+ static GstFlowReturn gst_rtp_session_send_rtp (RTPSession * sess,
+ RTPSource * src, gpointer data, gpointer user_data);
+ static GstFlowReturn gst_rtp_session_send_rtcp (RTPSession * sess,
+- RTPSource * src, GstBuffer * buffer, gboolean eos, gpointer user_data);
++ RTPSource * src, GstBuffer * buffer, gpointer user_data);
+ static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess,
+ GstBuffer * buffer, gpointer user_data);
+ static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
+@@ -1156,6 +1156,22 @@ rtcp_thread (GstRtpSession * rtpsession)
+ GST_RTP_SESSION_UNLOCK (rtpsession);
+ rtp_session_on_timeout (session, current_time, ntpnstime, running_time);
+ GST_RTP_SESSION_LOCK (rtpsession);
++
++ if (!rtp_session_get_num_sources (session)) {
++ /* when no sources left in the session, all of the them have went
++ * BYE at some point and removed, we can send EOS to the
++ * pipeline. */
++ GstPad *rtcp_src = rtpsession->send_rtcp_src;
++
++ if (rtcp_src) {
++ gst_object_ref (rtcp_src);
++ GST_LOG_OBJECT (rtpsession, "sending EOS");
++ GST_RTP_SESSION_UNLOCK (rtpsession);
++ gst_pad_push_event (rtpsession->send_rtcp_src, gst_event_new_eos ());
++ GST_RTP_SESSION_LOCK (rtpsession);
++ gst_object_unref (rtcp_src);
++ }
++ }
+ }
+ /* mark the thread as stopped now */
+ rtpsession->priv->thread_stopped = TRUE;
+@@ -1413,11 +1429,10 @@ do_rtcp_events (GstRtpSession * rtpsession, GstPad * srcpad)
+ }
+
+ /* called when the session manager has an RTCP packet ready for further
+- * sending. The eos flag is set when an EOS event should be sent downstream as
+- * well. */
++ * sending. */
+ static GstFlowReturn
+ gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src,
+- GstBuffer * buffer, gboolean eos, gpointer user_data)
++ GstBuffer * buffer, gpointer user_data)
+ {
+ GstFlowReturn result;
+ GstRtpSession *rtpsession;
+@@ -1440,11 +1455,6 @@ gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src,
+ GST_LOG_OBJECT (rtpsession, "sending RTCP");
+ result = gst_pad_push (rtcp_src, buffer);
+
+- /* we have to send EOS after this packet */
+- if (eos) {
+- GST_LOG_OBJECT (rtpsession, "sending EOS");
+- gst_pad_push_event (rtcp_src, gst_event_new_eos ());
+- }
+ gst_object_unref (rtcp_src);
+ } else {
+ GST_RTP_SESSION_UNLOCK (rtpsession);
+@@ -2056,7 +2066,6 @@ gst_rtp_session_event_send_rtcp_src (GstPad * pad, GstObject * parent,
+ return ret;
+ }
+
+-
+ static gboolean
+ gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstObject * parent,
+ GstEvent * event)
+diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c
+index 8b33b6b..aa8b40b 100644
+--- a/gst/rtpmanager/rtpsession.c
++++ b/gst/rtpmanager/rtpsession.c
+@@ -3263,7 +3263,6 @@ early_exit:
+ typedef struct
+ {
+ RTPSource *source;
+- gboolean is_bye;
+ GstBuffer *buffer;
+ } ReportOutput;
+
+@@ -3874,7 +3873,6 @@ static void
+ generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
+ {
+ RTPSession *sess = data->sess;
+- gboolean is_bye = FALSE;
+ ReportOutput *output;
+
+ /* only generate RTCP for active internal sources */
+@@ -3893,7 +3891,6 @@ generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
+ if (source->marked_bye) {
+ /* send BYE */
+ make_source_bye (sess, source, data);
+- is_bye = TRUE;
+ } else if (!data->is_early) {
+ /* loop over all known sources and add report blocks. If we are early, we
+ * just make a minimal RTCP packet and skip this step */
+@@ -3918,7 +3915,6 @@ generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
+
+ output = g_slice_new (ReportOutput);
+ output->source = g_object_ref (source);
+- output->is_bye = is_bye;
+ output->buffer = data->rtcp;
+ /* queue the RTCP packet to push later */
+ g_queue_push_tail (&data->output, output);
+@@ -4098,7 +4094,7 @@ done:
+ GST_DEBUG ("%p, sending RTCP packet, avg size %u, %u", &sess->stats,
+ sess->stats.avg_rtcp_packet_size, packet_size);
+ result =
+- sess->callbacks.send_rtcp (sess, source, buffer, output->is_bye,
++ sess->callbacks.send_rtcp (sess, source, buffer,
+ sess->send_rtcp_user_data);
+
+ RTP_SESSION_LOCK (sess);
+diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h
+index 9fa9327..c25981a 100644
+--- a/gst/rtpmanager/rtpsession.h
++++ b/gst/rtpmanager/rtpsession.h
+@@ -71,7 +71,6 @@ typedef GstFlowReturn (*RTPSessionSendRTP) (RTPSession *sess, RTPSource *src, gp
+ * @sess: an #RTPSession
+ * @src: the #RTPSource
+ * @buffer: the RTCP buffer ready for sending
+- * @eos: if an EOS event should be pushed
+ * @user_data: user data specified when registering
+ *
+ * This callback will be called when @sess has @buffer ready for sending to
+@@ -80,7 +79,7 @@ typedef GstFlowReturn (*RTPSessionSendRTP) (RTPSession *sess, RTPSource *src, gp
+ * Returns: a #GstFlowReturn.
+ */
+ typedef GstFlowReturn (*RTPSessionSendRTCP) (RTPSession *sess, RTPSource *src, GstBuffer *buffer,
+- gboolean eos, gpointer user_data);
++ gpointer user_data);
+
+ /**
+ * RTPSessionSyncRTCP:
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch b/Tools/gtk/patches/gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch
new file mode 100644
index 000000000..aad048300
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-0002-rtpbin-avoid-generating-errors-when-rtcp-messages-ar.patch
@@ -0,0 +1,61 @@
+From dab6c473c3e1b2b400ee18afc70140c2f842debf Mon Sep 17 00:00:00 2001
+From: "Alejandro G. Castro" <alex@igalia.com>
+Date: Thu, 20 Oct 2016 13:14:13 +0200
+Subject: [PATCH] rtpbin: avoid generating errors when rtcp messages are empty
+ and check the queue is not empty
+
+Add a check to verify all the output buffers were empty for the
+session in a timout and log an error.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=773269
+---
+ gst/rtpmanager/rtpsession.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c
+index 75908c0..f1d9210 100644
+--- a/gst/rtpmanager/rtpsession.c
++++ b/gst/rtpmanager/rtpsession.c
+@@ -3923,6 +3923,7 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
+ ReportData data = { GST_RTCP_BUFFER_INIT };
+ GHashTable *table_copy;
+ ReportOutput *output;
++ gboolean all_empty = FALSE;
+
+ g_return_val_if_fail (RTP_IS_SESSION (sess), GST_FLOW_ERROR);
+
+@@ -3989,6 +3990,9 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time,
+ if (!is_rtcp_time (sess, current_time, &data))
+ goto done;
+
++ /* check if all the buffers are empty afer generation */
++ all_empty = TRUE;
++
+ GST_DEBUG
+ ("doing RTCP generation %u for %u sources, early %d, may suppress %d",
+ sess->generation, data.num_to_report, data.is_early, data.may_suppress);
+@@ -4036,8 +4040,8 @@ done:
+
+ empty_buffer = gst_buffer_get_size (buffer) == 0;
+
+- if (empty_buffer)
+- g_warning ("rtpsession: Trying to send an empty RTCP packet");
++ if (!empty_buffer)
++ all_empty = FALSE;
+
+ if (sess->callbacks.send_rtcp &&
+ !empty_buffer && (do_not_suppress || !data.may_suppress)) {
+@@ -4068,6 +4072,10 @@ done:
+ g_object_unref (source);
+ g_slice_free (ReportOutput, output);
+ }
++
++ if (all_empty)
++ GST_ERROR ("generated empty RTCP messages for all the sources");
++
+ return result;
+ }
+
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gst-plugins-good-0003-rtpbin-receive-bundle-support.patch b/Tools/gtk/patches/gst-plugins-good-0003-rtpbin-receive-bundle-support.patch
new file mode 100644
index 000000000..ff89c8199
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-0003-rtpbin-receive-bundle-support.patch
@@ -0,0 +1,1018 @@
+From dcd3ce9751cdef0b5ab1fa118355f92bdfe82cb3 Mon Sep 17 00:00:00 2001
+From: Philippe Normand <philn@igalia.com>
+Date: Wed, 16 Nov 2016 08:56:34 +0100
+Subject: [PATCH] rtpbin: receive bundle support
+
+A new signal named on-bundled-ssrc is provided and can be
+used by the application to redirect a stream to a different
+GstRtpSession or to keep the RTX stream grouped within the
+GstRtpSession of the same media type.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=772740
+---
+ docs/plugins/gst-plugins-good-plugins.signals | 8 +
+ gst/rtpmanager/gstrtpbin.c | 562 ++++++++++++++++++--------
+ gst/rtpmanager/gstrtpbin.h | 2 +
+ tests/check/Makefile.am | 4 +
+ tests/check/elements/.gitignore | 1 +
+ tests/check/elements/rtpbundle.c | 390 ++++++++++++++++++
+ tests/check/meson.build | 1 +
+ tests/examples/rtp/.gitignore | 2 +
+ tests/examples/rtp/Makefile.am | 10 +-
+ tests/examples/rtp/client-rtpbundle.c | 266 ++++++++++++
+ tests/examples/rtp/server-rtpbundle.c | 179 ++++++++
+ 11 files changed, 1265 insertions(+), 160 deletions(-)
+ create mode 100644 tests/check/elements/rtpbundle.c
+ create mode 100644 tests/examples/rtp/client-rtpbundle.c
+ create mode 100644 tests/examples/rtp/server-rtpbundle.c
+
+diff --git a/docs/plugins/gst-plugins-good-plugins.signals b/docs/plugins/gst-plugins-good-plugins.signals
+index 3db17e9..44bbdda 100644
+--- a/docs/plugins/gst-plugins-good-plugins.signals
++++ b/docs/plugins/gst-plugins-good-plugins.signals
+@@ -375,6 +375,14 @@ guint arg1
+ </SIGNAL>
+
+ <SIGNAL>
++<NAME>GstRtpBin::on-bundled-ssrc</NAME>
++<RETURNS>guint</RETURNS>
++<FLAGS>l</FLAGS>
++GstRtpBin *gstrtpbin
++guint arg1
++</SIGNAL>
++
++<SIGNAL>
+ <NAME>GstRtpJitterBuffer::clear-pt-map</NAME>
+ <RETURNS>void</RETURNS>
+ <FLAGS>la</FLAGS>
+diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c
+index 648adb9..f58de01 100644
+--- a/gst/rtpmanager/gstrtpbin.c
++++ b/gst/rtpmanager/gstrtpbin.c
+@@ -53,6 +53,13 @@
+ * SSRC in the RTP packets to its own SSRC and wil forward the packets on the
+ * send_rtp_src_\%u pad after updating its internal state.
+ *
++ * #GstRtpBin can also demultiplex incoming bundled streams. The first
++ * #GstRtpSession will have a #GstRtpSsrcDemux element splitting the streams
++ * based on their SSRC and potentially dispatched to a different #GstRtpSession.
++ * Because retransmission SSRCs need to be merged with the corresponding media
++ * stream the #GstRtpBin::on-bundled-ssrc signal is emitted so that the
++ * application can find out to which session the SSRC belongs.
++ *
+ * The session manager needs the clock-rate of the payload types it is handling
+ * and will signal the #GstRtpSession::request-pt-map signal when it needs such a
+ * mapping. One can clear the cached values with the #GstRtpSession::clear-pt-map
+@@ -276,6 +283,8 @@ enum
+ SIGNAL_ON_NEW_SENDER_SSRC,
+ SIGNAL_ON_SENDER_SSRC_ACTIVE,
+
++ SIGNAL_ON_BUNDLED_SSRC,
++
+ LAST_SIGNAL
+ };
+
+@@ -362,6 +371,14 @@ static void remove_send_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session);
+ static void remove_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session);
+ static void free_client (GstRtpBinClient * client, GstRtpBin * bin);
+ static void free_stream (GstRtpBinStream * stream, GstRtpBin * bin);
++static GstRtpBinSession *create_session (GstRtpBin * rtpbin, gint id);
++static GstPad *complete_session_sink (GstRtpBin * rtpbin,
++ GstRtpBinSession * session, gboolean bundle_demuxer_needed);
++static void
++complete_session_receiver (GstRtpBin * rtpbin, GstRtpBinSession * session,
++ guint sessid);
++static GstPad *complete_session_rtcp (GstRtpBin * rtpbin,
++ GstRtpBinSession * session, guint sessid, gboolean bundle_demuxer_needed);
+
+ /* Manages the RTP stream for one SSRC.
+ *
+@@ -428,6 +445,12 @@ struct _GstRtpBinSession
+ gulong demux_newpad_sig;
+ gulong demux_padremoved_sig;
+
++ /* Bundling support */
++ GstElement *rtp_funnel;
++ GstElement *rtcp_funnel;
++ GstElement *bundle_demux;
++ gulong bundle_demux_newpad_sig;
++
+ GMutex lock;
+
+ /* list of GstRtpBinStream */
+@@ -629,6 +652,96 @@ ssrc_demux_pad_removed (GstElement * element, guint ssrc, GstPad * pad,
+ GST_RTP_BIN_UNLOCK (rtpbin);
+ }
+
++static void
++new_bundled_ssrc_pad_found (GstElement * element, guint ssrc, GstPad * pad,
++ GstRtpBinSession * session)
++{
++ GValue result = G_VALUE_INIT;
++ GValue params[2] = { G_VALUE_INIT, G_VALUE_INIT };
++ guint session_id = 0;
++ GstRtpBinSession *target_session = NULL;
++ GstRtpBin *rtpbin = session->bin;
++ gchar *name;
++ GstPad *src_pad;
++ GstPad *recv_rtp_sink = NULL;
++ GstPad *recv_rtcp_sink = NULL;
++ GstPadLinkReturn ret;
++
++ GST_RTP_BIN_DYN_LOCK (rtpbin);
++ GST_DEBUG_OBJECT (rtpbin, "new bundled SSRC pad %08x, %s:%s", ssrc,
++ GST_DEBUG_PAD_NAME (pad));
++
++ g_value_init (&result, G_TYPE_UINT);
++ g_value_init (&params[0], GST_TYPE_ELEMENT);
++ g_value_set_object (&params[0], rtpbin);
++ g_value_init (&params[1], G_TYPE_UINT);
++ g_value_set_uint (&params[1], ssrc);
++
++ g_signal_emitv (params,
++ gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC], 0, &result);
++ g_value_unset (&params[0]);
++
++ session_id = g_value_get_uint (&result);
++ if (session_id == 0) {
++ target_session = session;
++ } else {
++ target_session = find_session_by_id (rtpbin, (gint) session_id);
++ if (!target_session) {
++ target_session = create_session (rtpbin, session_id);
++ }
++ if (!target_session->recv_rtp_sink) {
++ recv_rtp_sink = complete_session_sink (rtpbin, target_session, FALSE);
++ }
++
++ if (!target_session->recv_rtp_src)
++ complete_session_receiver (rtpbin, target_session, session_id);
++
++ if (!target_session->recv_rtcp_sink) {
++ recv_rtcp_sink =
++ complete_session_rtcp (rtpbin, target_session, session_id, FALSE);
++ }
++ }
++
++ GST_DEBUG_OBJECT (rtpbin, "Assigning bundled ssrc %u to session %u", ssrc,
++ session_id);
++
++ if (!recv_rtp_sink) {
++ recv_rtp_sink =
++ gst_element_get_request_pad (target_session->rtp_funnel, "sink_%u");
++ }
++
++ if (!recv_rtcp_sink) {
++ recv_rtcp_sink =
++ gst_element_get_request_pad (target_session->rtcp_funnel, "sink_%u");
++ }
++
++ name = g_strdup_printf ("src_%u", ssrc);
++ src_pad = gst_element_get_static_pad (element, name);
++ ret = gst_pad_link (src_pad, recv_rtp_sink);
++ g_free (name);
++ gst_object_unref (src_pad);
++ gst_object_unref (recv_rtp_sink);
++ if (ret != GST_PAD_LINK_OK) {
++ g_warning
++ ("rtpbin: failed to link bundle demuxer to receive rtp funnel for session %u",
++ session_id);
++ }
++
++ name = g_strdup_printf ("rtcp_src_%u", ssrc);
++ src_pad = gst_element_get_static_pad (element, name);
++ gst_pad_link (src_pad, recv_rtcp_sink);
++ g_free (name);
++ gst_object_unref (src_pad);
++ gst_object_unref (recv_rtcp_sink);
++ if (ret != GST_PAD_LINK_OK) {
++ g_warning
++ ("rtpbin: failed to link bundle demuxer to receive rtcp sink pad for session %u",
++ session_id);
++ }
++
++ GST_RTP_BIN_DYN_UNLOCK (rtpbin);
++}
++
+ /* create a session with the given id. Must be called with RTP_BIN_LOCK */
+ static GstRtpBinSession *
+ create_session (GstRtpBin * rtpbin, gint id)
+@@ -649,6 +762,10 @@ create_session (GstRtpBin * rtpbin, gint id)
+ sess->bin = rtpbin;
+ sess->session = session;
+ sess->demux = demux;
++
++ sess->rtp_funnel = gst_element_factory_make ("funnel", NULL);
++ sess->rtcp_funnel = gst_element_factory_make ("funnel", NULL);
++
+ sess->ptmap = g_hash_table_new_full (NULL, NULL, NULL,
+ (GDestroyNotify) gst_caps_unref);
+ rtpbin->sessions = g_slist_prepend (rtpbin->sessions, sess);
+@@ -696,6 +813,8 @@ create_session (GstRtpBin * rtpbin, gint id)
+
+ gst_bin_add (GST_BIN_CAST (rtpbin), session);
+ gst_bin_add (GST_BIN_CAST (rtpbin), demux);
++ gst_bin_add (GST_BIN_CAST (rtpbin), sess->rtp_funnel);
++ gst_bin_add (GST_BIN_CAST (rtpbin), sess->rtcp_funnel);
+
+ GST_OBJECT_LOCK (rtpbin);
+ target = GST_STATE_TARGET (rtpbin);
+@@ -704,6 +823,8 @@ create_session (GstRtpBin * rtpbin, gint id)
+ /* change state only to what's needed */
+ gst_element_set_state (demux, target);
+ gst_element_set_state (session, target);
++ gst_element_set_state (sess->rtp_funnel, target);
++ gst_element_set_state (sess->rtcp_funnel, target);
+
+ return sess;
+
+@@ -807,7 +928,7 @@ get_pt_map (GstRtpBinSession * session, guint pt)
+ GValue ret = { 0 };
+ GValue args[3] = { {0}, {0}, {0} };
+
+- GST_DEBUG ("searching pt %d in cache", pt);
++ GST_DEBUG ("searching pt %u in cache", pt);
+
+ GST_RTP_SESSION_LOCK (session);
+
+@@ -820,7 +941,7 @@ get_pt_map (GstRtpBinSession * session, guint pt)
+
+ bin = session->bin;
+
+- GST_DEBUG ("emiting signal for pt %d in session %d", pt, session->id);
++ GST_DEBUG ("emiting signal for pt %u in session %u", pt, session->id);
+
+ /* not in cache, send signal to request caps */
+ g_value_init (&args[0], GST_TYPE_ELEMENT);
+@@ -856,7 +977,7 @@ get_pt_map (GstRtpBinSession * session, guint pt)
+ if (!caps)
+ goto no_caps;
+
+- GST_DEBUG ("caching pt %d as %" GST_PTR_FORMAT, pt, caps);
++ GST_DEBUG ("caching pt %u as %" GST_PTR_FORMAT, pt, caps);
+
+ /* store in cache, take additional ref */
+ g_hash_table_insert (session->ptmap, GINT_TO_POINTER (pt),
+@@ -947,7 +1068,7 @@ gst_rtp_bin_get_session (GstRtpBin * bin, guint session_id)
+ GstElement *ret = NULL;
+
+ GST_RTP_BIN_LOCK (bin);
+- GST_DEBUG_OBJECT (bin, "retrieving GstRtpSession, index: %d", session_id);
++ GST_DEBUG_OBJECT (bin, "retrieving GstRtpSession, index: %u", session_id);
+ session = find_session_by_id (bin, (gint) session_id);
+ if (session) {
+ ret = gst_object_ref (session->session);
+@@ -964,7 +1085,7 @@ gst_rtp_bin_get_internal_session (GstRtpBin * bin, guint session_id)
+ GstRtpBinSession *session;
+
+ GST_RTP_BIN_LOCK (bin);
+- GST_DEBUG_OBJECT (bin, "retrieving internal RTPSession object, index: %d",
++ GST_DEBUG_OBJECT (bin, "retrieving internal RTPSession object, index: %u",
+ session_id);
+ session = find_session_by_id (bin, (gint) session_id);
+ if (session) {
+@@ -2194,6 +2315,29 @@ gst_rtp_bin_class_init (GstRtpBinClass * klass)
+ on_sender_ssrc_active), NULL, NULL, g_cclosure_marshal_generic,
+ G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
+
++
++ /**
++ * GstRtpBin::on-bundled-ssrc:
++ * @rtpbin: the object which received the signal
++ * @ssrc: the bundled SSRC
++ *
++ * Notify of a new incoming bundled SSRC. If no handler is connected to the
++ * signal then the #GstRtpSession created for the recv_rtp_sink_\%u
++ * request pad will be managing this new SSRC. However if there is a handler
++ * connected then the application can decided to dispatch this new stream to
++ * another session by providing its ID as return value of the handler. This
++ * can be particularly useful to keep retransmission SSRCs grouped with the
++ * session for which they handle retransmission.
++ *
++ * Since: 1.12
++ */
++ gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC] =
++ g_signal_new ("on-bundled-ssrc", G_TYPE_FROM_CLASS (klass),
++ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpBinClass,
++ on_bundled_ssrc), NULL, NULL,
++ g_cclosure_marshal_generic, G_TYPE_UINT, 1, G_TYPE_UINT);
++
++
+ g_object_class_install_property (gobject_class, PROP_SDES,
+ g_param_spec_boxed ("sdes", "SDES",
+ "The SDES items of this session",
+@@ -3021,7 +3165,7 @@ new_payload_found (GstElement * element, guint pt, GstPad * pad,
+
+ rtpbin = stream->bin;
+
+- GST_DEBUG ("new payload pad %d", pt);
++ GST_DEBUG_OBJECT (rtpbin, "new payload pad %u", pt);
+
+ GST_RTP_BIN_SHUTDOWN_LOCK (rtpbin, shutdown);
+
+@@ -3078,7 +3222,7 @@ pt_map_requested (GstElement * element, guint pt, GstRtpBinSession * session)
+
+ rtpbin = session->bin;
+
+- GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %d in session %d", pt,
++ GST_DEBUG_OBJECT (rtpbin, "payload map requested for pt %u in session %u", pt,
+ session->id);
+
+ caps = get_pt_map (session, pt);
+@@ -3099,7 +3243,7 @@ static void
+ payload_type_change (GstElement * element, guint pt, GstRtpBinSession * session)
+ {
+ GST_DEBUG_OBJECT (session->bin,
+- "emiting signal for pt type changed to %d in session %d", pt,
++ "emiting signal for pt type changed to %u in session %u", pt,
+ session->id);
+
+ g_signal_emit (session->bin, gst_rtp_bin_signals[SIGNAL_PAYLOAD_TYPE_CHANGE],
+@@ -3246,15 +3390,42 @@ no_stream:
+ }
+ }
+
+-static gboolean
+-complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
++static void
++session_maybe_create_bundle_demuxer (GstRtpBinSession * session)
++{
++ GstRtpBin *rtpbin;
++
++ if (session->bundle_demux)
++ return;
++
++ rtpbin = session->bin;
++ if (g_signal_has_handler_pending (rtpbin,
++ gst_rtp_bin_signals[SIGNAL_ON_BUNDLED_SSRC], 0, TRUE)) {
++ GST_DEBUG_OBJECT (rtpbin, "Adding a bundle SSRC demuxer to session %u",
++ session->id);
++ session->bundle_demux = gst_element_factory_make ("rtpssrcdemux", NULL);
++ session->bundle_demux_newpad_sig = g_signal_connect (session->bundle_demux,
++ "new-ssrc-pad", (GCallback) new_bundled_ssrc_pad_found, session);
++
++ gst_bin_add (GST_BIN_CAST (rtpbin), session->bundle_demux);
++ gst_element_sync_state_with_parent (session->bundle_demux);
++ } else {
++ GST_DEBUG_OBJECT (rtpbin,
++ "No handler for the on-bundled-ssrc signal so no need for a bundle SSRC demuxer in session %u",
++ session->id);
++ }
++}
++
++static GstPad *
++complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session,
++ gboolean bundle_demuxer_needed)
+ {
+- gchar *gname;
+ guint sessid = session->id;
+ GstPad *recv_rtp_sink;
++ GstPad *funnel_src;
+ GstElement *decoder;
+- GstElementClass *klass;
+- GstPadTemplate *templ;
++
++ g_assert (!session->recv_rtp_sink);
+
+ /* get recv_rtp pad and store */
+ session->recv_rtp_sink =
+@@ -3265,6 +3436,9 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ g_signal_connect (session->recv_rtp_sink, "notify::caps",
+ (GCallback) caps_changed, session);
+
++ if (bundle_demuxer_needed)
++ session_maybe_create_bundle_demuxer (session);
++
+ GST_DEBUG_OBJECT (rtpbin, "requesting RTP decoder");
+ decoder = session_request_element (session, SIGNAL_REQUEST_RTP_DECODER);
+ if (decoder) {
+@@ -3282,7 +3456,14 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ if (decsrc == NULL)
+ goto dec_src_failed;
+
+- ret = gst_pad_link (decsrc, session->recv_rtp_sink);
++ if (session->bundle_demux) {
++ GstPad *demux_sink;
++ demux_sink = gst_element_get_static_pad (session->bundle_demux, "sink");
++ ret = gst_pad_link (decsrc, demux_sink);
++ gst_object_unref (demux_sink);
++ } else {
++ ret = gst_pad_link (decsrc, session->recv_rtp_sink);
++ }
+ gst_object_unref (decsrc);
+
+ if (ret != GST_PAD_LINK_OK)
+@@ -3290,81 +3471,54 @@ complete_session_sink (GstRtpBin * rtpbin, GstRtpBinSession * session)
+
+ } else {
+ GST_DEBUG_OBJECT (rtpbin, "no RTP decoder given");
+- recv_rtp_sink = gst_object_ref (session->recv_rtp_sink);
++ if (session->bundle_demux) {
++ recv_rtp_sink =
++ gst_element_get_static_pad (session->bundle_demux, "sink");
++ } else {
++ recv_rtp_sink =
++ gst_element_get_request_pad (session->rtp_funnel, "sink_%u");
++ }
+ }
+
+- GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
+- klass = GST_ELEMENT_GET_CLASS (rtpbin);
+- gname = g_strdup_printf ("recv_rtp_sink_%u", sessid);
+- templ = gst_element_class_get_pad_template (klass, "recv_rtp_sink_%u");
+- session->recv_rtp_sink_ghost =
+- gst_ghost_pad_new_from_template (gname, recv_rtp_sink, templ);
+- gst_object_unref (recv_rtp_sink);
+- gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
+- gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
+- g_free (gname);
++ funnel_src = gst_element_get_static_pad (session->rtp_funnel, "src");
++ gst_pad_link (funnel_src, session->recv_rtp_sink);
++ gst_object_unref (funnel_src);
+
+- return TRUE;
++ return recv_rtp_sink;
+
+ /* ERRORS */
+ pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session recv_rtp_sink pad");
+- return FALSE;
++ return NULL;
+ }
+ dec_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get decoder sink pad for session %d", sessid);
+- return FALSE;
++ g_warning ("rtpbin: failed to get decoder sink pad for session %u", sessid);
++ return NULL;
+ }
+ dec_src_failed:
+ {
+- g_warning ("rtpbin: failed to get decoder src pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get decoder src pad for session %u", sessid);
+ gst_object_unref (recv_rtp_sink);
+- return FALSE;
++ return NULL;
+ }
+ dec_link_failed:
+ {
+- g_warning ("rtpbin: failed to link rtp decoder for session %d", sessid);
++ g_warning ("rtpbin: failed to link rtp decoder for session %u", sessid);
+ gst_object_unref (recv_rtp_sink);
+- return FALSE;
++ return NULL;
+ }
+ }
+
+-/* Create a pad for receiving RTP for the session in @name. Must be called with
+- * RTP_BIN_LOCK.
+- */
+-static GstPad *
+-create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
++static void
++complete_session_receiver (GstRtpBin * rtpbin, GstRtpBinSession * session,
++ guint sessid)
+ {
+- guint sessid;
+ GstElement *aux;
+ GstPad *recv_rtp_src;
+- GstRtpBinSession *session;
+-
+- /* first get the session number */
+- if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
+- goto no_name;
+-
+- GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
+
+- /* get or create session */
+- session = find_session_by_id (rtpbin, sessid);
+- if (!session) {
+- GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
+- /* create session now */
+- session = create_session (rtpbin, sessid);
+- if (session == NULL)
+- goto create_error;
+- }
+-
+- /* check if pad was requested */
+- if (session->recv_rtp_sink_ghost != NULL)
+- return session->recv_rtp_sink_ghost;
+-
+- /* setup the session sink pad */
+- if (!complete_session_sink (rtpbin, session))
+- goto session_sink_failed;
++ g_assert (!session->recv_rtp_src);
+
+ session->recv_rtp_src =
+ gst_element_get_static_pad (session->session, "recv_rtp_src");
+@@ -3381,7 +3535,7 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+
+ GST_DEBUG_OBJECT (rtpbin, "linking AUX receiver");
+
+- pname = g_strdup_printf ("sink_%d", sessid);
++ pname = g_strdup_printf ("sink_%u", sessid);
+ auxsink = gst_element_get_static_pad (aux, pname);
+ g_free (pname);
+ if (auxsink == NULL)
+@@ -3394,7 +3548,7 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+
+ /* this can be NULL when this AUX element is not to be linked to
+ * an SSRC demuxer */
+- pname = g_strdup_printf ("src_%d", sessid);
++ pname = g_strdup_printf ("src_%u", sessid);
+ recv_rtp_src = gst_element_get_static_pad (aux, pname);
+ g_free (pname);
+ } else {
+@@ -3408,8 +3562,8 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+ sinkdpad = gst_element_get_static_pad (session->demux, "sink");
+ GST_DEBUG_OBJECT (rtpbin, "linking demuxer RTP sink pad");
+ gst_pad_link_full (recv_rtp_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
+- gst_object_unref (recv_rtp_src);
+ gst_object_unref (sinkdpad);
++ gst_object_unref (recv_rtp_src);
+
+ /* connect to the new-ssrc-pad signal of the SSRC demuxer */
+ session->demux_newpad_sig = g_signal_connect (session->demux,
+@@ -3417,6 +3571,71 @@ create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+ session->demux_padremoved_sig = g_signal_connect (session->demux,
+ "removed-ssrc-pad", (GCallback) ssrc_demux_pad_removed, session);
+ }
++
++ return;
++
++pad_failed:
++ {
++ g_warning ("rtpbin: failed to get session recv_rtp_src pad");
++ return;
++ }
++aux_sink_failed:
++ {
++ g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
++ return;
++ }
++aux_link_failed:
++ {
++ g_warning ("rtpbin: failed to link AUX pad to session %u", sessid);
++ return;
++ }
++}
++
++/* Create a pad for receiving RTP for the session in @name. Must be called with
++ * RTP_BIN_LOCK.
++ */
++static GstPad *
++create_recv_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
++{
++ guint sessid;
++ GstRtpBinSession *session;
++ GstPad *recv_rtp_sink;
++
++ /* first get the session number */
++ if (name == NULL || sscanf (name, "recv_rtp_sink_%u", &sessid) != 1)
++ goto no_name;
++
++ GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
++
++ /* get or create session */
++ session = find_session_by_id (rtpbin, sessid);
++ if (!session) {
++ GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
++ /* create session now */
++ session = create_session (rtpbin, sessid);
++ if (session == NULL)
++ goto create_error;
++ }
++
++ /* check if pad was requested */
++ if (session->recv_rtp_sink_ghost != NULL)
++ return session->recv_rtp_sink_ghost;
++
++ /* setup the session sink pad */
++ recv_rtp_sink = complete_session_sink (rtpbin, session, TRUE);
++ if (!recv_rtp_sink)
++ goto session_sink_failed;
++
++
++ GST_DEBUG_OBJECT (rtpbin, "ghosting session sink pad");
++ session->recv_rtp_sink_ghost =
++ gst_ghost_pad_new_from_template (name, recv_rtp_sink, templ);
++ gst_object_unref (recv_rtp_sink);
++ gst_pad_set_active (session->recv_rtp_sink_ghost, TRUE);
++ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin), session->recv_rtp_sink_ghost);
++
++ complete_session_receiver (rtpbin, session, sessid);
++
+ return session->recv_rtp_sink_ghost;
+
+ /* ERRORS */
+@@ -3435,21 +3654,6 @@ session_sink_failed:
+ /* warning already done */
+ return NULL;
+ }
+-pad_failed:
+- {
+- g_warning ("rtpbin: failed to get session recv_rtp_src pad");
+- return NULL;
+- }
+-aux_sink_failed:
+- {
+- g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
+- return NULL;
+- }
+-aux_link_failed:
+- {
+- g_warning ("rtpbin: failed to link AUX pad to session %d", sessid);
+- return NULL;
+- }
+ }
+
+ static void
+@@ -3463,6 +3667,11 @@ remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ g_signal_handler_disconnect (session->demux, session->demux_padremoved_sig);
+ session->demux_padremoved_sig = 0;
+ }
++ if (session->bundle_demux_newpad_sig) {
++ g_signal_handler_disconnect (session->bundle_demux,
++ session->bundle_demux_newpad_sig);
++ session->bundle_demux_newpad_sig = 0;
++ }
+ if (session->recv_rtp_src) {
+ gst_object_unref (session->recv_rtp_src);
+ session->recv_rtp_src = NULL;
+@@ -3480,37 +3689,14 @@ remove_recv_rtp (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ }
+ }
+
+-/* Create a pad for receiving RTCP for the session in @name. Must be called with
+- * RTP_BIN_LOCK.
+- */
+ static GstPad *
+-create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
+- const gchar * name)
++complete_session_rtcp (GstRtpBin * rtpbin, GstRtpBinSession * session,
++ guint sessid, gboolean bundle_demuxer_needed)
+ {
+- guint sessid;
+ GstElement *decoder;
+- GstRtpBinSession *session;
+- GstPad *sinkdpad, *decsink;
+-
+- /* first get the session number */
+- if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1)
+- goto no_name;
+-
+- GST_DEBUG_OBJECT (rtpbin, "finding session %d", sessid);
+-
+- /* get or create the session */
+- session = find_session_by_id (rtpbin, sessid);
+- if (!session) {
+- GST_DEBUG_OBJECT (rtpbin, "creating session %d", sessid);
+- /* create session now */
+- session = create_session (rtpbin, sessid);
+- if (session == NULL)
+- goto create_error;
+- }
+-
+- /* check if pad was requested */
+- if (session->recv_rtcp_sink_ghost != NULL)
+- return session->recv_rtcp_sink_ghost;
++ GstPad *sinkdpad;
++ GstPad *decsink = NULL;
++ GstPad *funnel_src;
+
+ /* get recv_rtp pad and store */
+ GST_DEBUG_OBJECT (rtpbin, "getting RTCP sink pad");
+@@ -3519,6 +3705,9 @@ create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
+ if (session->recv_rtcp_sink == NULL)
+ goto pad_failed;
+
++ if (bundle_demuxer_needed)
++ session_maybe_create_bundle_demuxer (session);
++
+ GST_DEBUG_OBJECT (rtpbin, "getting RTCP decoder");
+ decoder = session_request_element (session, SIGNAL_REQUEST_RTCP_DECODER);
+ if (decoder) {
+@@ -3535,14 +3724,26 @@ create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
+ if (decsrc == NULL)
+ goto dec_src_failed;
+
+- ret = gst_pad_link (decsrc, session->recv_rtcp_sink);
++ if (session->bundle_demux) {
++ GstPad *demux_sink;
++ demux_sink =
++ gst_element_get_static_pad (session->bundle_demux, "rtcp_sink");
++ ret = gst_pad_link (decsrc, demux_sink);
++ gst_object_unref (demux_sink);
++ } else {
++ ret = gst_pad_link (decsrc, session->recv_rtcp_sink);
++ }
+ gst_object_unref (decsrc);
+
+ if (ret != GST_PAD_LINK_OK)
+ goto dec_link_failed;
+ } else {
+ GST_DEBUG_OBJECT (rtpbin, "no RTCP decoder given");
+- decsink = gst_object_ref (session->recv_rtcp_sink);
++ if (session->bundle_demux) {
++ decsink = gst_element_get_static_pad (session->bundle_demux, "rtcp_sink");
++ } else {
++ decsink = gst_element_get_request_pad (session->rtcp_funnel, "sink_%u");
++ }
+ }
+
+ /* get srcpad, link to SSRCDemux */
+@@ -3556,26 +3757,12 @@ create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
+ gst_pad_link_full (session->sync_src, sinkdpad, GST_PAD_LINK_CHECK_NOTHING);
+ gst_object_unref (sinkdpad);
+
+- session->recv_rtcp_sink_ghost =
+- gst_ghost_pad_new_from_template (name, decsink, templ);
+- gst_object_unref (decsink);
+- gst_pad_set_active (session->recv_rtcp_sink_ghost, TRUE);
+- gst_element_add_pad (GST_ELEMENT_CAST (rtpbin),
+- session->recv_rtcp_sink_ghost);
++ funnel_src = gst_element_get_static_pad (session->rtcp_funnel, "src");
++ gst_pad_link (funnel_src, session->recv_rtcp_sink);
++ gst_object_unref (funnel_src);
+
+- return session->recv_rtcp_sink_ghost;
++ return decsink;
+
+- /* ERRORS */
+-no_name:
+- {
+- g_warning ("rtpbin: invalid name given");
+- return NULL;
+- }
+-create_error:
+- {
+- /* create_session already warned */
+- return NULL;
+- }
+ pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session rtcp_sink pad");
+@@ -3583,25 +3770,82 @@ pad_failed:
+ }
+ dec_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get decoder sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get decoder sink pad for session %u", sessid);
+ return NULL;
+ }
+ dec_src_failed:
+ {
+- g_warning ("rtpbin: failed to get decoder src pad for session %d", sessid);
+- gst_object_unref (decsink);
+- return NULL;
++ g_warning ("rtpbin: failed to get decoder src pad for session %u", sessid);
++ goto cleanup;
+ }
+ dec_link_failed:
+ {
+- g_warning ("rtpbin: failed to link rtcp decoder for session %d", sessid);
+- gst_object_unref (decsink);
+- return NULL;
++ g_warning ("rtpbin: failed to link rtcp decoder for session %u", sessid);
++ goto cleanup;
+ }
+ src_pad_failed:
+ {
+ g_warning ("rtpbin: failed to get session sync_src pad");
+- gst_object_unref (decsink);
++ }
++
++cleanup:
++ gst_object_unref (decsink);
++ return NULL;
++}
++
++/* Create a pad for receiving RTCP for the session in @name. Must be called with
++ * RTP_BIN_LOCK.
++ */
++static GstPad *
++create_recv_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ,
++ const gchar * name)
++{
++ guint sessid;
++ GstRtpBinSession *session;
++ GstPad *decsink = NULL;
++
++ /* first get the session number */
++ if (name == NULL || sscanf (name, "recv_rtcp_sink_%u", &sessid) != 1)
++ goto no_name;
++
++ GST_DEBUG_OBJECT (rtpbin, "finding session %u", sessid);
++
++ /* get or create the session */
++ session = find_session_by_id (rtpbin, sessid);
++ if (!session) {
++ GST_DEBUG_OBJECT (rtpbin, "creating session %u", sessid);
++ /* create session now */
++ session = create_session (rtpbin, sessid);
++ if (session == NULL)
++ goto create_error;
++ }
++
++ /* check if pad was requested */
++ if (session->recv_rtcp_sink_ghost != NULL)
++ return session->recv_rtcp_sink_ghost;
++
++ decsink = complete_session_rtcp (rtpbin, session, sessid, TRUE);
++ if (!decsink)
++ goto create_error;
++
++ session->recv_rtcp_sink_ghost =
++ gst_ghost_pad_new_from_template (name, decsink, templ);
++ gst_object_unref (decsink);
++ gst_pad_set_active (session->recv_rtcp_sink_ghost, TRUE);
++ gst_element_add_pad (GST_ELEMENT_CAST (rtpbin),
++ session->recv_rtcp_sink_ghost);
++
++ return session->recv_rtcp_sink_ghost;
++
++ /* ERRORS */
++no_name:
++ {
++ g_warning ("rtpbin: invalid name given");
++ return NULL;
++ }
++create_error:
++ {
++ /* create_session already warned */
+ return NULL;
+ }
+ }
+@@ -3651,7 +3895,7 @@ complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ GstPadLinkReturn ret;
+
+ GST_DEBUG_OBJECT (rtpbin, "linking RTP encoder");
+- ename = g_strdup_printf ("rtp_src_%d", sessid);
++ ename = g_strdup_printf ("rtp_src_%u", sessid);
+ encsrc = gst_element_get_static_pad (encoder, ename);
+ g_free (ename);
+
+@@ -3660,7 +3904,7 @@ complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
+
+ send_rtp_src = encsrc;
+
+- ename = g_strdup_printf ("rtp_sink_%d", sessid);
++ ename = g_strdup_printf ("rtp_sink_%u", sessid);
+ encsink = gst_element_get_static_pad (encoder, ename);
+ g_free (ename);
+ if (encsink == NULL)
+@@ -3694,23 +3938,23 @@ complete_session_src (GstRtpBin * rtpbin, GstRtpBinSession * session)
+ /* ERRORS */
+ no_srcpad:
+ {
+- g_warning ("rtpbin: failed to get rtp source pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get rtp source pad for session %u", sessid);
+ return FALSE;
+ }
+ enc_src_failed:
+ {
+- g_warning ("rtpbin: failed to get encoder src pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get encoder src pad for session %u", sessid);
+ return FALSE;
+ }
+ enc_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get encoder sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get encoder sink pad for session %u", sessid);
+ gst_object_unref (send_rtp_src);
+ return FALSE;
+ }
+ enc_link_failed:
+ {
+- g_warning ("rtpbin: failed to link rtp encoder for session %d", sessid);
++ g_warning ("rtpbin: failed to link rtp encoder for session %u", sessid);
+ gst_object_unref (send_rtp_src);
+ return FALSE;
+ }
+@@ -3772,22 +4016,22 @@ create_error:
+ }
+ existing_session:
+ {
+- g_warning ("rtpbin: session %d is already a sender", sessid);
++ g_warning ("rtpbin: session %u is already a sender", sessid);
+ return FALSE;
+ }
+ pad_failed:
+ {
+- g_warning ("rtpbin: failed to get session pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get session pad for session %u", sessid);
+ return FALSE;
+ }
+ aux_link_failed:
+ {
+- g_warning ("rtpbin: failed to link AUX for session %d", sessid);
++ g_warning ("rtpbin: failed to link AUX for session %u", sessid);
+ return FALSE;
+ }
+ session_src_failed:
+ {
+- g_warning ("rtpbin: failed to complete AUX for session %d", sessid);
++ g_warning ("rtpbin: failed to complete AUX for session %u", sessid);
+ return FALSE;
+ }
+ }
+@@ -3847,7 +4091,7 @@ create_send_rtp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+ if (!setup_aux_sender (rtpbin, session, aux))
+ goto aux_session_failed;
+
+- pname = g_strdup_printf ("sink_%d", sessid);
++ pname = g_strdup_printf ("sink_%u", sessid);
+ send_rtp_sink = gst_element_get_static_pad (aux, pname);
+ g_free (pname);
+
+@@ -3887,27 +4131,27 @@ create_error:
+ }
+ existing_session:
+ {
+- g_warning ("rtpbin: session %d is already in use", sessid);
++ g_warning ("rtpbin: session %u is already in use", sessid);
+ return NULL;
+ }
+ aux_session_failed:
+ {
+- g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
+ return NULL;
+ }
+ aux_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get AUX sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get AUX sink pad for session %u", sessid);
+ return NULL;
+ }
+ pad_failed:
+ {
+- g_warning ("rtpbin: failed to get session pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get session pad for session %u", sessid);
+ return NULL;
+ }
+ session_src_failed:
+ {
+- g_warning ("rtpbin: failed to setup source pads for session %d", sessid);
++ g_warning ("rtpbin: failed to setup source pads for session %u", sessid);
+ return NULL;
+ }
+ }
+@@ -3978,13 +4222,13 @@ create_rtcp (GstRtpBin * rtpbin, GstPadTemplate * templ, const gchar * name)
+
+ GST_DEBUG_OBJECT (rtpbin, "linking RTCP encoder");
+
+- ename = g_strdup_printf ("rtcp_src_%d", sessid);
++ ename = g_strdup_printf ("rtcp_src_%u", sessid);
+ encsrc = gst_element_get_static_pad (encoder, ename);
+ g_free (ename);
+ if (encsrc == NULL)
+ goto enc_src_failed;
+
+- ename = g_strdup_printf ("rtcp_sink_%d", sessid);
++ ename = g_strdup_printf ("rtcp_sink_%u", sessid);
+ encsink = gst_element_get_static_pad (encoder, ename);
+ g_free (ename);
+ if (encsink == NULL)
+@@ -4021,23 +4265,23 @@ no_session:
+ }
+ pad_failed:
+ {
+- g_warning ("rtpbin: failed to get rtcp pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get rtcp pad for session %u", sessid);
+ return NULL;
+ }
+ enc_src_failed:
+ {
+- g_warning ("rtpbin: failed to get encoder src pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get encoder src pad for session %u", sessid);
+ return NULL;
+ }
+ enc_sink_failed:
+ {
+- g_warning ("rtpbin: failed to get encoder sink pad for session %d", sessid);
++ g_warning ("rtpbin: failed to get encoder sink pad for session %u", sessid);
+ gst_object_unref (encsrc);
+ return NULL;
+ }
+ enc_link_failed:
+ {
+- g_warning ("rtpbin: failed to link rtcp encoder for session %d", sessid);
++ g_warning ("rtpbin: failed to link rtcp encoder for session %u", sessid);
+ gst_object_unref (encsrc);
+ return NULL;
+ }
+diff --git a/gst/rtpmanager/gstrtpbin.h b/gst/rtpmanager/gstrtpbin.h
+index fb13a47..384b76d 100644
+--- a/gst/rtpmanager/gstrtpbin.h
++++ b/gst/rtpmanager/gstrtpbin.h
+@@ -127,6 +127,8 @@ struct _GstRtpBinClass {
+
+ void (*on_new_sender_ssrc) (GstRtpBin *rtpbin, guint session, guint32 ssrc);
+ void (*on_sender_ssrc_active) (GstRtpBin *rtpbin, guint session, guint32 ssrc);
++
++ guint (*on_bundled_ssrc) (GstRtpBin *rtpbin, guint ssrc);
+ };
+
+ GType gst_rtp_bin_get_type (void);
diff --git a/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch b/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch
new file mode 100644
index 000000000..fb15e018f
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-0004-qtdemux-add-context-for-a-preferred-protection.patch
@@ -0,0 +1,320 @@
+From ae4f7d4f09a051c2fbbd05e4df9f79fa6522104f Mon Sep 17 00:00:00 2001
+From: Xabier Rodriguez Calvar <calvaris@igalia.com>
+Date: Fri, 16 Sep 2016 16:08:18 +0200
+Subject: [PATCH] qtdemux: add context for a preferred protection
+
+qtdemux selected the first system corresponding to a working GStreamer
+decryptor. With this change, before selecting that decryptor, qtdemux
+will check if it has context (a preferred decryptor id) and if not, it
+will request it.
+
+The request includes track-id, available key system ids for the
+available decryptors and event the events so that the init data is
+accessible.
+---
+ gst/isomp4/qtdemux.c | 209 +++++++++++++++++++++++++++++++++++++++++++++++++--
+ gst/isomp4/qtdemux.h | 2 +-
+ 2 files changed, 204 insertions(+), 7 deletions(-)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 0425e66..e05e75e 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -480,6 +480,8 @@ static GstIndex *gst_qtdemux_get_index (GstElement * element);
+ #endif
+ static GstStateChangeReturn gst_qtdemux_change_state (GstElement * element,
+ GstStateChange transition);
++static void gst_qtdemux_set_context (GstElement * element,
++ GstContext * context);
+ static gboolean qtdemux_sink_activate (GstPad * sinkpad, GstObject * parent);
+ static gboolean qtdemux_sink_activate_mode (GstPad * sinkpad,
+ GstObject * parent, GstPadMode mode, gboolean active);
+@@ -554,6 +556,7 @@ gst_qtdemux_class_init (GstQTDemuxClass * klass)
+ gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_qtdemux_set_index);
+ gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_qtdemux_get_index);
+ #endif
++ gstelement_class->set_context = GST_DEBUG_FUNCPTR (gst_qtdemux_set_context);
+
+ gst_tag_register_musicbrainz_tags ();
+
+@@ -612,6 +615,7 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
+ qtdemux->cenc_aux_info_sizes = NULL;
+ qtdemux->cenc_aux_sample_count = 0;
+ qtdemux->protection_system_ids = NULL;
++ qtdemux->preferred_protection_system_id = NULL;
+ g_queue_init (&qtdemux->protection_event_queue);
+ gst_segment_init (&qtdemux->segment, GST_FORMAT_TIME);
+ qtdemux->flowcombiner = gst_flow_combiner_new ();
+@@ -1972,6 +1976,10 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
+ g_queue_foreach (&qtdemux->protection_event_queue, (GFunc) gst_event_unref,
+ NULL);
+ g_queue_clear (&qtdemux->protection_event_queue);
++ if (qtdemux->preferred_protection_system_id) {
++ g_free (qtdemux->preferred_protection_system_id);
++ qtdemux->preferred_protection_system_id = NULL;
++ }
+ }
+ qtdemux->offset = 0;
+ gst_adapter_clear (qtdemux->adapter);
+@@ -2404,6 +2412,29 @@ gst_qtdemux_change_state (GstElement * element, GstStateChange transition)
+ }
+
+ static void
++gst_qtdemux_set_context (GstElement * element, GstContext * context)
++{
++ GstQTDemux *qtdemux = GST_QTDEMUX (element);
++
++ g_return_if_fail (GST_IS_CONTEXT (context));
++
++ if (g_strcmp0 (gst_context_get_context_type (context),
++ "drm-preferred-decryption-system-id") == 0) {
++ const GstStructure *s;
++
++ s = gst_context_get_structure (context);
++ qtdemux->preferred_protection_system_id =
++ g_strdup (gst_structure_get_string (s, "decryption-system-id"));
++ GST_DEBUG_OBJECT (element, "set preferred decryption system to %s",
++ qtdemux->preferred_protection_system_id);
++ }
++
++ GST_TRACE_OBJECT (element, "chaining set_context to superclass %p or %p",
++ GST_ELEMENT_GET_CLASS (element), parent_class);
++ GST_ELEMENT_CLASS (parent_class)->set_context (element, context);
++}
++
++static void
+ qtdemux_parse_ftyp (GstQTDemux * qtdemux, const guint8 * buffer, gint length)
+ {
+ /* counts as header data */
+@@ -3392,6 +3423,8 @@ qtdemux_parse_pssh (GstQTDemux * qtdemux, GNode * node)
+ event = gst_event_new_protection (sysid_string, pssh,
+ (parent_box_type == FOURCC_moov) ? "isobmff/moov" : "isobmff/moof");
+ for (i = 0; i < qtdemux->n_streams; ++i) {
++ GST_TRACE_OBJECT (qtdemux,
++ "adding protection event for stream %d and system %s", i, sysid_string);
+ g_queue_push_tail (&qtdemux->streams[i]->protection_scheme_event_queue,
+ gst_event_ref (event));
+ }
+@@ -4993,6 +5026,12 @@ gst_qtdemux_decorate_and_push_buffer (GstQTDemux * qtdemux,
+ GstEvent *event;
+
+ while ((event = g_queue_pop_head (&stream->protection_scheme_event_queue))) {
++#if (!GST_DISABLE_GST_DEBUG)
++ const gchar *system_id = NULL;
++ gst_event_parse_protection (event, &system_id, NULL, NULL);
++ GST_TRACE_OBJECT (qtdemux, "pushing again protection event for system %s",
++ system_id);
++#endif
+ gst_pad_push_event (stream->pad, event);
+ }
+
+@@ -6947,11 +6986,148 @@ qtdemux_do_allocation (GstQTDemux * qtdemux, QtDemuxStream * stream)
+ }
+
+ static gboolean
++pad_query (const GValue * item, GValue * value, gpointer user_data)
++{
++ GstPad *pad = g_value_get_object (item);
++ GstQuery *query = user_data;
++ gboolean res;
++
++ res = gst_pad_peer_query (pad, query);
++
++ if (res) {
++ g_value_set_boolean (value, TRUE);
++ return FALSE;
++ }
++
++ GST_INFO_OBJECT (pad, "pad peer query failed");
++ return TRUE;
++}
++
++static gboolean
++gst_qtdemux_run_query (GstElement * element, GstQuery * query,
++ GstPadDirection direction)
++{
++ GstIterator *it;
++ GstIteratorFoldFunction func = pad_query;
++ GValue res = { 0, };
++
++ g_value_init (&res, G_TYPE_BOOLEAN);
++ g_value_set_boolean (&res, FALSE);
++
++ /* Ask neighbor */
++ if (direction == GST_PAD_SRC)
++ it = gst_element_iterate_src_pads (element);
++ else
++ it = gst_element_iterate_sink_pads (element);
++
++ while (gst_iterator_fold (it, func, &res, query) == GST_ITERATOR_RESYNC)
++ gst_iterator_resync (it);
++
++ gst_iterator_free (it);
++
++ return g_value_get_boolean (&res);
++}
++
++static void
++gst_qtdemux_request_protection_context_if_needed (GstQTDemux * qtdemux,
++ QtDemuxStream * stream)
++{
++ GstQuery *query;
++ GstContext *ctxt;
++ GstElement *element = GST_ELEMENT (qtdemux);
++ GstStructure *st;
++ gchar **filtered_sys_ids;
++ GValue event_list = G_VALUE_INIT;
++ GList *walk;
++
++ /* 1. Check if we already have the context. */
++ if (qtdemux->preferred_protection_system_id != NULL) {
++ GST_LOG_OBJECT (element,
++ "already have the protection context, no need to request it again");
++ return;
++ }
++
++ GST_TRACE_OBJECT (qtdemux, "currently we have detected %u protection systems",
++ qtdemux->protection_system_ids->len);
++ g_ptr_array_add (qtdemux->protection_system_ids, NULL);
++ filtered_sys_ids = gst_protection_filter_systems_by_available_decryptors (
++ (const gchar **) qtdemux->protection_system_ids->pdata);
++ g_ptr_array_remove_index (qtdemux->protection_system_ids,
++ qtdemux->protection_system_ids->len - 1);
++ if (filtered_sys_ids == NULL || filtered_sys_ids[0] == NULL) {
++ GST_LOG_OBJECT (qtdemux, "no suitable decryptors found, not issuing the "
++ "context request");
++ g_strfreev (filtered_sys_ids);
++ return;
++ }
++ GST_TRACE_OBJECT (qtdemux, "found suitable decryptors, running the context "
++ "request");
++
++ if (stream->protection_scheme_event_queue.length) {
++ GST_TRACE_OBJECT (qtdemux, "using stream event queue, length %u",
++ stream->protection_scheme_event_queue.length);
++ walk = stream->protection_scheme_event_queue.tail;
++ } else {
++ GST_TRACE_OBJECT (qtdemux, "using demuxer event queue, length %u",
++ qtdemux->protection_event_queue.length);
++ walk = qtdemux->protection_event_queue.tail;
++ }
++
++ g_value_init (&event_list, GST_TYPE_LIST);
++ for (; walk; walk = g_list_previous (walk)) {
++ GValue *event_value = g_new0 (GValue, 1);
++ g_value_init (event_value, GST_TYPE_EVENT);
++ g_value_set_boxed (event_value, walk->data);
++ gst_value_list_append_and_take_value (&event_list, event_value);
++ }
++
++ /* 2a) Query downstream with GST_QUERY_CONTEXT for the context and
++ * check if downstream already has a context of the specific type
++ * 2b) Query upstream as above.
++ */
++ query = gst_query_new_context ("drm-preferred-decryption-system-id");
++ st = (GstStructure *) gst_query_get_structure (query);
++ gst_structure_set (st, "track-id", G_TYPE_UINT, stream->track_id,
++ "stream-encryption-systems", G_TYPE_STRV, filtered_sys_ids, NULL);
++ gst_structure_set_value (st, "stream-encryption-events", &event_list);
++ if (gst_qtdemux_run_query (element, query, GST_PAD_SRC)) {
++ gst_query_parse_context (query, &ctxt);
++ GST_INFO_OBJECT (element, "found context (%p) in downstream query", ctxt);
++ gst_element_set_context (element, ctxt);
++ } else if (gst_qtdemux_run_query (element, query, GST_PAD_SINK)) {
++ gst_query_parse_context (query, &ctxt);
++ GST_INFO_OBJECT (element, "found context (%p) in upstream query", ctxt);
++ gst_element_set_context (element, ctxt);
++ } else {
++ /* 3) Post a GST_MESSAGE_NEED_CONTEXT message on the bus with
++ * the required context type and afterwards check if a
++ * usable context was set now as in 1). The message could
++ * be handled by the parent bins of the element and the
++ * application.
++ */
++ GstMessage *msg;
++
++ GST_INFO_OBJECT (element, "posting need context message");
++ msg = gst_message_new_need_context (GST_OBJECT_CAST (element),
++ "drm-preferred-decryption-system-id");
++ st = (GstStructure *) gst_message_get_structure (msg);
++ gst_structure_set (st, "track-id", G_TYPE_UINT, stream->track_id,
++ "stream-encryption-systems", G_TYPE_STRV, filtered_sys_ids, NULL);
++ gst_structure_set_value (st, "stream-encryption-events", &event_list);
++ gst_element_post_message (element, msg);
++ }
++
++ g_strfreev (filtered_sys_ids);
++ g_value_unset (&event_list);
++ gst_query_unref (query);
++}
++
++static gboolean
+ gst_qtdemux_configure_protected_caps (GstQTDemux * qtdemux,
+ QtDemuxStream * stream)
+ {
+ GstStructure *s;
+- const gchar *selected_system;
++ const gchar *selected_system = NULL;
+
+ g_return_val_if_fail (qtdemux != NULL, FALSE);
+ g_return_val_if_fail (stream != NULL, FALSE);
+@@ -6966,17 +7142,38 @@ gst_qtdemux_configure_protected_caps (GstQTDemux * qtdemux,
+ "cenc protection system information has been found");
+ return FALSE;
+ }
+- g_ptr_array_add (qtdemux->protection_system_ids, NULL);
+- selected_system = gst_protection_select_system ((const gchar **)
+- qtdemux->protection_system_ids->pdata);
+- g_ptr_array_remove_index (qtdemux->protection_system_ids,
+- qtdemux->protection_system_ids->len - 1);
++
++ gst_qtdemux_request_protection_context_if_needed (qtdemux, stream);
++ if (qtdemux->preferred_protection_system_id != NULL) {
++ guint i;
++ for (i = 0; i < qtdemux->protection_system_ids->len; i++) {
++ if (g_strcmp0 (g_ptr_array_index (qtdemux->protection_system_ids, i),
++ qtdemux->preferred_protection_system_id) == 0) {
++ const gchar *preferred_system_array[] =
++ { qtdemux->preferred_protection_system_id, NULL };
++ selected_system = gst_protection_select_system (preferred_system_array);
++ break;
++ }
++ }
++ }
++
++ if (!selected_system) {
++ g_ptr_array_add (qtdemux->protection_system_ids, NULL);
++ selected_system = gst_protection_select_system ((const gchar **)
++ qtdemux->protection_system_ids->pdata);
++ g_ptr_array_remove_index (qtdemux->protection_system_ids,
++ qtdemux->protection_system_ids->len - 1);
++ }
++
+ if (!selected_system) {
+ GST_ERROR_OBJECT (qtdemux, "stream is protected, but no "
+ "suitable decryptor element has been found");
+ return FALSE;
+ }
+
++ GST_DEBUG_OBJECT (qtdemux, "selected protection system is %s",
++ selected_system);
++
+ s = gst_caps_get_structure (stream->caps, 0);
+ if (!gst_structure_has_name (s, "application/x-cenc")) {
+ gst_structure_set (s,
+diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
+index 53bd071..55c4f63 100644
+--- a/gst/isomp4/qtdemux.h
++++ b/gst/isomp4/qtdemux.h
+@@ -153,7 +153,7 @@ struct _GstQTDemux {
+ guint64 cenc_aux_info_offset;
+ guint8 *cenc_aux_info_sizes;
+ guint32 cenc_aux_sample_count;
+-
++ gchar *preferred_protection_system_id;
+ };
+
+ struct _GstQTDemuxClass {
+--
+2.11.0
+
diff --git a/Tools/gtk/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch b/Tools/gtk/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch
new file mode 100644
index 000000000..3a60db477
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-Revert-qtdemux-expose-streams-with-first-moof-for-fr.patch
@@ -0,0 +1,133 @@
+From 1a81bd90d4a3e59d6669a0bbfa456f1ed4e5db48 Mon Sep 17 00:00:00 2001
+From: Xabier Rodriguez Calvar <calvaris@igalia.com>
+Date: Thu, 7 Apr 2016 13:57:16 +0200
+Subject: [PATCH] Revert "qtdemux: expose streams with first moof for
+ fragmented format"
+
+This reverts commit d8bb6687ea251570c331038279a43d448167d6ad.
+---
+ gst/isomp4/qtdemux.c | 54 ++++++++++++++++------------------------------------
+ gst/isomp4/qtdemux.h | 1 -
+ 2 files changed, 16 insertions(+), 39 deletions(-)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index 39be163..9636b4b 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -609,7 +609,6 @@ gst_qtdemux_init (GstQTDemux * qtdemux)
+ qtdemux->state = QTDEMUX_STATE_INITIAL;
+ qtdemux->pullbased = FALSE;
+ qtdemux->posted_redirect = FALSE;
+- qtdemux->pending_configure = FALSE;
+ qtdemux->neededbytes = 16;
+ qtdemux->todrop = 0;
+ qtdemux->adapter = gst_adapter_new ();
+@@ -2049,7 +2048,6 @@ gst_qtdemux_reset (GstQTDemux * qtdemux, gboolean hard)
+ gst_caps_replace (&qtdemux->media_caps, NULL);
+ qtdemux->timescale = 0;
+ qtdemux->got_moov = FALSE;
+- qtdemux->pending_configure = FALSE;
+ } else if (qtdemux->mss_mode) {
+ gst_flow_combiner_reset (qtdemux->flowcombiner);
+ for (n = 0; n < qtdemux->n_streams; n++)
+@@ -6104,7 +6102,6 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+ &fourcc);
+ if (fourcc == FOURCC_moov) {
+ gint n;
+- gboolean got_samples = FALSE;
+
+ /* in usual fragmented setup we could try to scan for more
+ * and end up at the the moov (after mdat) again */
+@@ -6136,27 +6133,19 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+ qtdemux_node_dump (demux, demux->moov_node);
+ qtdemux_parse_tree (demux);
+ qtdemux_prepare_streams (demux);
++ if (!demux->got_moov)
++ qtdemux_expose_streams (demux);
++ else {
+
+- for (n = 0; n < demux->n_streams; n++) {
+- QtDemuxStream *stream = demux->streams[n];
+- got_samples |= stream->stbl_index >= 0;
+- }
+- if (!demux->fragmented || got_samples) {
+- if (!demux->got_moov) {
+- qtdemux_expose_streams (demux);
+- } else {
+- for (n = 0; n < demux->n_streams; n++) {
+- QtDemuxStream *stream = demux->streams[n];
+- gst_qtdemux_configure_stream (demux, stream);
+- }
++ for (n = 0; n < demux->n_streams; n++) {
++ QtDemuxStream *stream = demux->streams[n];
++
++ gst_qtdemux_configure_stream (demux, stream);
+ }
+- gst_qtdemux_check_send_pending_segment (demux);
+- demux->pending_configure = FALSE;
+- } else {
+- demux->pending_configure = TRUE;
+ }
+
+ demux->got_moov = TRUE;
++ gst_qtdemux_check_send_pending_segment (demux);
+
+ /* fragmented streams headers shouldn't contain edts atoms */
+ if (!demux->fragmented) {
+@@ -6175,7 +6164,6 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+ guint64 dist = 0;
+ GstClockTime prev_pts;
+ guint64 prev_offset;
+- gint n;
+
+ GST_DEBUG_OBJECT (demux, "Parsing [moof]");
+
+@@ -6209,25 +6197,15 @@ gst_qtdemux_process_adapter (GstQTDemux * demux, gboolean force)
+ ret = GST_FLOW_ERROR;
+ goto done;
+ }
+- /* in MSS we need to expose the pads after the first moof as we won't get a moov
+- * Also, fragmented format need to be exposed if a moov have no valid sample data */
+- if (demux->mss_mode || demux->pending_configure) {
+- if (!demux->exposed) {
+- if (!demux->pending_newsegment) {
+- GstSegment segment;
+- gst_segment_init (&segment, GST_FORMAT_TIME);
+- GST_DEBUG_OBJECT (demux, "new pending_newsegment");
+- demux->pending_newsegment = gst_event_new_segment (&segment);
+- }
+- qtdemux_expose_streams (demux);
+- } else {
+- for (n = 0; n < demux->n_streams; n++) {
+- QtDemuxStream *stream = demux->streams[n];
+- gst_qtdemux_configure_stream (demux, stream);
+- }
++ /* in MSS we need to expose the pads after the first moof as we won't get a moov */
++ if (demux->mss_mode && !demux->exposed) {
++ if (!demux->pending_newsegment) {
++ GstSegment segment;
++ gst_segment_init (&segment, GST_FORMAT_TIME);
++ GST_DEBUG_OBJECT (demux, "new pending_newsegment");
++ demux->pending_newsegment = gst_event_new_segment (&segment);
+ }
+- gst_qtdemux_check_send_pending_segment (demux);
+- demux->pending_configure = FALSE;
++ qtdemux_expose_streams (demux);
+ }
+ } else {
+ GST_DEBUG_OBJECT (demux, "Discarding [moof]");
+diff --git a/gst/isomp4/qtdemux.h b/gst/isomp4/qtdemux.h
+index 6061215..ecf0c63 100644
+--- a/gst/isomp4/qtdemux.h
++++ b/gst/isomp4/qtdemux.h
+@@ -89,7 +89,6 @@ struct _GstQTDemux {
+ gboolean posted_redirect;
+
+ /* push based variables */
+- gboolean pending_configure;
+ guint neededbytes;
+ guint todrop;
+ GstAdapter *adapter;
+--
+2.8.0.rc3
+
diff --git a/Tools/gtk/patches/gst-plugins-good-use-the-tfdt-decode-time.patch b/Tools/gtk/patches/gst-plugins-good-use-the-tfdt-decode-time.patch
new file mode 100644
index 000000000..c3c08dfed
--- /dev/null
+++ b/Tools/gtk/patches/gst-plugins-good-use-the-tfdt-decode-time.patch
@@ -0,0 +1,89 @@
+From 1556043c00eb60d3871b4baa8b029175c16c7097 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Enrique=20Oca=C3=B1a=20Gonz=C3=A1lez?= <eocanha@igalia.com>
+Date: Mon, 24 Oct 2016 16:56:31 +0000
+Subject: [PATCH] Use the tfdt decode time on byte streams when it's
+ significantly different than the time in the last sample
+
+We consider there's a sifnificant difference when it's larger than on second
+or than half the duration of the last processed fragment in case the latter is
+larger.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=754230
+---
+ gst/isomp4/qtdemux.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
+index db2d361..5430a39 100644
+--- a/gst/isomp4/qtdemux.c
++++ b/gst/isomp4/qtdemux.c
+@@ -95,6 +95,8 @@
+
+ #define STREAM_IS_EOS(s) (s->time_position == GST_CLOCK_TIME_NONE)
+
++#define ABSDIFF(x, y) ( (x) > (y) ? ((x) - (y)) : ((y) - (x)) )
++
+ GST_DEBUG_CATEGORY (qtdemux_debug);
+
+ /*typedef struct _QtNode QtNode; */
+@@ -256,6 +258,7 @@ struct _QtDemuxStream
+ guint32 n_samples_moof; /* sample count in a moof */
+ guint64 duration_moof; /* duration in timescale of a moof, used for figure out
+ * the framerate of fragmented format stream */
++ guint64 duration_last_moof;
+ guint32 offset_in_sample;
+ guint32 max_buffer_size;
+
+@@ -1828,6 +1831,7 @@ _create_stream (void)
+ stream->protection_scheme_info = NULL;
+ stream->n_samples_moof = 0;
+ stream->duration_moof = 0;
++ stream->duration_last_moof = 0;
+ g_queue_init (&stream->protection_scheme_event_queue);
+ return stream;
+ }
+@@ -2315,6 +2319,7 @@ gst_qtdemux_stream_flush_samples_data (GstQTDemux * qtdemux,
+
+ stream->n_samples_moof = 0;
+ stream->duration_moof = 0;
++ stream->duration_last_moof = 0;
+ }
+
+ static void
+@@ -2883,6 +2888,25 @@ qtdemux_parse_trun (GstQTDemux * qtdemux, GstByteReader * trun,
+ stream->samples[stream->n_samples - 1].timestamp +
+ stream->samples[stream->n_samples - 1].duration;
+
++ /* If this is a GST_FORMAT_BYTES stream and there's a significant
++ * difference (1 sec.) between decode_ts and timestamp, prefer the
++ * former */
++ if (!qtdemux->upstream_format_is_time
++ && ABSDIFF (decode_ts, timestamp) >
++ MAX (stream->duration_last_moof / 2,
++ GSTTIME_TO_QTSTREAMTIME (stream, GST_SECOND))) {
++ GST_INFO_OBJECT (qtdemux,
++ "decode_ts (%" GST_TIME_FORMAT ") and timestamp (%" GST_TIME_FORMAT
++ ") are significantly different (more than %" GST_TIME_FORMAT
++ "), using decode_ts",
++ GST_TIME_ARGS (QTSTREAMTIME_TO_GSTTIME (stream, decode_ts)),
++ GST_TIME_ARGS (QTSTREAMTIME_TO_GSTTIME (stream, timestamp)),
++ GST_TIME_ARGS (QTSTREAMTIME_TO_GSTTIME (stream,
++ MAX (stream->duration_last_moof / 2,
++ GSTTIME_TO_QTSTREAMTIME (stream, GST_SECOND)))));
++ timestamp = decode_ts;
++ }
++
+ gst_ts = QTSTREAMTIME_TO_GSTTIME (stream, timestamp);
+ GST_INFO_OBJECT (qtdemux, "first sample ts %" GST_TIME_FORMAT
+ " (extends previous samples)", GST_TIME_ARGS (gst_ts));
+@@ -3544,6 +3568,7 @@ qtdemux_parse_moof (GstQTDemux * qtdemux, const guint8 * buffer, guint length,
+
+ /* initialise moof sample data */
+ stream->n_samples_moof = 0;
++ stream->duration_last_moof = stream->duration_moof;
+ stream->duration_moof = 0;
+
+ /* Track Run node */
+--
+2.1.4
+
diff --git a/Tools/gtk/patches/gstreamer-0001-protection-added-function-to-filter-system-ids.patch b/Tools/gtk/patches/gstreamer-0001-protection-added-function-to-filter-system-ids.patch
new file mode 100644
index 000000000..e72ef6c13
--- /dev/null
+++ b/Tools/gtk/patches/gstreamer-0001-protection-added-function-to-filter-system-ids.patch
@@ -0,0 +1,77 @@
+From 7772eb350591682b6a315c8a87a58131f731f1d4 Mon Sep 17 00:00:00 2001
+From: Xabier Rodriguez Calvar <calvaris@igalia.com>
+Date: Wed, 19 Oct 2016 16:44:16 +0200
+Subject: [PATCH] protection: added function to filter system ids
+
+gst_protection_filter_systems_by_available_decryptors takes an array of
+strings and returns a new array of strings filtered by the avaible
+decryptors for them so the ones you get are the ones that you should be
+able to decrypt.
+---
+ gst/gstprotection.c | 36 ++++++++++++++++++++++++++++++++++++
+ gst/gstprotection.h | 2 ++
+ 2 files changed, 38 insertions(+)
+
+diff --git a/gst/gstprotection.c b/gst/gstprotection.c
+index 8ee52ea..2d7e5e0 100644
+--- a/gst/gstprotection.c
++++ b/gst/gstprotection.c
+@@ -191,6 +191,42 @@ gst_protection_select_system (const gchar ** system_identifiers)
+ return retval;
+ }
+
++gchar **
++gst_protection_filter_systems_by_available_decryptors (const gchar **
++ system_identifiers)
++{
++ GList *decryptors, *walk;
++ gchar **retval;
++ guint i = 0, decryptors_number;
++
++ decryptors =
++ gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DECRYPTOR,
++ GST_RANK_MARGINAL);
++
++ decryptors_number = g_list_length (decryptors);
++ retval = g_new (gchar *, decryptors_number + 1);
++
++ GST_TRACE ("found %u decrytors", decryptors_number);
++
++ for (walk = decryptors; walk; walk = g_list_next (walk)) {
++ GstElementFactory *fact = (GstElementFactory *) walk->data;
++
++ const char *found_sys_id =
++ gst_protection_factory_check (fact, system_identifiers);
++ GST_TRACE ("factory %s is valid for %s", GST_OBJECT_NAME (fact),
++ found_sys_id);
++
++ if (found_sys_id) {
++ retval[i++] = g_strdup (found_sys_id);
++ }
++ }
++ retval[i] = NULL;
++
++ gst_plugin_feature_list_free (decryptors);
++
++ return retval;
++}
++
+ static const gchar *
+ gst_protection_factory_check (GstElementFactory * fact,
+ const gchar ** system_identifiers)
+diff --git a/gst/gstprotection.h b/gst/gstprotection.h
+index f2f54c4..95976c5 100644
+--- a/gst/gstprotection.h
++++ b/gst/gstprotection.h
+@@ -66,6 +66,8 @@ GstProtectionMeta *gst_buffer_add_protection_meta (GstBuffer * buffer,
+ GstStructure * info);
+
+ const gchar *gst_protection_select_system (const gchar ** system_identifiers);
++gchar ** gst_protection_filter_systems_by_available_decryptors (
++ const gchar ** system_identifiers);
+
+ G_END_DECLS
+ #endif /* __GST_PROTECTION_META_H__ */
+--
+2.10.2
+
diff --git a/Tools/gtk/patches/gtk+-configure-fix-detecting-CUPS-2.x.patch b/Tools/gtk/patches/gtk+-configure-fix-detecting-CUPS-2.x.patch
new file mode 100644
index 000000000..1099f36f2
--- /dev/null
+++ b/Tools/gtk/patches/gtk+-configure-fix-detecting-CUPS-2.x.patch
@@ -0,0 +1,11 @@
+--- a/configure 2016-12-06 14:33:55.708778846 -0500
++++ b/configure 2016-12-06 14:35:09.695069930 -0500
+@@ -25092,7 +25092,7 @@
+ CUPS_API_MAJOR=`echo $ECHO_N $CUPS_API_VERSION | awk -F. '{print $1}'`
+ CUPS_API_MINOR=`echo $ECHO_N $CUPS_API_VERSION | awk -F. '{print $2}'`
+
+- if test $CUPS_API_MAJOR -gt 1 -o \
++ if test $CUPS_API_MAJOR -lt 1 -o \
+ $CUPS_API_MAJOR -eq 1 -a $CUPS_API_MINOR -lt 2; then
+ as_fn_error $? "CUPS >= 1.2 not found" "$LINENO" 5
+ fi
diff --git a/Tools/gtk/patches/icudata-stdlibs.patch b/Tools/gtk/patches/icudata-stdlibs.patch
new file mode 100644
index 000000000..5e92bdec1
--- /dev/null
+++ b/Tools/gtk/patches/icudata-stdlibs.patch
@@ -0,0 +1,15 @@
+Index: icu-52~m1/source/config/mh-linux
+===================================================================
+--- icu-52~m1.orig/source/config/mh-linux 2013-09-14 18:53:23.284040467 -0400
++++ icu-52~m1/source/config/mh-linux 2013-09-14 18:53:23.284040467 -0400
+@@ -21,7 +21,9 @@
+ LD_RPATH_PRE = -Wl,-rpath,
+
+ ## These are the library specific LDFLAGS
+-LDFLAGSICUDT=-nodefaultlibs -nostdlib
++#LDFLAGSICUDT=-nodefaultlibs -nostdlib
++# Debian change: linking icudata as data only causes too many problems.
++LDFLAGSICUDT=
+
+ ## Compiler switch to embed a library name
+ # The initial tab in the next line is to prevent icu-config from reading it.
diff --git a/Tools/gtk/patches/libnice-0001-TURN-allow-REALM-to-be-empty.patch b/Tools/gtk/patches/libnice-0001-TURN-allow-REALM-to-be-empty.patch
new file mode 100644
index 000000000..7f52e4021
--- /dev/null
+++ b/Tools/gtk/patches/libnice-0001-TURN-allow-REALM-to-be-empty.patch
@@ -0,0 +1,50 @@
+From 0c55166a817ec51096460f789234ef49237000cc Mon Sep 17 00:00:00 2001
+From: Alessandro Decina <alessandro.d@gmail.com>
+Date: Thu, 24 Mar 2016 10:48:27 +1100
+Subject: [PATCH 1/2] TURN: allow REALM to be empty
+
+---
+ agent/conncheck.c | 6 ++----
+ stun/stunhmac.c | 6 ++++--
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/agent/conncheck.c b/agent/conncheck.c
+index 057fc81..97bf536 100644
+--- a/agent/conncheck.c
++++ b/agent/conncheck.c
+@@ -2768,13 +2768,11 @@ static gboolean priv_map_reply_to_relay_request (NiceAgent *agent, StunMessage *
+ agent->compatibility == NICE_COMPATIBILITY_OC2007R2) &&
+ stun_message_get_class (resp) == STUN_ERROR &&
+ stun_message_find_error (resp, &code) ==
+- STUN_MESSAGE_RETURN_SUCCESS &&
+- recv_realm != NULL && recv_realm_len > 0) {
+-
++ STUN_MESSAGE_RETURN_SUCCESS) {
+ if (code == 438 ||
+ (code == 401 &&
+ !(recv_realm_len == sent_realm_len &&
+- sent_realm != NULL &&
++ recv_realm != NULL && sent_realm != NULL &&
+ memcmp (sent_realm, recv_realm, sent_realm_len) == 0))) {
+ d->stun_resp_msg = *resp;
+ memcpy (d->stun_resp_buffer, resp->buffer,
+diff --git a/stun/stunhmac.c b/stun/stunhmac.c
+index df5deb6..f73943f 100644
+--- a/stun/stunhmac.c
++++ b/stun/stunhmac.c
+@@ -90,8 +90,10 @@ static const uint8_t *priv_trim_var (const uint8_t *var, size_t *var_len)
+ ptr++;
+ (*var_len)--;
+ }
+- while(ptr[*var_len-1] == '"' ||
+- ptr[*var_len-1] == 0) {
++
++ while(*var_len > 0 &&
++ (ptr[*var_len-1] == '"' ||
++ ptr[*var_len-1] == 0)) {
+ (*var_len)--;
+ }
+
+--
+2.3.4
+
diff --git a/Tools/gtk/patches/libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch b/Tools/gtk/patches/libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch
new file mode 100644
index 000000000..6af57e8b2
--- /dev/null
+++ b/Tools/gtk/patches/libnice-0001-nicesrc-spin-the-agent-mainloop-in-a-separate-thread.patch
@@ -0,0 +1,253 @@
+From 3196a96a408a90f707dff3f31fa3d05d64aeb68a Mon Sep 17 00:00:00 2001
+From: Alessandro Decina <alessandro.d@gmail.com>
+Date: Tue, 13 Oct 2015 12:49:19 +1100
+Subject: [PATCH] nicesrc: spin the agent mainloop in a separate thread
+
+Don't run the mainloop from the srcpad task, since that can get blocked in the
+pipeline and cause unnecessary STUN retrasmissions (at best) and completely
+block the agent (at worst).
+---
+ gst/gstnicesrc.c | 158 ++++++++++++++++++++++++++++++++-----------------------
+ gst/gstnicesrc.h | 4 +-
+ 2 files changed, 93 insertions(+), 69 deletions(-)
+
+diff --git a/gst/gstnicesrc.c b/gst/gstnicesrc.c
+index d369e09..eb59fe9 100644
+--- a/gst/gstnicesrc.c
++++ b/gst/gstnicesrc.c
+@@ -48,6 +48,14 @@ GST_DEBUG_CATEGORY_STATIC (nicesrc_debug);
+
+ #define BUFFER_SIZE (65536)
+
++static gboolean
++gst_nice_src_start (
++ GstBaseSrc *basesrc);
++
++static gboolean
++gst_nice_src_stop (
++ GstBaseSrc *basesrc);
++
+ static GstFlowReturn
+ gst_nice_src_create (
+ GstPushSrc *basesrc,
+@@ -57,10 +65,6 @@ static gboolean
+ gst_nice_src_unlock (
+ GstBaseSrc *basesrc);
+
+-static gboolean
+-gst_nice_src_unlock_stop (
+- GstBaseSrc *basesrc);
+-
+ static void
+ gst_nice_src_set_property (
+ GObject *object,
+@@ -116,8 +120,9 @@ gst_nice_src_class_init (GstNiceSrcClass *klass)
+ gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_nice_src_create);
+
+ gstbasesrc_class = (GstBaseSrcClass *) klass;
++ gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_nice_src_start);
++ gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_nice_src_stop);
+ gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_nice_src_unlock);
+- gstbasesrc_class->unlock_stop = GST_DEBUG_FUNCPTR (gst_nice_src_unlock_stop);
+
+ gobject_class = (GObjectClass *) klass;
+ gobject_class->set_property = gst_nice_src_set_property;
+@@ -179,9 +184,83 @@ gst_nice_src_init (GstNiceSrc *src)
+ src->component_id = 0;
+ src->mainctx = g_main_context_new ();
+ src->mainloop = g_main_loop_new (src->mainctx, FALSE);
+- src->unlocked = FALSE;
+- src->idle_source = NULL;
+ src->outbufs = g_queue_new ();
++ src->agent_io_thread = NULL;
++ g_cond_init (&src->outcond);
++}
++
++static gpointer
++gst_nice_src_agent_io_thread (gpointer data)
++{
++ GstNiceSrc *nicesrc = GST_NICE_SRC (data);
++
++ GST_INFO_OBJECT (nicesrc, "starting agent io thread");
++ g_main_loop_run (nicesrc->mainloop);
++ GST_INFO_OBJECT (nicesrc, "exiting agent io thread");
++
++ return NULL;
++}
++
++static gboolean
++main_loop_running_cb (gpointer data)
++{
++ GstNiceSrc *nicesrc = GST_NICE_SRC (data);
++
++ GST_OBJECT_LOCK (nicesrc);
++ /* _start() and _stop() could both be waiting for the mainloop to start so we
++ * need to broadcast */
++ g_cond_broadcast (&nicesrc->outcond);
++ GST_OBJECT_UNLOCK (nicesrc);
++
++ return FALSE;
++}
++
++static gboolean
++gst_nice_src_start (GstBaseSrc * basesrc)
++{
++ GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc);
++ GSource *source;
++ gchar *thread_name;
++
++ GST_OBJECT_LOCK (nicesrc);
++ source = g_idle_source_new ();
++ g_source_set_callback (source,
++ (GSourceFunc) main_loop_running_cb, nicesrc, NULL);
++ g_source_attach (source, nicesrc->mainctx);
++ g_source_unref (source);
++
++ thread_name = g_strdup_printf ("%s:agent_io", GST_OBJECT_NAME (nicesrc));
++ nicesrc->agent_io_thread = g_thread_new (thread_name, gst_nice_src_agent_io_thread, nicesrc);
++ g_free (thread_name);
++ /* wait until the agent thread starts spinning the mainloop or _stop() is
++ * called */
++ while (GST_BASE_SRC_IS_STARTING (basesrc) &&
++ !g_main_loop_is_running (nicesrc->mainloop))
++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc));
++ GST_OBJECT_UNLOCK (nicesrc);
++
++ return TRUE;
++}
++
++static gboolean
++gst_nice_src_stop (GstBaseSrc * basesrc)
++{
++ GstNiceSrc *nicesrc = GST_NICE_SRC (basesrc);
++ GThread *agent_io_thread = NULL;
++
++ GST_OBJECT_LOCK (nicesrc);
++ /* here we wait for the agent thread created in _start() to be scheduled so
++ * that we don't risk calling _quit() first and then _run() on the mainloop */
++ while (!g_main_loop_is_running (nicesrc->mainloop))
++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc));
++ g_main_loop_quit (nicesrc->mainloop);
++ agent_io_thread = nicesrc->agent_io_thread;
++ nicesrc->agent_io_thread = NULL;
++ GST_OBJECT_UNLOCK (nicesrc);
++
++ g_thread_join (agent_io_thread);
++
++ return TRUE;
+ }
+
+ static void
+@@ -207,62 +286,17 @@ gst_nice_src_read_callback (NiceAgent *agent,
+ #endif
+ GST_OBJECT_LOCK (nicesrc);
+ g_queue_push_tail (nicesrc->outbufs, buffer);
+- g_main_loop_quit (nicesrc->mainloop);
++ g_cond_signal (&nicesrc->outcond);
+ GST_OBJECT_UNLOCK (nicesrc);
+ }
+
+ static gboolean
+-gst_nice_src_unlock_idler (gpointer data)
+-{
+- GstNiceSrc *nicesrc = GST_NICE_SRC (data);
+-
+- GST_OBJECT_LOCK (nicesrc);
+- if (nicesrc->unlocked)
+- g_main_loop_quit (nicesrc->mainloop);
+-
+- if (nicesrc->idle_source) {
+- g_source_destroy (nicesrc->idle_source);
+- g_source_unref (nicesrc->idle_source);
+- nicesrc->idle_source = NULL;
+- }
+- GST_OBJECT_UNLOCK (nicesrc);
+-
+- return FALSE;
+-}
+-
+-static gboolean
+ gst_nice_src_unlock (GstBaseSrc *src)
+ {
+ GstNiceSrc *nicesrc = GST_NICE_SRC (src);
+
+ GST_OBJECT_LOCK (src);
+- nicesrc->unlocked = TRUE;
+-
+- g_main_loop_quit (nicesrc->mainloop);
+-
+- if (!nicesrc->idle_source) {
+- nicesrc->idle_source = g_idle_source_new ();
+- g_source_set_priority (nicesrc->idle_source, G_PRIORITY_HIGH);
+- g_source_set_callback (nicesrc->idle_source, gst_nice_src_unlock_idler, src, NULL);
+- g_source_attach (nicesrc->idle_source, g_main_loop_get_context (nicesrc->mainloop));
+- }
+- GST_OBJECT_UNLOCK (src);
+-
+- return TRUE;
+-}
+-
+-static gboolean
+-gst_nice_src_unlock_stop (GstBaseSrc *src)
+-{
+- GstNiceSrc *nicesrc = GST_NICE_SRC (src);
+-
+- GST_OBJECT_LOCK (src);
+- nicesrc->unlocked = FALSE;
+- if (nicesrc->idle_source) {
+- g_source_destroy (nicesrc->idle_source);
+- g_source_unref(nicesrc->idle_source);
+- }
+- nicesrc->idle_source = NULL;
++ g_cond_signal (&nicesrc->outcond);
+ GST_OBJECT_UNLOCK (src);
+
+ return TRUE;
+@@ -278,19 +312,8 @@ gst_nice_src_create (
+ GST_LOG_OBJECT (nicesrc, "create called");
+
+ GST_OBJECT_LOCK (basesrc);
+- if (nicesrc->unlocked) {
+- GST_OBJECT_UNLOCK (basesrc);
+-#if GST_CHECK_VERSION (1,0,0)
+- return GST_FLOW_FLUSHING;
+-#else
+- return GST_FLOW_WRONG_STATE;
+-#endif
+- }
+- if (g_queue_is_empty (nicesrc->outbufs)) {
+- GST_OBJECT_UNLOCK (basesrc);
+- g_main_loop_run (nicesrc->mainloop);
+- GST_OBJECT_LOCK (basesrc);
+- }
++ if (g_queue_is_empty (nicesrc->outbufs))
++ g_cond_wait (&nicesrc->outcond, GST_OBJECT_GET_LOCK (nicesrc));
+
+ *buffer = g_queue_pop_head (nicesrc->outbufs);
+ GST_OBJECT_UNLOCK (basesrc);
+@@ -331,6 +354,7 @@ gst_nice_src_dispose (GObject *object)
+ g_queue_free (src->outbufs);
+ }
+ src->outbufs = NULL;
++ g_cond_clear (&src->outcond);
+
+ G_OBJECT_CLASS (gst_nice_src_parent_class)->dispose (object);
+ }
+diff --git a/gst/gstnicesrc.h b/gst/gstnicesrc.h
+index 5d3f554..2d9f674 100644
+--- a/gst/gstnicesrc.h
++++ b/gst/gstnicesrc.h
+@@ -68,8 +68,8 @@ struct _GstNiceSrc
+ GMainContext *mainctx;
+ GMainLoop *mainloop;
+ GQueue *outbufs;
+- gboolean unlocked;
+- GSource *idle_source;
++ GCond outcond;
++ GThread *agent_io_thread;
+ };
+
+ typedef struct _GstNiceSrcClass GstNiceSrcClass;
+--
+2.3.4
+
diff --git a/Tools/gtk/patches/librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch b/Tools/gtk/patches/librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch
new file mode 100644
index 000000000..a20af4ce1
--- /dev/null
+++ b/Tools/gtk/patches/librsvg-2.36.1-bump-up-config.guess-to-support-aarch64.patch
@@ -0,0 +1,1581 @@
+diff -ur librsvg-2.36.1-orig/config.guess librsvg-2.36.1/config.guess
+--- librsvg-2.36.1-orig/config.guess 2012-02-03 13:14:58.000000000 +0100
++++ librsvg-2.36.1/config.guess 2014-09-25 18:36:54.000000000 +0200
+@@ -1,14 +1,12 @@
+ #! /bin/sh
+ # Attempt to guess a canonical system name.
+-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-# Free Software Foundation, Inc.
++# Copyright 1992-2014 Free Software Foundation, Inc.
+
+-timestamp='2009-11-20'
++timestamp='2014-03-23'
+
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful, but
+@@ -17,26 +15,22 @@
+ # General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
+-
+-
+-# Originally written by Per Bothner. Please send patches (context
+-# diff format) to <config-patches@gnu.org> and include a ChangeLog
+-# entry.
++# the same distribution terms that you use for the rest of that
++# program. This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+ #
+-# This script attempts to guess a canonical system name similar to
+-# config.sub. If it succeeds, it prints the system name on stdout, and
+-# exits with 0. Otherwise, it exits with 1.
++# Originally written by Per Bothner.
+ #
+ # You can get the latest version of this script from:
+ # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
++#
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++
+
+ me=`echo "$0" | sed -e 's,.*/,,'`
+
+@@ -56,8 +50,7 @@
+ GNU config.guess ($timestamp)
+
+ Originally written by Per Bothner.
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright 1992-2014 Free Software Foundation, Inc.
+
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -139,12 +132,33 @@
+ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
++case "${UNAME_SYSTEM}" in
++Linux|GNU|GNU/*)
++ # If the system lacks a compiler, then just pick glibc.
++ # We could probably try harder.
++ LIBC=gnu
++
++ eval $set_cc_for_build
++ cat <<-EOF > $dummy.c
++ #include <features.h>
++ #if defined(__UCLIBC__)
++ LIBC=uclibc
++ #elif defined(__dietlibc__)
++ LIBC=dietlibc
++ #else
++ LIBC=gnu
++ #endif
++ EOF
++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
++ ;;
++esac
++
+ # Note: order is significant - the case branches are not exclusive.
+
+ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
++ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+@@ -180,7 +194,7 @@
+ fi
+ ;;
+ *)
+- os=netbsd
++ os=netbsd
+ ;;
+ esac
+ # The OS release
+@@ -201,6 +215,10 @@
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
++ *:Bitrig:*:*)
++ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
++ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
++ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+@@ -223,7 +241,7 @@
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
++ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+@@ -269,7 +287,10 @@
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- exit ;;
++ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
++ exitcode=$?
++ trap '' 0
++ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+@@ -295,12 +316,12 @@
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+- echo powerpc-ibm-os400
++ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+- arm:riscos:*:*|arm:RISCOS:*:*)
++ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+@@ -394,23 +415,23 @@
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+- echo m68k-atari-mint${UNAME_RELEASE}
++ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+- exit ;;
++ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+- echo m68k-atari-mint${UNAME_RELEASE}
++ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+- echo m68k-milan-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-milan-mint${UNAME_RELEASE}
++ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+- echo m68k-hades-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-hades-mint${UNAME_RELEASE}
++ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+- echo m68k-unknown-mint${UNAME_RELEASE}
+- exit ;;
++ echo m68k-unknown-mint${UNAME_RELEASE}
++ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+@@ -480,8 +501,8 @@
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+- # DG/UX returns AViiON for all architectures
+- UNAME_PROCESSOR=`/usr/bin/uname -p`
++ # DG/UX returns AViiON for all architectures
++ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+@@ -494,7 +515,7 @@
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+- exit ;;
++ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+@@ -551,7 +572,7 @@
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+- *:AIX:*:[456])
++ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+@@ -594,52 +615,52 @@
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+- case "${sc_cpu_version}" in
+- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+- 532) # CPU_PA_RISC2_0
+- case "${sc_kernel_bits}" in
+- 32) HP_ARCH="hppa2.0n" ;;
+- 64) HP_ARCH="hppa2.0w" ;;
++ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
++ case "${sc_cpu_version}" in
++ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
++ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
++ 532) # CPU_PA_RISC2_0
++ case "${sc_kernel_bits}" in
++ 32) HP_ARCH="hppa2.0n" ;;
++ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+- esac ;;
+- esac
++ esac ;;
++ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+- sed 's/^ //' << EOF >$dummy.c
++ sed 's/^ //' << EOF >$dummy.c
++
++ #define _HPUX_SOURCE
++ #include <stdlib.h>
++ #include <unistd.h>
++
++ int main ()
++ {
++ #if defined(_SC_KERNEL_BITS)
++ long bits = sysconf(_SC_KERNEL_BITS);
++ #endif
++ long cpu = sysconf (_SC_CPU_VERSION);
+
+- #define _HPUX_SOURCE
+- #include <stdlib.h>
+- #include <unistd.h>
+-
+- int main ()
+- {
+- #if defined(_SC_KERNEL_BITS)
+- long bits = sysconf(_SC_KERNEL_BITS);
+- #endif
+- long cpu = sysconf (_SC_CPU_VERSION);
+-
+- switch (cpu)
+- {
+- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+- case CPU_PA_RISC2_0:
+- #if defined(_SC_KERNEL_BITS)
+- switch (bits)
+- {
+- case 64: puts ("hppa2.0w"); break;
+- case 32: puts ("hppa2.0n"); break;
+- default: puts ("hppa2.0"); break;
+- } break;
+- #else /* !defined(_SC_KERNEL_BITS) */
+- puts ("hppa2.0"); break;
+- #endif
+- default: puts ("hppa1.0"); break;
+- }
+- exit (0);
+- }
++ switch (cpu)
++ {
++ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
++ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
++ case CPU_PA_RISC2_0:
++ #if defined(_SC_KERNEL_BITS)
++ switch (bits)
++ {
++ case 64: puts ("hppa2.0w"); break;
++ case 32: puts ("hppa2.0n"); break;
++ default: puts ("hppa2.0"); break;
++ } break;
++ #else /* !defined(_SC_KERNEL_BITS) */
++ puts ("hppa2.0"); break;
++ #endif
++ default: puts ("hppa1.0"); break;
++ }
++ exit (0);
++ }
+ EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+@@ -730,22 +751,22 @@
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+- exit ;;
++ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+- exit ;;
++ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+- exit ;;
++ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+- exit ;;
++ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+- exit ;;
++ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+@@ -769,14 +790,14 @@
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+- exit ;;
++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
++ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
++ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
++ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+@@ -788,30 +809,35 @@
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+- case ${UNAME_MACHINE} in
+- pc98)
+- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++ UNAME_PROCESSOR=`/usr/bin/uname -p`
++ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
++ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
++ *:MINGW64*:*)
++ echo ${UNAME_MACHINE}-pc-mingw64
++ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
++ *:MSYS*:*)
++ echo ${UNAME_MACHINE}-pc-msys
++ exit ;;
+ i*:windows32*:*)
+- # uname -m includes "-pc" on this system.
+- echo ${UNAME_MACHINE}-mingw32
++ # uname -m includes "-pc" on this system.
++ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+- case ${UNAME_MACHINE} in
++ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+@@ -848,15 +874,22 @@
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
++ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
++ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
++ aarch64:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
++ aarch64_be:Linux:*:*)
++ UNAME_MACHINE=aarch64_be
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+@@ -866,52 +899,56 @@
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+- esac
++ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
++ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
++ arc:Linux:*:* | arceb:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
++ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
++ | grep -q __ARM_PCS_VFP
++ then
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
++ else
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
++ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+- echo cris-axis-linux-gnu
++ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+- echo crisv32-axis-linux-gnu
++ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+- echo frv-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
++ hexagon:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+- LIBC=gnu
+- eval $set_cc_for_build
+- sed 's/^ //' << EOF >$dummy.c
+- #ifdef __dietlibc__
+- LIBC=dietlibc
+- #endif
+-EOF
+- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
++ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+@@ -930,51 +967,63 @@
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
++ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+- or32:Linux:*:*)
+- echo or32-unknown-linux-gnu
++ openrisc*:Linux:*:*)
++ echo or1k-unknown-linux-${LIBC}
++ exit ;;
++ or32:Linux:*:* | or1k*:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+- echo sparc-unknown-linux-gnu
++ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+- echo hppa64-unknown-linux-gnu
++ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+- PA7*) echo hppa1.1-unknown-linux-gnu ;;
+- PA8*) echo hppa2.0-unknown-linux-gnu ;;
+- *) echo hppa-unknown-linux-gnu ;;
++ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
++ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
++ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+- echo powerpc64-unknown-linux-gnu
++ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+- echo powerpc-unknown-linux-gnu
++ echo powerpc-unknown-linux-${LIBC}
++ exit ;;
++ ppc64le:Linux:*:*)
++ echo powerpc64le-unknown-linux-${LIBC}
++ exit ;;
++ ppcle:Linux:*:*)
++ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+- echo ${UNAME_MACHINE}-ibm-linux
++ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
++ tile*:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+- echo ${UNAME_MACHINE}-dec-linux-gnu
++ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+- echo x86_64-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-gnu
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+@@ -983,11 +1032,11 @@
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+- # Unixware is an offshoot of SVR4, but it has its own version
+- # number series starting with 2...
+- # I am not positive that other SVR4 systems won't match this,
++ # Unixware is an offshoot of SVR4, but it has its own version
++ # number series starting with 2...
++ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+- # Use sysv4.2uw... so that sysv4* matches it.
++ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+@@ -1019,7 +1068,7 @@
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+- # UnixWare 7.x, OpenUNIX and OpenServer 6.
++ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+@@ -1047,13 +1096,13 @@
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+- # uname -m prints for DJGPP always 'pc', but it prints nothing about
+- # the processor, so we play safe by assuming i586.
++ # uname -m prints for DJGPP always 'pc', but it prints nothing about
++ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+- exit ;;
++ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+@@ -1088,8 +1137,8 @@
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+- && { echo i486-ncr-sysv4; exit; } ;;
++ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
++ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+@@ -1132,10 +1181,10 @@
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+- # says <Richard.M.Bartel@ccMail.Census.GOV>
+- echo i586-unisys-sysv4
+- exit ;;
++ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
++ # says <Richard.M.Bartel@ccMail.Census.GOV>
++ echo i586-unisys-sysv4
++ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+@@ -1161,11 +1210,11 @@
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+- echo mips-nec-sysv${UNAME_RELEASE}
++ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+- echo mips-unknown-sysv${UNAME_RELEASE}
++ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+- exit ;;
++ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+@@ -1178,6 +1227,9 @@
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
++ x86_64:Haiku:*:*)
++ echo x86_64-unknown-haiku
++ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+@@ -1204,19 +1256,31 @@
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+- case $UNAME_PROCESSOR in
+- i386)
+- eval $set_cc_for_build
+- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+- grep IS_64BIT_ARCH >/dev/null
+- then
+- UNAME_PROCESSOR="x86_64"
+- fi
+- fi ;;
+- unknown) UNAME_PROCESSOR=powerpc ;;
+- esac
++ eval $set_cc_for_build
++ if test "$UNAME_PROCESSOR" = unknown ; then
++ UNAME_PROCESSOR=powerpc
++ fi
++ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
++ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
++ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
++ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
++ grep IS_64BIT_ARCH >/dev/null
++ then
++ case $UNAME_PROCESSOR in
++ i386) UNAME_PROCESSOR=x86_64 ;;
++ powerpc) UNAME_PROCESSOR=powerpc64 ;;
++ esac
++ fi
++ fi
++ elif test "$UNAME_PROCESSOR" = i386 ; then
++ # Avoid executing cc on OS X 10.9, as it ships with a stub
++ # that puts up a graphical alert prompting to install
++ # developer tools. Any system running Mac OS X 10.7 or
++ # later (Darwin 11 and later) is required to have a 64-bit
++ # processor. This is not true of the ARM version of Darwin
++ # that Apple uses in portable devices.
++ UNAME_PROCESSOR=x86_64
++ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+@@ -1230,7 +1294,10 @@
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+- NSE-?:NONSTOP_KERNEL:*:*)
++ NEO-?:NONSTOP_KERNEL:*:*)
++ echo neo-tandem-nsk${UNAME_RELEASE}
++ exit ;;
++ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+@@ -1275,13 +1342,13 @@
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+- echo mips-sei-seiux${UNAME_RELEASE}
++ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+- UNAME_MACHINE=`(uname -p) 2>/dev/null`
++ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+@@ -1299,158 +1366,10 @@
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+-esac
+-
+-#echo '(No uname command or uname output not recognized.)' 1>&2
+-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+-
+-eval $set_cc_for_build
+-cat >$dummy.c <<EOF
+-#ifdef _SEQUENT_
+-# include <sys/types.h>
+-# include <sys/utsname.h>
+-#endif
+-main ()
+-{
+-#if defined (sony)
+-#if defined (MIPSEB)
+- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+- I don't know.... */
+- printf ("mips-sony-bsd\n"); exit (0);
+-#else
+-#include <sys/param.h>
+- printf ("m68k-sony-newsos%s\n",
+-#ifdef NEWSOS4
+- "4"
+-#else
+- ""
+-#endif
+- ); exit (0);
+-#endif
+-#endif
+-
+-#if defined (__arm) && defined (__acorn) && defined (__unix)
+- printf ("arm-acorn-riscix\n"); exit (0);
+-#endif
+-
+-#if defined (hp300) && !defined (hpux)
+- printf ("m68k-hp-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (NeXT)
+-#if !defined (__ARCHITECTURE__)
+-#define __ARCHITECTURE__ "m68k"
+-#endif
+- int version;
+- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+- if (version < 4)
+- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+- else
+- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+- exit (0);
+-#endif
+-
+-#if defined (MULTIMAX) || defined (n16)
+-#if defined (UMAXV)
+- printf ("ns32k-encore-sysv\n"); exit (0);
+-#else
+-#if defined (CMU)
+- printf ("ns32k-encore-mach\n"); exit (0);
+-#else
+- printf ("ns32k-encore-bsd\n"); exit (0);
+-#endif
+-#endif
+-#endif
+-
+-#if defined (__386BSD__)
+- printf ("i386-pc-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (sequent)
+-#if defined (i386)
+- printf ("i386-sequent-dynix\n"); exit (0);
+-#endif
+-#if defined (ns32000)
+- printf ("ns32k-sequent-dynix\n"); exit (0);
+-#endif
+-#endif
+-
+-#if defined (_SEQUENT_)
+- struct utsname un;
+-
+- uname(&un);
+-
+- if (strncmp(un.version, "V2", 2) == 0) {
+- printf ("i386-sequent-ptx2\n"); exit (0);
+- }
+- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+- printf ("i386-sequent-ptx1\n"); exit (0);
+- }
+- printf ("i386-sequent-ptx\n"); exit (0);
+-
+-#endif
+-
+-#if defined (vax)
+-# if !defined (ultrix)
+-# include <sys/param.h>
+-# if defined (BSD)
+-# if BSD == 43
+- printf ("vax-dec-bsd4.3\n"); exit (0);
+-# else
+-# if BSD == 199006
+- printf ("vax-dec-bsd4.3reno\n"); exit (0);
+-# else
+- printf ("vax-dec-bsd\n"); exit (0);
+-# endif
+-# endif
+-# else
+- printf ("vax-dec-bsd\n"); exit (0);
+-# endif
+-# else
+- printf ("vax-dec-ultrix\n"); exit (0);
+-# endif
+-#endif
+-
+-#if defined (alliant) && defined (i860)
+- printf ("i860-alliant-bsd\n"); exit (0);
+-#endif
+-
+- exit (1);
+-}
+-EOF
+-
+-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+- { echo "$SYSTEM_NAME"; exit; }
+-
+-# Apollos put the system type in the environment.
+-
+-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+-
+-# Convex versions that predate uname can use getsysinfo(1)
+-
+-if [ -x /usr/convex/getsysinfo ]
+-then
+- case `getsysinfo -f cpu_type` in
+- c1*)
+- echo c1-convex-bsd
+- exit ;;
+- c2*)
+- if getsysinfo -f scalar_acc
+- then echo c32-convex-bsd
+- else echo c2-convex-bsd
+- fi
++ x86_64:VMkernel:*:*)
++ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+- c34*)
+- echo c34-convex-bsd
+- exit ;;
+- c38*)
+- echo c38-convex-bsd
+- exit ;;
+- c4*)
+- echo c4-convex-bsd
+- exit ;;
+- esac
+-fi
++esac
+
+ cat >&2 <<EOF
+ $0: unable to guess system type
+diff -ur librsvg-2.36.1-orig/config.sub librsvg-2.36.1/config.sub
+--- librsvg-2.36.1-orig/config.sub 2012-02-03 13:14:58.000000000 +0100
++++ librsvg-2.36.1/config.sub 2014-09-25 18:37:12.000000000 +0200
+@@ -1,38 +1,31 @@
+ #! /bin/sh
+ # Configuration validation subroutine script.
+-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+-# Free Software Foundation, Inc.
+-
+-timestamp='2009-11-20'
+-
+-# This file is (in principle) common to ALL GNU software.
+-# The presence of a machine in this file suggests that SOME GNU software
+-# can handle that machine. It does not imply ALL GNU software can.
+-#
+-# This file is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
++# Copyright 1992-2014 Free Software Foundation, Inc.
++
++timestamp='2014-09-11'
++
++# This file is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ #
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++# General Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+-# 02110-1301, USA.
++# along with this program; if not, see <http://www.gnu.org/licenses/>.
+ #
+ # As a special exception to the GNU General Public License, if you
+ # distribute this file as part of a program that contains a
+ # configuration script generated by Autoconf, you may include it under
+-# the same distribution terms that you use for the rest of that program.
++# the same distribution terms that you use for the rest of that
++# program. This Exception is an additional permission under section 7
++# of the GNU General Public License, version 3 ("GPLv3").
+
+
+-# Please send patches to <config-patches@gnu.org>. Submit a context
+-# diff and a properly formatted GNU ChangeLog entry.
++# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+ #
+ # Configuration subroutine to validate and canonicalize a configuration type.
+ # Supply the specified configuration type as an argument.
+@@ -75,8 +68,7 @@
+ version="\
+ GNU config.sub ($timestamp)
+
+-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
++Copyright 1992-2014 Free Software Foundation, Inc.
+
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -123,13 +115,18 @@
+ # Here we must recognize all the valid KERNEL-OS combinations.
+ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+ case $maybe_os in
+- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
++ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
++ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
++ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
++ android-linux)
++ os=-linux-android
++ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
++ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+@@ -152,12 +149,12 @@
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+- -apple | -axis | -knuth | -cray | -microblaze)
++ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+- -bluegene*)
+- os=-cnk
++ -bluegene*)
++ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+@@ -173,10 +170,10 @@
+ os=-chorusos
+ basic_machine=$1
+ ;;
+- -chorusrdb)
+- os=-chorusrdb
++ -chorusrdb)
++ os=-chorusrdb
+ basic_machine=$1
+- ;;
++ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+@@ -221,6 +218,12 @@
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
++ -lynx*178)
++ os=-lynxos178
++ ;;
++ -lynx*5)
++ os=-lynxos5
++ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+@@ -245,20 +248,28 @@
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
++ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
++ | arc | arceb \
++ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
++ | avr | avr32 \
++ | be32 | be64 \
+ | bfin \
+- | c4x | clipper \
++ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
++ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
++ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
++ | k1om \
++ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+- | maxq | mb | microblaze | mcore | mep | metag \
++ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+@@ -272,38 +283,51 @@
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
++ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
++ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
++ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+- | nios | nios2 \
++ | nds32 | nds32le | nds32be \
++ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+- | or32 \
++ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
++ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+- | rx \
++ | riscv32 | riscv64 \
++ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+- | spu | strongarm \
+- | tahoe | thumb | tic4x | tic80 | tron \
++ | spu \
++ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+- | v850 | v850e \
++ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
++ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+- m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+- # Motorola 68HC11/12.
++ c54x)
++ basic_machine=tic54x-unknown
++ ;;
++ c55x)
++ basic_machine=tic55x-unknown
++ ;;
++ c6x)
++ basic_machine=tic6x-unknown
++ ;;
++ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+@@ -313,6 +337,21 @@
+ basic_machine=mt-unknown
+ ;;
+
++ strongarm | thumb | xscale)
++ basic_machine=arm-unknown
++ ;;
++ xgate)
++ basic_machine=$basic_machine-unknown
++ os=-none
++ ;;
++ xscaleeb)
++ basic_machine=armeb-unknown
++ ;;
++
++ xscaleel)
++ basic_machine=armel-unknown
++ ;;
++
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+@@ -327,25 +366,31 @@
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
++ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
++ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
++ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+- | clipper-* | craynv-* | cydra-* \
++ | c[123]* | c30-* | [cjt]90-* | c4x-* \
++ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
++ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
++ | k1om-* \
++ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
++ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
++ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+@@ -359,33 +404,41 @@
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
++ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
++ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
++ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+- | nios-* | nios2-* \
++ | nds32-* | nds32le-* | nds32be-* \
++ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
++ | open8-* \
++ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
++ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+- | romp-* | rs6000-* | rx-* \
++ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+- | tahoe-* | thumb-* \
+- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
++ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
++ | tahoe-* \
++ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
++ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+- | v850-* | v850e-* | vax-* \
++ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
++ | vax-* \
+ | we32k-* \
+- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
++ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+@@ -410,7 +463,7 @@
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+- abacus)
++ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+@@ -480,11 +533,20 @@
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
++ c54x-*)
++ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
++ c55x-*)
++ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
++ c6x-*)
++ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+- cegcc)
++ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+@@ -516,7 +578,7 @@
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+- cr16)
++ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+@@ -674,7 +736,6 @@
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+@@ -732,11 +793,15 @@
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+- microblaze)
++ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
++ mingw64)
++ basic_machine=x86_64-pc
++ os=-mingw64
++ ;;
+ mingw32)
+- basic_machine=i386-pc
++ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+@@ -764,6 +829,10 @@
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
++ moxiebox)
++ basic_machine=moxie-unknown
++ os=-moxiebox
++ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+@@ -771,10 +840,18 @@
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
++ msys)
++ basic_machine=i686-pc
++ os=-msys
++ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
++ nacl)
++ basic_machine=le32-unknown
++ os=-nacl
++ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+@@ -839,6 +916,12 @@
+ np1)
+ basic_machine=np1-gould
+ ;;
++ neo-tandem)
++ basic_machine=neo-tandem
++ ;;
++ nse-tandem)
++ basic_machine=nse-tandem
++ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+@@ -921,9 +1004,10 @@
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+- ppc) basic_machine=powerpc-unknown
++ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ppc-* | ppcbe-*)
++ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+@@ -948,7 +1032,11 @@
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+- rdos)
++ rdos | rdos64)
++ basic_machine=x86_64-pc
++ os=-rdos
++ ;;
++ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+@@ -1017,6 +1105,9 @@
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
++ strongarm-* | thumb-*)
++ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+@@ -1073,20 +1164,8 @@
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+- tic54x | c54x*)
+- basic_machine=tic54x-unknown
+- os=-coff
+- ;;
+- tic55x | c55x*)
+- basic_machine=tic55x-unknown
+- os=-coff
+- ;;
+- tic6x | c6x*)
+- basic_machine=tic6x-unknown
+- os=-coff
+- ;;
+ tile*)
+- basic_machine=tile-unknown
++ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+@@ -1156,6 +1235,9 @@
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
++ xscale-* | xscalee[bl]-*)
++ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
++ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+@@ -1253,11 +1335,11 @@
+ if [ x"$os" != x"" ]
+ then
+ case $os in
+- # First match some system type aliases
+- # that might get confused with valid system types.
++ # First match some system type aliases
++ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+- -auroraux)
+- os=-auroraux
++ -auroraux)
++ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+@@ -1281,28 +1363,29 @@
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+- | -sym* | -kopensolaris* \
++ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+- | -openbsd* | -solidbsd* \
++ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+- | -uxpv* | -beos* | -mpeix* | -udk* \
++ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
++ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
++ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
++ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
++ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+@@ -1341,7 +1424,7 @@
+ -opened*)
+ os=-openedition
+ ;;
+- -os400*)
++ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+@@ -1390,7 +1473,7 @@
+ -sinix*)
+ os=-sysv4
+ ;;
+- -tpf*)
++ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+@@ -1426,15 +1509,14 @@
+ -aros*)
+ os=-aros
+ ;;
+- -kaos*)
+- os=-kaos
+- ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
++ -nacl*)
++ ;;
+ -none)
+ ;;
+ *)
+@@ -1457,10 +1539,10 @@
+ # system, and we'll never get to this point.
+
+ case $basic_machine in
+- score-*)
++ score-*)
+ os=-elf
+ ;;
+- spu-*)
++ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+@@ -1472,8 +1554,23 @@
+ arm*-semi)
+ os=-aout
+ ;;
+- c4x-* | tic4x-*)
+- os=-coff
++ c4x-* | tic4x-*)
++ os=-coff
++ ;;
++ c8051-*)
++ os=-elf
++ ;;
++ hexagon-*)
++ os=-elf
++ ;;
++ tic54x-*)
++ os=-coff
++ ;;
++ tic55x-*)
++ os=-coff
++ ;;
++ tic6x-*)
++ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+@@ -1493,14 +1590,11 @@
+ ;;
+ m68000-sun)
+ os=-sunos3
+- # This also exists in the configure program, but was not the
+- # default.
+- # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+- mep-*)
++ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+@@ -1527,7 +1621,7 @@
+ *-ibm)
+ os=-aix
+ ;;
+- *-knuth)
++ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
diff --git a/Tools/gtk/patches/libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch b/Tools/gtk/patches/libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch
new file mode 100644
index 000000000..67545df38
--- /dev/null
+++ b/Tools/gtk/patches/libsoup-auth-Fix-async-authentication-when-flag-SOUP_MESSAGE.patch
@@ -0,0 +1,130 @@
+From afee3002ff45b7a00df3d6804fa7d329b907d361 Mon Sep 17 00:00:00 2001
+From: Carlos Garcia Campos <cgarcia@igalia.com>
+Date: Mon, 30 Jan 2017 13:57:12 +0100
+Subject: [PATCH 1/2] auth: Fix async authentication when flag
+ SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is used
+
+When the flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is used, it's not possible
+to successfully authenticate, and SOUP_STATUS_UNAUTHORIZED is always
+returned even when soup_auth_autenticate was called with the right
+credentials. This happens because we set the auth on the soup message right
+after emitting the authenticate signal only if it was authenticated. If the
+signal pauses the message, the auth will no longer be associated to the message,
+and not cached either because flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is
+present. Since we always check if the auth returned by
+soup_auth_get_message is ready before trying to use it, we can simply
+always set the auth on the mssage right after emitting the authenticate
+signal even if it was not authenticated yet. If it's eventually
+authenticated then got-body callback will check it's ready to re-queue
+the message as expected.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=777936
+---
+ libsoup/soup-auth-manager.c | 4 +--
+ tests/auth-test.c | 61 +++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 63 insertions(+), 2 deletions(-)
+
+diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
+index 704661bc..9ff446cc 100644
+--- a/libsoup/soup-auth-manager.c
++++ b/libsoup/soup-auth-manager.c
+@@ -625,7 +625,7 @@ auth_got_headers (SoupMessage *msg, gpointer manager)
+ /* If we need to authenticate, try to do it. */
+ authenticate_auth (manager, auth, msg,
+ prior_auth_failed, FALSE, TRUE);
+- soup_message_set_auth (msg, soup_auth_is_ready (auth, msg) ? auth : NULL);
++ soup_message_set_auth (msg, auth);
+ g_object_unref (auth);
+ g_mutex_unlock (&priv->lock);
+ }
+@@ -689,7 +689,7 @@ proxy_auth_got_headers (SoupMessage *msg, gpointer manager)
+ /* If we need to authenticate, try to do it. */
+ authenticate_auth (manager, auth, msg,
+ prior_auth_failed, TRUE, TRUE);
+- soup_message_set_proxy_auth (msg, soup_auth_is_ready (auth, msg) ? auth : NULL);
++ soup_message_set_proxy_auth (msg, auth);
+ g_object_unref (auth);
+ g_mutex_unlock (&priv->lock);
+ }
+diff --git a/tests/auth-test.c b/tests/auth-test.c
+index b674c61c..23e22133 100644
+--- a/tests/auth-test.c
++++ b/tests/auth-test.c
+@@ -1336,6 +1336,66 @@ do_message_do_not_use_auth_cache_test (void)
+ }
+
+ static void
++async_no_auth_cache_authenticate (SoupSession *session, SoupMessage *msg,
++ SoupAuth *auth, gboolean retrying, SoupAuth **auth_out)
++{
++ debug_printf (1, " async_no_auth_cache_authenticate\n");
++
++ soup_session_pause_message (session, msg);
++ *auth_out = g_object_ref (auth);
++ g_main_loop_quit (loop);
++}
++
++static void
++async_no_auth_cache_finished (SoupSession *session, SoupMessage *msg, gpointer user_data)
++{
++ debug_printf (1, " async_no_auth_cache_finished\n");
++
++ g_main_loop_quit (loop);
++}
++
++static void
++do_async_message_do_not_use_auth_cache_test (void)
++{
++ SoupSession *session;
++ SoupMessage *msg;
++ char *uri;
++ SoupAuth *auth = NULL;
++ SoupMessageFlags flags;
++
++ SOUP_TEST_SKIP_IF_NO_APACHE;
++
++ loop = g_main_loop_new (NULL, TRUE);
++ session = soup_test_session_new (SOUP_TYPE_SESSION_ASYNC, NULL);
++ uri = g_strconcat (base_uri, "Basic/realm1/", NULL);
++
++ msg = soup_message_new ("GET", uri);
++ g_free (uri);
++ g_signal_connect (session, "authenticate",
++ G_CALLBACK (async_no_auth_cache_authenticate), &auth);
++ flags = soup_message_get_flags (msg);
++ soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
++ g_object_ref (msg);
++ soup_session_queue_message (session, msg, async_no_auth_cache_finished, NULL);
++ g_main_loop_run (loop);
++
++ soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
++
++ soup_test_assert (auth, "msg didn't get authenticate signal");
++ soup_auth_authenticate (auth, "user1", "realm1");
++ g_object_unref (auth);
++
++ soup_session_unpause_message (session, msg);
++ g_main_loop_run (loop);
++
++ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
++
++ soup_test_session_abort_unref (session);
++ g_object_unref (msg);
++ g_main_loop_unref (loop);
++}
++
++static void
+ has_authorization_header_authenticate (SoupSession *session, SoupMessage *msg,
+ SoupAuth *auth, gboolean retrying, gpointer data)
+ {
+@@ -1432,6 +1492,7 @@ main (int argc, char **argv)
+ g_test_add_func ("/auth/disappearing-auth", do_disappearing_auth_test);
+ g_test_add_func ("/auth/clear-credentials", do_clear_credentials_test);
+ g_test_add_func ("/auth/message-do-not-use-auth-cache", do_message_do_not_use_auth_cache_test);
++ g_test_add_func ("/auth/async-message-do-not-use-auth-cache", do_async_message_do_not_use_auth_cache_test);
+ g_test_add_func ("/auth/authorization-header-request", do_message_has_authorization_header_test);
+
+ ret = g_test_run ();
+--
+2.11.0
+
diff --git a/Tools/gtk/patches/libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch b/Tools/gtk/patches/libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch
new file mode 100644
index 000000000..7d3ab58b2
--- /dev/null
+++ b/Tools/gtk/patches/libsoup-auth-do-not-use-cached-credentials-in-lookup-method-.patch
@@ -0,0 +1,114 @@
+From c8401c372adc9a9cb11fc870c390affb10379cfa Mon Sep 17 00:00:00 2001
+From: Carlos Garcia Campos <cgarcia@igalia.com>
+Date: Sat, 11 Feb 2017 17:44:46 +0100
+Subject: [PATCH 2/2] auth: do not use cached credentials in lookup method when
+ flag SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE is present
+
+This is causing that a request with flag
+SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE success if a previous request without
+the flag stored the credentials. This patch also fixes another issues
+with the test /auth/message-do-not-use-auth-cache, the case of providing
+the credentials in the url was working because do_digest_nonce_test()
+didn't disconnect the authenticate signal that was actually used. This
+is because soup_uri_to_string removes the password from the uri. The
+test needs to use a custom message created with
+soup_message_new_from_uri() instead of using do_digest_nonce_test().
+
+https://bugzilla.gnome.org/show_bug.cgi?id=778497
+---
+ libsoup/soup-auth-manager.c | 6 ++++++
+ tests/auth-test.c | 29 +++++++++++++++++++++++++----
+ 2 files changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
+index 9ff446cc..b32ba900 100644
+--- a/libsoup/soup-auth-manager.c
++++ b/libsoup/soup-auth-manager.c
+@@ -472,6 +472,9 @@ lookup_auth (SoupAuthManagerPrivate *priv, SoupMessage *msg)
+ if (auth && soup_auth_is_ready (auth, msg))
+ return auth;
+
++ if (soup_message_get_flags (msg) & SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE)
++ return NULL;
++
+ host = get_auth_host_for_uri (priv, soup_message_get_uri (msg));
+ if (!host->auth_realms && !make_auto_ntlm_auth (priv, host))
+ return NULL;
+@@ -496,6 +499,9 @@ lookup_proxy_auth (SoupAuthManagerPrivate *priv, SoupMessage *msg)
+ if (auth && soup_auth_is_ready (auth, msg))
+ return auth;
+
++ if (soup_message_get_flags (msg) & SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE)
++ return NULL;
++
+ return priv->proxy_auth;
+ }
+
+diff --git a/tests/auth-test.c b/tests/auth-test.c
+index 23e22133..2d66da9e 100644
+--- a/tests/auth-test.c
++++ b/tests/auth-test.c
+@@ -442,6 +442,12 @@ do_digest_nonce_test (SoupSession *session,
+ got_401 ? "got" : "did not get");
+ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
+
++ if (expect_signal) {
++ g_signal_handlers_disconnect_by_func (session,
++ G_CALLBACK (digest_nonce_authenticate),
++ NULL);
++ }
++
+ g_object_unref (msg);
+ }
+
+@@ -1297,9 +1303,10 @@ do_message_do_not_use_auth_cache_test (void)
+ {
+ SoupSession *session;
+ SoupAuthManager *manager;
++ SoupMessage *msg;
++ SoupMessageFlags flags;
+ SoupURI *soup_uri;
+ char *uri;
+- char *uri_with_credentials;
+
+ SOUP_TEST_SKIP_IF_NO_APACHE;
+
+@@ -1318,18 +1325,32 @@ do_message_do_not_use_auth_cache_test (void)
+ soup_uri = soup_uri_new (uri);
+ soup_uri_set_user (soup_uri, "user1");
+ soup_uri_set_password (soup_uri, "realm1");
+- uri_with_credentials = soup_uri_to_string (soup_uri, FALSE);
++ msg = soup_message_new_from_uri (SOUP_METHOD_GET, soup_uri);
++ flags = soup_message_get_flags (msg);
++ soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
++ soup_session_send_message (session, msg);
++ soup_test_assert_message_status (msg, SOUP_STATUS_OK);
++ g_object_unref (msg);
+ soup_uri_free (soup_uri);
+- do_digest_nonce_test (session, "Fourth", uri_with_credentials, FALSE, TRUE, FALSE);
+- g_free (uri_with_credentials);
+
+ manager = SOUP_AUTH_MANAGER (soup_session_get_feature (session, SOUP_TYPE_AUTH_MANAGER));
++
+ soup_auth_manager_clear_cached_credentials (manager);
+
+ /* Now check that credentials are not stored */
+ do_digest_nonce_test (session, "First", uri, FALSE, TRUE, TRUE);
+ do_digest_nonce_test (session, "Second", uri, TRUE, TRUE, TRUE);
+ do_digest_nonce_test (session, "Third", uri, TRUE, FALSE, FALSE);
++
++ /* Credentials were stored for uri, but if we set SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE flag,
++ * and we don't have the authenticate signal, it should respond with 401
++ */
++ msg = soup_message_new (SOUP_METHOD_GET, uri);
++ flags = soup_message_get_flags (msg);
++ soup_message_set_flags (msg, flags | SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE);
++ soup_session_send_message (session, msg);
++ soup_test_assert_message_status (msg, SOUP_STATUS_UNAUTHORIZED);
++ g_object_unref (msg);
+ g_free (uri);
+
+ soup_test_session_abort_unref (session);
+--
+2.11.0
+
diff --git a/Tools/gtk/patches/mesa-gallivm-Fix-build-after-LLVM-commit-211259.patch b/Tools/gtk/patches/mesa-gallivm-Fix-build-after-LLVM-commit-211259.patch
new file mode 100644
index 000000000..75f38e552
--- /dev/null
+++ b/Tools/gtk/patches/mesa-gallivm-Fix-build-after-LLVM-commit-211259.patch
@@ -0,0 +1,29 @@
+From 564821c917f4a9d5a0de2ee77b90b0cd85e3d3a6 Mon Sep 17 00:00:00 2001
+From: Aaron Watry <awatry@gmail.com>
+Date: Fri, 20 Jun 2014 19:13:30 -0500
+Subject: [PATCH] gallivm: Fix build after LLVM commit 211259
+
+Signed-off-by: Aaron Watry <awatry@gmail.com>
+Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
+---
+ src/gallium/auxiliary/gallivm/lp_bld_debug.cpp | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
+index df26883..413a0c2 100644
+--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
++++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp
+@@ -51,7 +51,9 @@
+ #include <llvm/MC/MCInstPrinter.h>
+ #include <llvm/MC/MCRegisterInfo.h>
+
+-#if HAVE_LLVM >= 0x0303
++#if HAVE_LLVM >= 0x0305
++#define OwningPtr std::unique_ptr
++#elif HAVE_LLVM >= 0x0303
+ #include <llvm/ADT/OwningPtr.h>
+ #endif
+
+--
+2.1.0
+
diff --git a/Tools/gtk/patches/openh264-configure.patch b/Tools/gtk/patches/openh264-configure.patch
new file mode 100644
index 000000000..7bf1bd5a1
--- /dev/null
+++ b/Tools/gtk/patches/openh264-configure.patch
@@ -0,0 +1,12 @@
+--- /dev/null 2015-06-05 15:20:34.000000000 +1000
++++ pseudo-configure 2015-06-05 15:20:37.000000000 +1000
+@@ -0,0 +1,8 @@
++#!/bin/sh
++
++X=Makefile
++sed -e "s:^PREFIX=.*:PREFIX=$JHBUILD_PREFIX:" ${X} > ${X}.tmp && mv ${X}.tmp ${X}
++sed -e "s:^SHAREDLIB_DIR=.*:SHAREDLIB_DIR=$CMAKE_LIBRARY_PATH:" ${X} > ${X}.tmp && mv ${X}.tmp ${X}
++
++X=build/x86-common.mk
++sed -e "s:^ASM =.*:ASM = yasm:" $X > ${X}.tmp && mv ${X}.tmp $X
+
diff --git a/Tools/gtk/patches/rtspsrc-timeout-on-udpsrc-is-in-nanoseconds.patch b/Tools/gtk/patches/rtspsrc-timeout-on-udpsrc-is-in-nanoseconds.patch
new file mode 100644
index 000000000..87ed49087
--- /dev/null
+++ b/Tools/gtk/patches/rtspsrc-timeout-on-udpsrc-is-in-nanoseconds.patch
@@ -0,0 +1,27 @@
+From e0bb1fe30985aa0784825388500cc4fa92c1ff9c Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wim.taymans@collabora.co.uk>
+Date: Wed, 12 Dec 2012 11:09:42 +0100
+Subject: [PATCH 2/2] rtspsrc: timeout on udpsrc is in nanoseconds
+
+---
+ gst/rtsp/gstrtspsrc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
+index 98577b8..902d8ff 100644
+--- a/gst/rtsp/gstrtspsrc.c
++++ b/gst/rtsp/gstrtspsrc.c
+@@ -2812,8 +2812,8 @@ gst_rtspsrc_stream_configure_udp (GstRTSPSrc * src, GstRTSPStream * stream,
+ /* configure a timeout on the UDP port. When the timeout message is
+ * posted, we assume UDP transport is not possible. We reconnect using TCP
+ * if we can. */
+- g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout", src->udp_timeout,
+- NULL);
++ g_object_set (G_OBJECT (stream->udpsrc[0]), "timeout",
++ src->udp_timeout * 1000, NULL);
+
+ /* get output pad of the UDP source. */
+ *outpad = gst_element_get_static_pad (stream->udpsrc[0], "src");
+--
+1.8.1.2
+
diff --git a/Tools/gtk/patches/shared-mime-info-xht-glob.patch b/Tools/gtk/patches/shared-mime-info-xht-glob.patch
new file mode 100644
index 000000000..667ae4991
--- /dev/null
+++ b/Tools/gtk/patches/shared-mime-info-xht-glob.patch
@@ -0,0 +1,21 @@
+From 6e5818deb54fdfa70f5798fc1df1d5c3eaba42df Mon Sep 17 00:00:00 2001
+From: Bastien Nocera <hadess@hadess.net>
+Date: Thu, 7 Jan 2016 15:48:47 +0100
+Subject: Add *.xht as a glob for XHTML files
+
+
+diff --git a/freedesktop.org.xml.in b/freedesktop.org.xml.in
+index dc12655..48696d9 100644
+--- a/freedesktop.org.xml.in
++++ b/freedesktop.org.xml.in
+@@ -3669,6 +3669,7 @@ command to generate the output files.
+ <sub-class-of type="application/xml"/>
+ <generic-icon name="text-html"/>
+ <glob pattern="*.xhtml"/>
++ <glob pattern="*.xht"/>
+ <root-XML namespaceURI='http://www.w3.org/1999/xhtml' localName='html'/>
+ </mime-type>
+ <mime-type type="application/zip">
+--
+cgit v0.10.2
+
diff --git a/Tools/gtk/patches/shared-mime-info-xhtml-magic.patch b/Tools/gtk/patches/shared-mime-info-xhtml-magic.patch
new file mode 100644
index 000000000..4d0e81615
--- /dev/null
+++ b/Tools/gtk/patches/shared-mime-info-xhtml-magic.patch
@@ -0,0 +1,26 @@
+From 4961dc3e48d13c0c675ad7c135419b864813ca55 Mon Sep 17 00:00:00 2001
+From: Bastien Nocera <hadess@hadess.net>
+Date: Thu, 7 Jan 2016 15:49:16 +0100
+Subject: Add magic for XHTML files
+
+
+diff --git a/freedesktop.org.xml.in b/freedesktop.org.xml.in
+index 48696d9..9ea2f95 100644
+--- a/freedesktop.org.xml.in
++++ b/freedesktop.org.xml.in
+@@ -3670,6 +3670,12 @@ command to generate the output files.
+ <generic-icon name="text-html"/>
+ <glob pattern="*.xhtml"/>
+ <glob pattern="*.xht"/>
++ <magic priority="60">
++ <match type="string" value="//W3C//DTD XHTML " offset="0:256"/>
++ <match type="string" value="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" offset="0:256"/>
++ <match type="string" value="&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml" offset="0:256"/>
++ <match type="string" value="&lt;HTML xmlns=&quot;http://www.w3.org/1999/xhtml" offset="0:256"/>
++ </magic>
+ <root-XML namespaceURI='http://www.w3.org/1999/xhtml' localName='html'/>
+ </mime-type>
+ <mime-type type="application/zip">
+--
+cgit v0.10.2
+
diff --git a/Tools/gtk/patches/udpsrc-improve-timeouts.patch b/Tools/gtk/patches/udpsrc-improve-timeouts.patch
new file mode 100644
index 000000000..d26e346a8
--- /dev/null
+++ b/Tools/gtk/patches/udpsrc-improve-timeouts.patch
@@ -0,0 +1,53 @@
+From dbbdf54778771535dfea5ddbdeeaba89d9bc7be6 Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wim.taymans@collabora.co.uk>
+Date: Wed, 12 Dec 2012 11:08:13 +0100
+Subject: [PATCH 1/2] udpsrc: improve timeouts
+
+Make it possible to set the timeout after we went to the READY state by using
+the timeout when checking the condition. This also makes it possible to set the
+timeout with a higher granularity than seconds.
+---
+ gst/udp/gstudpsrc.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/gst/udp/gstudpsrc.c b/gst/udp/gstudpsrc.c
+index bdad5b3..5b54021 100644
+--- a/gst/udp/gstudpsrc.c
++++ b/gst/udp/gstudpsrc.c
+@@ -397,13 +397,20 @@ retry:
+ goto no_select;
+
+ do {
++ gint64 timeout;
++
+ try_again = FALSE;
+
++ if (udpsrc->timeout)
++ timeout = udpsrc->timeout / 1000;
++ else
++ timeout = -1;
++
+ GST_LOG_OBJECT (udpsrc, "doing select, timeout %" G_GUINT64_FORMAT,
+- udpsrc->timeout);
++ timeout);
+
+- if (!g_socket_condition_wait (udpsrc->used_socket, G_IO_IN | G_IO_PRI,
+- udpsrc->cancellable, &err)) {
++ if (!g_socket_condition_timed_wait (udpsrc->used_socket, G_IO_IN | G_IO_PRI,
++ timeout, udpsrc->cancellable, &err)) {
+ if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_BUSY)
+ || g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ goto stopped;
+@@ -823,9 +830,6 @@ gst_udpsrc_start (GstBaseSrc * bsrc)
+ goto getsockname_error;
+ }
+
+- if (src->timeout)
+- g_socket_set_timeout (src->used_socket, src->timeout / GST_SECOND);
+-
+ #if GLIB_CHECK_VERSION (2, 35, 7)
+ {
+ gint val = 0;
+--
+1.8.1.2
+
diff --git a/Tools/gtk/patches/xserver-remove-bogus-dependencies.patch b/Tools/gtk/patches/xserver-remove-bogus-dependencies.patch
new file mode 100644
index 000000000..e17753e37
--- /dev/null
+++ b/Tools/gtk/patches/xserver-remove-bogus-dependencies.patch
@@ -0,0 +1,43 @@
+From 879f42531ff04be578c39f9d44548aeb3ded67fd Mon Sep 17 00:00:00 2001
+From: Gustavo Noronha Silva <gustavo.noronha@collabora.com>
+Date: Wed, 8 May 2013 19:44:15 -0300
+Subject: [PATCH 2/2] Filter out -l parameters when setting dependencies
+
+Newer make (Fedora 19) gets confused when it finds a -l parameter in a
+dependency, and tries to make it as a target, causing the build to fail.
+
+Signed-off-by: Gustavo Noronha Silva <gustavo.noronha@collabora.com>
+---
+ hw/vfb/Makefile.am | 2 +-
+ test/Makefile.am | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/vfb/Makefile.am b/hw/vfb/Makefile.am
+index 9f4992c..06830ae 100644
+--- a/hw/vfb/Makefile.am
++++ b/hw/vfb/Makefile.am
+@@ -20,7 +20,7 @@ XVFB_LIBS = \
+ $(top_builddir)/Xi/libXistubs.la
+
+ Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS)
+-Xvfb_DEPENDENCIES = $(XVFB_LIBS)
++Xvfb_DEPENDENCIES = $(filter-out -l%,$(XVFB_LIBS))
+ Xvfb_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
+
+ relink:
+diff --git a/test/Makefile.am b/test/Makefile.am
+index 34f53fc..3509306 100644
+--- a/test/Makefile.am
++++ b/test/Makefile.am
+@@ -131,7 +131,7 @@ libxservertest_la_LIBADD += \
+ endif
+ endif
+
+-libxservertest_la_DEPENDENCIES = $(libxservertest_la_LIBADD)
++libxservertest_la_DEPENDENCIES = $(filter-out -l%,$(libxservertest_la_LIBADD))
+ endif
+
+ EXTRA_DIST = ddxstubs.c
+--
+1.8.2.1
+
diff --git a/Tools/gtk/patches/xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch b/Tools/gtk/patches/xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch
new file mode 100644
index 000000000..ad380c851
--- /dev/null
+++ b/Tools/gtk/patches/xserver-search-for-DRI-drivers-at-LIBGL_DRIVERS_PATH-environ.patch
@@ -0,0 +1,84 @@
+From fcbd29debee422bcb147057a089fd1da5e699656 Mon Sep 17 00:00:00 2001
+From: Carlos Alberto Lopez Perez <clopez@igalia.com>
+Date: Wed, 23 Mar 2016 03:47:58 +0100
+Subject: [PATCH xserver] Search for DRI drivers at LIBGL_DRIVERS_PATH
+ environment variable.
+
+ * The Mesa driver uses this environment variable to override the
+ default compiled search path for DRI drivers.
+
+ * This is useful for testing purposes when the user needs to
+ override the system default one at runtime.
+---
+ glx/glxdricommon.c | 40 ++++++++++++++++++++++++++++++----------
+ 1 file changed, 30 insertions(+), 10 deletions(-)
+
+diff --git a/glx/glxdricommon.c b/glx/glxdricommon.c
+index 62cce13..543f631 100644
+--- a/glx/glxdricommon.c
++++ b/glx/glxdricommon.c
+@@ -246,8 +246,6 @@ glxConvertConfigs(const __DRIcoreExtension * core,
+ return head.next;
+ }
+
+-static const char dri_driver_path[] = DRI_DRIVER_PATH;
+-
+ /* Temporary define to allow building without a dri_interface.h from
+ * updated Mesa. Some day when we don't care about Mesa that old any
+ * more this can be removed.
+@@ -261,22 +259,44 @@ glxProbeDriver(const char *driverName,
+ void **coreExt, const char *coreName, int coreVersion,
+ void **renderExt, const char *renderName, int renderVersion)
+ {
+- int i;
++ int i, len;
+ void *driver;
+ char filename[PATH_MAX];
+ char *get_extensions_name;
+ const __DRIextension **extensions = NULL;
++ const char *dri_driver_path, *p, *next;
+
+- snprintf(filename, sizeof filename, "%s/%s_dri.so",
+- dri_driver_path, driverName);
++ dri_driver_path = getenv("LIBGL_DRIVERS_PATH");
++
++ if (dri_driver_path == NULL)
++ dri_driver_path = DRI_DRIVER_PATH;
++
++ for (p = dri_driver_path; *p; p = next) {
++ next = strchr(p, ':');
++ if (next == NULL) {
++ len = strlen(p);
++ next = p + len;
++ }
++ else {
++ len = next - p;
++ next++;
++ }
++
++ snprintf(filename, sizeof filename, "%.*s/%s_dri.so",
++ len, p, driverName);
++
++ driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
++ if (driver == NULL)
++ LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
++ filename, dlerror());
++ else
++ break;
+
+- driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+- if (driver == NULL) {
+- LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
+- filename, dlerror());
+- goto cleanup_failure;
+ }
+
++ if (driver == NULL)
++ goto cleanup_failure;
++
+ if (asprintf(&get_extensions_name, "%s_%s",
+ __DRI_DRIVER_GET_EXTENSIONS, driverName) != -1) {
+ const __DRIextension **(*get_extensions)(void);
+--
+2.1.4
+
diff --git a/Tools/gtk/webkitdom.py b/Tools/gtk/webkitdom.py
deleted file mode 100755
index 221defba6..000000000
--- a/Tools/gtk/webkitdom.py
+++ /dev/null
@@ -1,285 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2013 Igalia S.L.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301 USA
-
-import common
-import os
-import re
-import sys
-
-from ConfigParser import SafeConfigParser
-
-
-class WebKitDOMDocGenerator(object):
-
- DELETED_CLASSES = [
- "WebKitDOMBarInfo",
- "WebKitDOMHTMLPropertiesCollection",
- "WebKitDOMMemoryInfo",
- "WebKitDOMMicroDataItemValue",
- "WebKitDOMPropertyNodeList"]
-
- def __init__(self, symbol_files, file_handle):
- self._symbol_files = symbol_files
- self._file_handle = file_handle
-
- def write_header(self):
- pass
-
- def write_section(self, symbol_file):
- raise NotImplementedError
-
- def write_deleted_classes(self):
- raise NotImplementedError
-
- def write_footer(self):
- pass
-
- def write(self, string):
- self._file_handle.write(string)
-
- @staticmethod
- def is_deprecated_symbol_file(file_path):
- return 'WebKitDOMDeprecated' in file_path
-
- def generate(self):
- self.write_header()
- for symbol_file in self._symbol_files:
- if WebKitDOMDocGenerator.is_deprecated_symbol_file(symbol_file):
- continue
- self.write_section(symbol_file)
- self.write_deleted_classes()
- self.write_footer()
-
-
-class WebKitDOMDocGeneratorSGML(WebKitDOMDocGenerator):
- def write_header(self):
- self.write('''<?xml version="1.0"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
-<!ENTITY version SYSTEM "version.xml">
-]>
-<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
- <bookinfo>
- <title>WebKitDOMGTK+ Reference Manual</title>
- <releaseinfo>for WebKitDOMGTK+ &version;</releaseinfo>
- </bookinfo>
-
- <chapter>
- <title>Class Overview</title>
-''')
-
- def write_section(self, symbol_file):
- basename = os.path.basename(symbol_file)
- self.write(' <xi:include href="xml/%s"/>\n' % basename.replace(".symbols", ".xml"))
-
- def write_deleted_classes(self):
- for class_name in self.DELETED_CLASSES:
- self.write(' <xi:include href="xml/%s.xml"/>\n' % class_name)
-
- def write_footer(self):
- self.write(''' </chapter>
-
- <index id="index-all">
- <title>Index</title>
- <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
- </index>
- <index id="api-index-deprecated" role="deprecated">
- <title>Index of deprecated symbols</title>
- <xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
- </index>
-
- <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
-</book>
-''')
-
-
-class WebKitDOMDocGeneratorSections(WebKitDOMDocGenerator):
- def __init__(self, symbol_files, file_handle):
- super(WebKitDOMDocGeneratorSections, self).__init__(symbol_files, file_handle)
-
- self._first_decamelize_re = re.compile('(.)([A-Z][a-z]+)')
- self._second_decamelize_re = re.compile('([a-z0-9])([A-Z])')
- self._dom_class_re = re.compile('(^WebKitDOM)(.+)$')
- self._function_re = re.compile('^.+ (.+)\((.+)\)$')
-
- self.deprecated_symbosl = {}
- for symbol_file in symbol_files:
- if WebKitDOMDocGenerator.is_deprecated_symbol_file(symbol_file):
- self._deprecated_symbols = self._find_deprecated_symbols(symbol_file)
- break
-
- def _dom_class(self, class_name):
- return self._dom_class_re.sub(r'\2', class_name)
-
- def _dom_class_decamelize(self, class_name):
- s1 = self._first_decamelize_re.sub(r'\1_\2', self._dom_class(class_name))
- retval = self._second_decamelize_re.sub(r'\1_\2', s1)
-
- # Fix some exceptions.
- retval = retval.replace('Web_Kit', 'WebKit')
- retval = retval.replace('X_Path', 'XPath')
- retval = retval.replace('HTMLI_Frame', 'HTML_IFrame')
-
- return retval
-
- def _deleted_class(self, function):
- for deleted_class in self.DELETED_CLASSES:
- decamelized = 'webkit_dom_%s' % self._dom_class_decamelize(deleted_class).lower()
- if function.startswith(decamelized):
- return deleted_class
- return None
-
- def _find_deprecated_symbols(self, symbol_file):
- retval = {}
- f = open(symbol_file, 'r')
- for line in f.readlines():
- match = self._function_re.match(line)
- if not match:
- continue
-
- function = match.group(1)
- args = match.group(2).split(', ')
- class_name = args[0].strip('*')
- if class_name == 'void':
- class_name = self._deleted_class(function)
-
- retval.setdefault(class_name, []).append(function)
-
- return retval
-
- def _symbol_list(self, symbol_file):
- retval = []
- f = open(symbol_file, 'r')
- for line in f.readlines():
- match = self._function_re.match(line)
- if not match or match.group(1).endswith('get_type'):
- continue
- retval.append(match.group(1))
-
- return retval
-
- def write_section(self, symbol_file):
- class_name = os.path.basename(symbol_file).replace(".symbols", "")
- is_custom = class_name == 'WebKitDOMCustom'
- is_interface = class_name == 'WebKitDOMEventTarget'
- is_object = class_name == 'WebKitDOMObject'
- self.write('<SECTION>\n')
- self.write('<FILE>%s</FILE>\n<TITLE>%s</TITLE>\n' % (class_name, class_name))
- if not is_custom:
- self.write('%s\n' % class_name)
- self.write('\n')
- self.write('\n'.join(self._symbol_list(symbol_file)) + '\n')
- try:
- deprecated_functions = self._deprecated_symbols[class_name]
- self.write('\n'.join(deprecated_functions) + '\n')
- except KeyError:
- pass
- if not is_custom:
- self.write('\n<SUBSECTION Standard>\n')
- self.write('%sClass\n' % class_name)
- dom_class = self._dom_class_decamelize(class_name).upper()
- self.write('WEBKIT_TYPE_DOM_%s\n' % dom_class)
- self.write('WEBKIT_DOM_%s\n' % dom_class)
- if is_object:
- self.write('WEBKIT_IS_DOM_%s\n' % dom_class)
- else:
- self.write('WEBKIT_DOM_IS_%s\n' % dom_class)
- self.write('WEBKIT_DOM_%s_CLASS\n' % dom_class)
- if is_interface:
- self.write('WEBKIT_DOM_%s_GET_IFACE\n' % dom_class)
- else:
- if is_object:
- self.write('WEBKIT_IS_DOM_%s_CLASS\n' % dom_class)
- else:
- self.write('WEBKIT_DOM_IS_%s_CLASS\n' % dom_class)
- self.write('WEBKIT_DOM_%s_GET_CLASS\n' % dom_class)
- self.write('\n<SUBSECTION Private>\n')
- if is_object:
- self.write('%sPrivate\n' % class_name)
- self.write('webkit_dom_%s_get_type\n' % dom_class.lower())
- self.write('</SECTION>\n\n')
-
- def write_deleted_classes(self):
- for class_name in self.DELETED_CLASSES:
- self.write('<SECTION>\n')
- self.write('<FILE>%s</FILE>\n<TITLE>%s</TITLE>\n' % (class_name, class_name))
- self.write('\n'.join([name for name in self._deprecated_symbols[class_name] if not name.endswith('get_type')]) + '\n')
- self.write('\n<SUBSECTION Private>\n')
- self.write('webkit_dom_%s_get_type\n' % self._dom_class_decamelize(class_name).lower())
- self.write('</SECTION>\n\n')
-
- def write_footer(self):
- self.write('<SECTION>\n')
- self.write('<FILE>webkitdomdefines</FILE>\n<TITLE>WebKitDOMDefines</TITLE>\n')
- self.write('<SUBSECTION Private>\n')
- self.write('WEBKIT_API\nWEBKIT_DEPRECATED\nWEBKIT_DEPRECATED_FOR\n')
- self.write('</SECTION>\n\n')
-
-
-def write_doc_files():
- doc_dir = common.build_path('DerivedSources', 'webkitdom', 'docs')
-
- try:
- os.mkdir(doc_dir)
- except:
- pass # Commonly happens if the directory already exists.
-
- with open(os.path.join(doc_dir, 'webkitdomgtk-sections.txt'), 'w') as sections_file:
- generator = WebKitDOMDocGeneratorSections(get_all_webkitdom_symbol_files(), sections_file)
- generator.generate()
- with open(os.path.join(doc_dir, 'webkitdomgtk-docs.sgml'), 'w') as sgml_file:
- generator = WebKitDOMDocGeneratorSGML(get_all_webkitdom_symbol_files(), sgml_file)
- generator.generate()
-
-
-def header_name_list_from_gtkdoc_config_file():
- config_file = common.build_path('gtkdoc-webkitdom.cfg')
- if not os.path.isfile(config_file):
- sys.stderr.write("Could not find config file at %s\n" % config_file)
- return sys.exit(1)
-
- config = SafeConfigParser()
- config.read(config_file)
- module_name = config.sections()[0]
- return [os.path.basename(f) for f in str(config.get(module_name, 'headers')).replace(';', ' ').split()]
-
-
-def get_all_webkitdom_symbol_files():
- static_symbol_files_path = common.top_level_path('Source', 'WebCore', 'bindings', 'gobject')
- generated_symbol_files_path = common.build_path('DerivedSources', 'webkitdom')
-
- symbol_files = []
- for header_name in header_name_list_from_gtkdoc_config_file():
- # webkitdomdefines.h doesn't have a corresponding symbols file and webkitdom.symbols is a
- # file containing the expected symbols results.
- if header_name in ("webkitdom.h", "webkitdomdefines.h"):
- continue
-
- symbol_file = header_name.replace(".h", ".symbols")
- path = os.path.join(static_symbol_files_path, symbol_file)
- if os.path.exists(path):
- symbol_files.append(path)
- continue
- path = os.path.join(generated_symbol_files_path, symbol_file)
- if os.path.exists(path):
- symbol_files.append(path)
- continue
- sys.stderr.write("Could not find symbol file for header: %s\n" % header_name)
- sys.exit(1)
-
- return symbol_files
diff --git a/Tools/gtk/ycm_extra_conf.py b/Tools/gtk/ycm_extra_conf.py
new file mode 100644
index 000000000..871e8af8e
--- /dev/null
+++ b/Tools/gtk/ycm_extra_conf.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+# Copyright (C) 2013 Danilo Cesar Lemes de Paula <danilo.eu@gmail.com>
+# Copyright (C) 2014 ChangSeok Oh <shivamidow@gmail.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import sys
+import ycm_core
+
+# It's very likely that this script is a symlink somewhere in the WebKit directory,
+# so we try to find the actual script location so that we can locate the tools
+# directory.
+original_file = __file__[:-1] if __file__.endswith(".pyc") else __file__
+if os.path.islink(original_file):
+ parent_folder = os.path.abspath(os.path.dirname(original_file))
+ link_file = os.path.join(parent_folder, os.readlink(original_file))
+ __tools_directory = os.path.dirname(link_file)
+else:
+ __tools_directory = os.path.dirname(original_file)
+
+sys.path.insert(0, os.path.abspath(__tools_directory))
+import common
+
+
+FLAGS_PRECEDING_PATHS = ['-isystem', '-I', '-iquote', '--sysroot=']
+def transform_relative_paths_to_absolute_paths(arguments, build_path):
+ result = []
+ make_next_absolute = False
+ for argument in arguments:
+ if make_next_absolute:
+ make_next_absolute = False
+ if not argument.startswith('/'):
+ argument = os.path.join(build_path, argument)
+ elif argument in FLAGS_PRECEDING_PATHS:
+ # Some flags precede the path in the list. For those we make the
+ # next argument absolute.
+ make_next_absolute = True
+ else:
+ # Some argument contain the flag and the path together. For these
+ # we parse the argument out of the path.
+ for flag in FLAGS_PRECEDING_PATHS:
+ if argument.startswith(flag):
+ argument = flag + os.path.join(build_path, argument[len(flag):])
+ break
+
+ result.append(argument)
+ return result
+
+
+def get_build_path():
+ webkitbuild_path = os.path.join(common.get_build_path(fatal=False), '..')
+ if not os.path.exists(webkitbuild_path):
+ return None
+
+ release_build_path = os.path.join(webkitbuild_path, 'Release')
+ debug_build_path = os.path.join(webkitbuild_path, 'Debug')
+
+ try:
+ release_mtime = os.path.getmtime(os.path.join(release_build_path, 'compile_commands.json'))
+ except os.error:
+ release_mtime = 0
+ try:
+ debug_mtime = os.path.getmtime(os.path.join(debug_build_path, 'compile_commands.json'))
+ except os.error:
+ debug_mtime = 0
+
+ return release_build_path if release_mtime >= debug_mtime else debug_build_path
+
+
+def FlagsForFile(filename, **kwargs):
+ """This is the main entry point for YCM. Its interface is fixed.
+
+ Args:
+ filename: (String) Path to source file being edited.
+
+ Returns:
+ (Dictionary)
+ 'flags': (List of Strings) Command line flags.
+ 'do_cache': (Boolean) True if the result should be cached.
+ """
+
+ result = {'flags': ['-std=c++11', '-x', 'c++'], 'do_cache': True}
+
+ # Headers can't be built, so we get the source file flags instead.
+ if filename.endswith('.h'):
+ alternative_extensions = ['.cpp', '.c']
+ for alternative_extension in alternative_extensions:
+ alternative_filename = filename[:-2] + alternative_extension
+ if os.path.exists(alternative_filename):
+ filename = alternative_filename
+ break
+ else:
+ return result
+ # Force config.h file inclusion, for GLib macros.
+ result['flags'].append("-includeconfig.h")
+
+ build_path = os.path.normpath(get_build_path())
+ if not build_path:
+ print "Could not find WebKit build path."
+ return result
+
+ database = ycm_core.CompilationDatabase(build_path)
+ if not database:
+ print "Could not find compile_commands.json in %s, You might forget to add CMAKE_EXPORT_COMPILE_COMMANDS=ON to cmakeargs" % build_path
+ return result
+
+ compilation_info = database.GetCompilationInfoForFile(filename)
+ if not compilation_info:
+ print "No compilation info."
+ return result
+
+ result['flags'] = transform_relative_paths_to_absolute_paths(list(compilation_info.compiler_flags_), compilation_info.compiler_working_dir_)
+ return result
+
+
+if __name__ == "__main__":
+ import sys
+ if len(sys.argv) >= 2:
+ print FlagsForFile(sys.argv[1])