summaryrefslogtreecommitdiffstats
path: root/source/xap
diff options
context:
space:
mode:
Diffstat (limited to 'source/xap')
-rwxr-xr-xsource/xap/MPlayer/MPlayer.SlackBuild19
-rw-r--r--source/xap/MPlayer/po_charset.patch12
-rwxr-xr-xsource/xap/NetworkManager-openvpn/NetworkManager-openvpn.SlackBuild2
-rwxr-xr-xsource/xap/audacious-plugins/audacious-plugins.SlackBuild15
-rwxr-xr-xsource/xap/audacious-plugins/audacious-plugins.SlackBuild.meson8
-rwxr-xr-xsource/xap/audacious/audacious.SlackBuild13
-rwxr-xr-xsource/xap/audacious/audacious.SlackBuild.meson8
-rwxr-xr-xsource/xap/blueman/blueman.SlackBuild11
-rwxr-xr-xsource/xap/ddd/ddd.SlackBuild19
-rwxr-xr-xsource/xap/electricsheep/electricsheep.SlackBuild6
-rw-r--r--source/xap/electricsheep/electricsheep.evil.gcc14.diff11
-rwxr-xr-xsource/xap/ffmpegthumbnailer/ffmpegthumbnailer.SlackBuild19
-rw-r--r--source/xap/freerdp/1ef7b9e3.patch28
-rw-r--r--source/xap/freerdp/d0c5b1ae.patch140
-rwxr-xr-xsource/xap/freerdp/freerdp.SlackBuild26
-rwxr-xr-xsource/xap/fvwm/fvwm.SlackBuild3
-rw-r--r--source/xap/geeqie/fix-build-re-docs.diff26
-rwxr-xr-xsource/xap/geeqie/geeqie.SlackBuild8
-rwxr-xr-xsource/xap/gftp/gftp.SlackBuild3
-rwxr-xr-xsource/xap/gimp/gimp.SlackBuild3
-rwxr-xr-xsource/xap/gnuchess/gnuchess.SlackBuild3
-rwxr-xr-xsource/xap/gucharmap/gucharmap.SlackBuild12
-rw-r--r--source/xap/gucharmap/gucharmap.url1
-rwxr-xr-xsource/xap/hexchat/hexchat.SlackBuild2
-rwxr-xr-xsource/xap/mozilla-firefox/mozilla-firefox.SlackBuild11
-rwxr-xr-xsource/xap/mozilla-thunderbird/mozilla-thunderbird.SlackBuild19
-rw-r--r--source/xap/mpv/doinst.sh26
-rw-r--r--source/xap/mpv/dynamically_generate_desktop_file_protocols.patch462
-rwxr-xr-xsource/xap/mpv/mpv.SlackBuild158
-rw-r--r--source/xap/mpv/mpv.url1
-rw-r--r--source/xap/mpv/slack-desc19
-rwxr-xr-xsource/xap/pan/pan.SlackBuild74
-rw-r--r--source/xap/pan/pan.url1
-rwxr-xr-xsource/xap/pavucontrol/pavucontrol.SlackBuild46
-rwxr-xr-xsource/xap/pidgin/pidgin.SlackBuild7
-rwxr-xr-xsource/xap/rdesktop/rdesktop.SlackBuild3
-rwxr-xr-xsource/xap/rxvt-unicode/rxvt-unicode.SlackBuild2
-rwxr-xr-xsource/xap/sane/sane.SlackBuild11
-rwxr-xr-xsource/xap/seamonkey/seamonkey.SlackBuild4
-rw-r--r--source/xap/seamonkey/seamonkey.url1
-rwxr-xr-xsource/xap/seyon/seyon.SlackBuild2
-rw-r--r--source/xap/ssr/0010-plthook.patch2349
-rw-r--r--source/xap/ssr/0020-ffmpeg-7.patch54
-rw-r--r--source/xap/ssr/1000-Fix-build-with-ffmpeg-5.0.patch (renamed from source/xap/ssr/0003-Fix-build-with-ffmpeg-5.0.patch)105
-rw-r--r--source/xap/ssr/1010-appstream-metadata-https-category.patch87
-rw-r--r--source/xap/ssr/2000-private-glinject.patch40
-rw-r--r--source/xap/ssr/3000-more-ffmpeg7-fixup.patch28
-rw-r--r--source/xap/ssr/3001-disable-non-compiling-channel-support.patch11
-rwxr-xr-xsource/xap/ssr/ssr.SlackBuild30
-rwxr-xr-xsource/xap/xaos/xaos.SlackBuild23
-rwxr-xr-xsource/xap/xgames/xgames.SlackBuild8
-rw-r--r--source/xap/xine-lib/xine-lib-1.2.13-ffmpeg6-compatibility.patch196
-rw-r--r--source/xap/xine-lib/xine-lib-1.2.13-ffmpeg6-compatibility_2.patch475
-rw-r--r--source/xap/xine-lib/xine-lib-1.2.13-ffmpeg7-compatibility.patch318
-rw-r--r--source/xap/xine-lib/xine-lib-configure-c99.patch116
-rwxr-xr-xsource/xap/xine-lib/xine-lib.SlackBuild13
-rwxr-xr-xsource/xap/xlockmore/xlockmore.SlackBuild9
-rwxr-xr-xsource/xap/xmms/xmms.SlackBuild5
-rwxr-xr-xsource/xap/xsane/xsane.SlackBuild3
-rwxr-xr-xsource/xap/xscreensaver/xscreensaver.SlackBuild49
-rw-r--r--source/xap/xscreensaver/xscreensaver.setuid.diff179
-rwxr-xr-xsource/xap/xsnow/xsnow.SlackBuild2
62 files changed, 4822 insertions, 523 deletions
diff --git a/source/xap/MPlayer/MPlayer.SlackBuild b/source/xap/MPlayer/MPlayer.SlackBuild
index 44df8d0ff..447b1ccdf 100755
--- a/source/xap/MPlayer/MPlayer.SlackBuild
+++ b/source/xap/MPlayer/MPlayer.SlackBuild
@@ -25,11 +25,11 @@
# Set initial variables:
PKGNAM=MPlayer
-VERSION=${VERSION:-20240403}
+VERSION=${VERSION:-20240812}
# Need to build trunk until there's a stable branch compatible with the
# latest ffmpeg stable release:
#BRANCH=${BRANCH:-1.3} # leave empty if you want to build MPlayer trunk
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-1}
TAG=${TAG:-}
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
@@ -56,7 +56,7 @@ LANGUAGES="en,de,es,fr"
MARCH=$( uname -m )
if [ -z "$ARCH" ]; then
case "$MARCH" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
armv7hl) export ARCH=$MARCH ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
@@ -68,11 +68,10 @@ if [ "$ARCH" = "x86_64" ]; then
LIBDIRSUFFIX="64"
# --enable-runtime-cpudetection is supported only for x86, x86_64, and PPC
EXTRACONFIGUREOPTIONS="--enable-runtime-cpudetection"
-elif [ "$ARCH" = "i486" -o \
- "$ARCH" = "i586" -o \
+elif [ "$ARCH" = "i586" -o \
"$ARCH" = "i686" ]; then
LIBDIRSUFFIX=""
- # --enable-runtime-cpudetection is failing on 32-bit, so we'll set -march=i586
+ # --enable-runtime-cpudetection is failing on 32-bit, so we'll set -march=pentium4
# manually after ./configure.
#EXTRACONFIGUREOPTIONS="--enable-runtime-cpudetection"
EXTRACONFIGUREOPTIONS=""
@@ -251,9 +250,6 @@ fi
# fix building against samba 4:
zcat $SRCDIR/include-samba-4.0.patch.gz | patch -p1 --verbose || exit 1
-# fix building against gettext-0.22.4:
-zcat $SRCDIR/po_charset.patch.gz | patch -p1 --verbose || exit 1
-
echo Building ...
# MPlayer wants to automatically determine compiler flags,
# so we don't provide CFLAGS.
@@ -272,6 +268,7 @@ echo Building ...
--disable-ffmpeg_a \
--codecsdir=${CODECSDIR} \
--language="${LANGUAGES}" \
+ --extra-cflags="-Wno-error=incompatible-pointer-types -Wno-error=int-conversion" \
${EXTRACONFIGUREOPTIONS} \
${DO_PATENTED} || exit 1
@@ -282,8 +279,8 @@ fi
# Set -march/-mtune manually since runtime cpu detection causes a compile error
# on 32-bit x86:
-if [ "$ARCH" = "i586" ]; then
- sed -i "s/march=native/march=i586/g" config.mak
+if [ "$ARCH" = "i686" ]; then
+ sed -i "s/march=native/march=pentium4/g" config.mak
sed -i "s/mtune=native/mtune=generic/g" config.mak
fi
diff --git a/source/xap/MPlayer/po_charset.patch b/source/xap/MPlayer/po_charset.patch
deleted file mode 100644
index 4d7619071..000000000
--- a/source/xap/MPlayer/po_charset.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- ./help/help_create_po.pl.orig 2024-01-30 14:09:03.000000000 -0600
-+++ ./help/help_create_po.pl 2024-01-30 14:10:33.423012066 -0600
-@@ -56,6 +56,9 @@
- open(po, "> $ARGV[1]") or die "Cannot open $ARGV[1]";
-
- print po "# DO NOT EDIT - this file is generated from $ARGV[0]\n";
-+print po "msgid \"\"\n";
-+print po "msgstr \"\"\n";
-+print po "\"Content-Type: text/plain; charset=UTF-8\"\n";
-
- foreach my $id (keys %podefs)
- {
diff --git a/source/xap/NetworkManager-openvpn/NetworkManager-openvpn.SlackBuild b/source/xap/NetworkManager-openvpn/NetworkManager-openvpn.SlackBuild
index a4659ac80..d68ec3f66 100755
--- a/source/xap/NetworkManager-openvpn/NetworkManager-openvpn.SlackBuild
+++ b/source/xap/NetworkManager-openvpn/NetworkManager-openvpn.SlackBuild
@@ -25,7 +25,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=NetworkManager-openvpn
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-1}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
diff --git a/source/xap/audacious-plugins/audacious-plugins.SlackBuild b/source/xap/audacious-plugins/audacious-plugins.SlackBuild
index 65d939a21..c80ffdaee 100755
--- a/source/xap/audacious-plugins/audacious-plugins.SlackBuild
+++ b/source/xap/audacious-plugins/audacious-plugins.SlackBuild
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2017, 2018, 2020 Patrick J. Volkerding, Sebeka, MN, USA
+# Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2017, 2018, 2020, 2024 Patrick J. Volkerding, Sebeka, MN, USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -24,7 +24,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=audacious-plugins
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-3}
# Whether to include faad/aac support:
FAAD=${FAAD:---disable-aac}
@@ -34,7 +34,7 @@ NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -44,14 +44,11 @@ fi
TMP=${TMP:-/tmp}
PKG=$TMP/package-${PKGNAM}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
diff --git a/source/xap/audacious-plugins/audacious-plugins.SlackBuild.meson b/source/xap/audacious-plugins/audacious-plugins.SlackBuild.meson
index bfb33c58f..ab589d3bf 100755
--- a/source/xap/audacious-plugins/audacious-plugins.SlackBuild.meson
+++ b/source/xap/audacious-plugins/audacious-plugins.SlackBuild.meson
@@ -34,7 +34,7 @@ NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -44,14 +44,14 @@ fi
TMP=${TMP:-/tmp}
PKG=$TMP/package-${PKGNAM}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "s390" ]; then
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
diff --git a/source/xap/audacious/audacious.SlackBuild b/source/xap/audacious/audacious.SlackBuild
index 204e96256..f53a2d7fc 100755
--- a/source/xap/audacious/audacious.SlackBuild
+++ b/source/xap/audacious/audacious.SlackBuild
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright 2006-2021 Patrick J. Volkerding, Sebeka, MN, USA
+# Copyright 2006-2024 Patrick J. Volkerding, Sebeka, MN, USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -24,14 +24,14 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=audacious
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -52,11 +52,15 @@ PKG=$TMP/package-${PKGNAM}
if [ "$ARCH" = "i586" ]; then
SLKCFLAGS="-O2 -march=i586 -mtune=i686"
LIBDIRSUFFIX=""
+elif [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
+ SLKLDFLAGS=""
+ LIBDIRSUFFIX=""
elif [ "$ARCH" = "s390" ]; then
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
elif [ "$ARCH" = "arm" ]; then
SLKCFLAGS="-O2 -march=armv4 -mtune=xscale"
@@ -86,6 +90,7 @@ find . \
# Configure:
CFLAGS="$SLKCFLAGS" \
+CXXFLAGS="$SLKCFLAGS" \
./configure \
--prefix=/usr \
--libdir=/usr/lib${LIBDIRSUFFIX} \
diff --git a/source/xap/audacious/audacious.SlackBuild.meson b/source/xap/audacious/audacious.SlackBuild.meson
index 6ef77f727..23c03505d 100755
--- a/source/xap/audacious/audacious.SlackBuild.meson
+++ b/source/xap/audacious/audacious.SlackBuild.meson
@@ -31,7 +31,7 @@ NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -49,14 +49,14 @@ fi
TMP=${TMP:-/tmp}
PKG=$TMP/package-${PKGNAM}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "s390" ]; then
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
elif [ "$ARCH" = "arm" ]; then
SLKCFLAGS="-O2 -march=armv4 -mtune=xscale"
diff --git a/source/xap/blueman/blueman.SlackBuild b/source/xap/blueman/blueman.SlackBuild
index ca8c8c4fc..c8aa704a7 100755
--- a/source/xap/blueman/blueman.SlackBuild
+++ b/source/xap/blueman/blueman.SlackBuild
@@ -32,7 +32,7 @@ BUILD=${BUILD:-1}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -52,14 +52,11 @@ NUMJOBS=${NUMJOBS:-" -j7 "}
TMP=${TMP:-/tmp}
PKG=$TMP/package-$PKGNAM
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-O2 -march=i686 -mtune=i686"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
diff --git a/source/xap/ddd/ddd.SlackBuild b/source/xap/ddd/ddd.SlackBuild
index e724eee92..ef8df1959 100755
--- a/source/xap/ddd/ddd.SlackBuild
+++ b/source/xap/ddd/ddd.SlackBuild
@@ -29,12 +29,12 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=ddd
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-1}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) ARCH=i586 ;;
+ i?86) ARCH=i686 ;;
arm*) ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) ARCH=$( uname -m ) ;;
@@ -53,21 +53,12 @@ TMP=${TMP:-/tmp}
PKG=$TMP/package-$PKGNAM
OUTPUT=${OUTPUT:-$TMP}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-O2 -march=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
-elif [ "$ARCH" = "armv7hl" ]; then
- SLKCFLAGS="-O3 -march=armv7-a -mfpu=vfpv3-d16"
- LIBDIRSUFFIX=""
else
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
diff --git a/source/xap/electricsheep/electricsheep.SlackBuild b/source/xap/electricsheep/electricsheep.SlackBuild
index 0c151d0e5..d513e8c41 100755
--- a/source/xap/electricsheep/electricsheep.SlackBuild
+++ b/source/xap/electricsheep/electricsheep.SlackBuild
@@ -140,6 +140,9 @@ case "$ARCH" in
;;
esac
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=incompatible-pointer-types -Wno-error=implicit-function-declaration"
+
# Create working directories:
mkdir -p $OUTPUT # place for the package to be saved
mkdir -p $TMP/tmp-$PKGNAM # location to build the source
@@ -205,6 +208,9 @@ cd client
# We do not use gnome:
cat $SRCDIR/electricsheep_gnome-open.patch | patch -p1 --verbose \
2>&1 | tee $OUTPUT/patch-$PKGNAM.log
+ # This optimization is broken, oh well
+ cat $SRCDIR/electricsheep.evil.gcc14.diff | patch -p2 --verbose \
+ 2>&1 | tee $OUTPUT/patch-$PKGNAM.log
# Prevent install errors due to missing gnome
sed -i -e "/^install-data-local:/,/^$/d" Makefile.in
LDFLAGS="$SLKLDFLAGS" \
diff --git a/source/xap/electricsheep/electricsheep.evil.gcc14.diff b/source/xap/electricsheep/electricsheep.evil.gcc14.diff
new file mode 100644
index 000000000..981a4814f
--- /dev/null
+++ b/source/xap/electricsheep/electricsheep.evil.gcc14.diff
@@ -0,0 +1,11 @@
+--- ./client/ffmpeg/libavcodec/bitstream.h.orig 2024-05-10 17:20:22.784264430 -0500
++++ ./client/ffmpeg/libavcodec/bitstream.h 2024-05-10 17:20:14.597264247 -0500
+@@ -53,7 +53,7 @@
+
+ extern const uint8_t ff_reverse[256];
+
+-#if defined(ARCH_X86)
++#if defined(ARCH_X8666)
+ // avoid +32 for shift optimization (gcc should do that ...)
+ static inline int32_t NEG_SSR32( int32_t a, int8_t s){
+ asm ("sarl %1, %0\n\t"
diff --git a/source/xap/ffmpegthumbnailer/ffmpegthumbnailer.SlackBuild b/source/xap/ffmpegthumbnailer/ffmpegthumbnailer.SlackBuild
index 30d5f5627..a52132f70 100755
--- a/source/xap/ffmpegthumbnailer/ffmpegthumbnailer.SlackBuild
+++ b/source/xap/ffmpegthumbnailer/ffmpegthumbnailer.SlackBuild
@@ -26,12 +26,12 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=ffmpegthumbnailer
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-5}
+BUILD=${BUILD:-6}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$(uname -m)" in
- i?86) ARCH=i586 ;;
+ i?86) ARCH=i686 ;;
arm*) readelf /usr/bin/file -A | grep -E -q "Tag_CPU.*[4,5]" && ARCH=arm || ARCH=armv7hl ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) ARCH=$(uname -m) ;;
@@ -49,21 +49,12 @@ fi
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-O2 -march=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
-elif [ "$ARCH" = "armv7hl" ]; then
- SLKCFLAGS="-O3 -march=armv7-a -mfpu=vfpv3-d16"
- LIBDIRSUFFIX=""
else
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
diff --git a/source/xap/freerdp/1ef7b9e3.patch b/source/xap/freerdp/1ef7b9e3.patch
new file mode 100644
index 000000000..279dc86d4
--- /dev/null
+++ b/source/xap/freerdp/1ef7b9e3.patch
@@ -0,0 +1,28 @@
+From 1ef7b9e3e06ef69e5145c6f11cc330078abaa9ea Mon Sep 17 00:00:00 2001
+From: Armin Novak <anovak@thincast.com>
+Date: Fri, 24 Nov 2023 19:40:52 +0100
+Subject: [PATCH] [codec,dsp] fix ffmpeg deprecation warning
+
+---
+ libfreerdp/codec/dsp_ffmpeg.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/libfreerdp/codec/dsp_ffmpeg.c b/libfreerdp/codec/dsp_ffmpeg.c
+index c5c30fb89ed2..c929b3c553a2 100644
+--- a/libfreerdp/codec/dsp_ffmpeg.c
++++ b/libfreerdp/codec/dsp_ffmpeg.c
+@@ -439,7 +439,13 @@ static BOOL ffmpeg_encode_frame(AVCodecContext* context, AVFrame* in, AVPacket*
+ if (in->format == AV_SAMPLE_FMT_FLTP)
+ {
+ uint8_t** pp = in->extended_data;
+- for (int y = 0; y < in->channels; y++)
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
++ const int nr_channels = in->channels;
++#else
++ const int nr_channels = in->ch_layout.nb_channels;
++#endif
++
++ for (int y = 0; y < nr_channels; y++)
+ {
+ float* data = pp[y];
+ for (int x = 0; x < in->nb_samples; x++)
diff --git a/source/xap/freerdp/d0c5b1ae.patch b/source/xap/freerdp/d0c5b1ae.patch
new file mode 100644
index 000000000..753eb7b3a
--- /dev/null
+++ b/source/xap/freerdp/d0c5b1ae.patch
@@ -0,0 +1,140 @@
+From d0c5b1ae4289c7f3cde3fbc031cb4a3160df05ff Mon Sep 17 00:00:00 2001
+From: Armin Novak <armin.novak@thincast.com>
+Date: Wed, 7 Jun 2023 11:46:07 +0200
+Subject: [PATCH] [codec,dsp] fix ffmpeg deprecations
+
+---
+ libfreerdp/codec/dsp_ffmpeg.c | 54 +++++++++++++++++++++++++++--------
+ 1 file changed, 42 insertions(+), 12 deletions(-)
+
+diff --git a/libfreerdp/codec/dsp_ffmpeg.c b/libfreerdp/codec/dsp_ffmpeg.c
+index 2c93a667750e..ebba52b147d2 100644
+--- a/libfreerdp/codec/dsp_ffmpeg.c
++++ b/libfreerdp/codec/dsp_ffmpeg.c
+@@ -224,18 +224,17 @@ static void ffmpeg_close_context(FREERDP_DSP_CONTEXT* context)
+ static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
+ {
+ int ret;
+- int layout;
+- const AUDIO_FORMAT* format;
+
+ if (!context || context->isOpen)
+ return FALSE;
+
+- format = &context->format;
++ const AUDIO_FORMAT* format = &context->format;
+
+ if (!format)
+ return FALSE;
+-
+- layout = av_get_default_channel_layout(format->nChannels);
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
++ const int layout = av_get_default_channel_layout(format->nChannels);
++#endif
+ context->id = ffmpeg_get_avcodec(format);
+
+ if (ffmpeg_codec_is_filtered(context->id, context->encoder))
+@@ -271,8 +270,12 @@ static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
+ break;
+ }
+
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
+ context->context->channels = format->nChannels;
+ context->context->channel_layout = layout;
++#else
++ av_channel_layout_default(&context->context->ch_layout, format->nChannels);
++#endif
+ context->context->sample_rate = format->nSamplesPerSec;
+ context->context->block_align = format->nBlockAlign;
+ context->context->bit_rate = format->nAvgBytesPerSec * 8;
+@@ -315,8 +318,12 @@ static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
+ if (!context->rcontext)
+ goto fail;
+
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
+ context->frame->channel_layout = layout;
+ context->frame->channels = format->nChannels;
++#else
++ av_channel_layout_default(&context->frame->ch_layout, format->nChannels);
++#endif
+ context->frame->sample_rate = format->nSamplesPerSec;
+ context->frame->format = AV_SAMPLE_FMT_S16;
+
+@@ -331,13 +338,21 @@ static BOOL ffmpeg_open_context(FREERDP_DSP_CONTEXT* context)
+ context->resampled->sample_rate = format->nSamplesPerSec;
+ }
+
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
+ context->resampled->channel_layout = layout;
+ context->resampled->channels = format->nChannels;
++#else
++ av_channel_layout_default(&context->resampled->ch_layout, format->nChannels);
++#endif
+
+ if (context->context->frame_size > 0)
+ {
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
+ context->buffered->channel_layout = context->resampled->channel_layout;
+ context->buffered->channels = context->resampled->channels;
++#else
++ av_channel_layout_copy(&context->buffered->ch_layout, &context->resampled->ch_layout);
++#endif
+ context->buffered->format = context->resampled->format;
+ context->buffered->nb_samples = context->context->frame_size;
+
+@@ -458,14 +473,20 @@ static BOOL ffmpeg_fill_frame(AVFrame* frame, const AUDIO_FORMAT* inputFormat, c
+ size_t size)
+ {
+ int ret, bpp;
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
+ frame->channels = inputFormat->nChannels;
++ frame->channel_layout = av_get_default_channel_layout(frame->channels);
++#else
++ av_channel_layout_default(&frame->ch_layout, inputFormat->nChannels);
++#endif
+ frame->sample_rate = inputFormat->nSamplesPerSec;
+ frame->format = ffmpeg_sample_format(inputFormat);
+- frame->channel_layout = av_get_default_channel_layout(frame->channels);
++
+ bpp = av_get_bytes_per_sample(frame->format);
+ frame->nb_samples = size / inputFormat->nChannels / bpp;
+
+- if ((ret = avcodec_fill_audio_frame(frame, frame->channels, frame->format, data, size, 1)) < 0)
++ if ((ret = avcodec_fill_audio_frame(frame, inputFormat->nChannels, frame->format, data, size,
++ 1)) < 0)
+ {
+ const char* err = av_err2str(ret);
+ WLog_ERR(TAG, "Error during audio frame fill %s [%d]", err, ret);
+@@ -547,7 +568,12 @@ static BOOL ffmpeg_decode(AVCodecContext* dec_ctx, AVPacket* pkt, AVFrame* frame
+ }
+
+ {
+- const size_t data_size = resampled->channels * resampled->nb_samples * 2;
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
++ const size_t channels = resampled->channels;
++#else
++ const size_t channels = resampled->ch_layout.nb_channels;
++#endif
++ const size_t data_size = channels * resampled->nb_samples * 2;
+ Stream_EnsureRemainingCapacity(out, data_size);
+ Stream_Write(out, resampled->data[0], data_size);
+ }
+@@ -745,10 +771,14 @@ BOOL freerdp_dsp_ffmpeg_encode(FREERDP_DSP_CONTEXT* context, const AUDIO_FORMAT*
+ if (inSamples + (int)context->bufferedSamples > context->context->frame_size)
+ inSamples = context->context->frame_size - (int)context->bufferedSamples;
+
+- rc =
+- av_samples_copy(context->buffered->extended_data, context->resampled->extended_data,
+- (int)context->bufferedSamples, copied, inSamples,
+- context->context->channels, context->context->sample_fmt);
++#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(57, 28, 100)
++ const int channels = context->context->channels;
++#else
++ const int channels = context->context->ch_layout.nb_channels;
++#endif
++ rc = av_samples_copy(context->buffered->extended_data,
++ context->resampled->extended_data, (int)context->bufferedSamples,
++ copied, inSamples, channels, context->context->sample_fmt);
+ rest -= inSamples;
+ copied += inSamples;
+ context->bufferedSamples += (UINT32)inSamples;
diff --git a/source/xap/freerdp/freerdp.SlackBuild b/source/xap/freerdp/freerdp.SlackBuild
index 21e78ee05..b48d4a467 100755
--- a/source/xap/freerdp/freerdp.SlackBuild
+++ b/source/xap/freerdp/freerdp.SlackBuild
@@ -24,12 +24,12 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=freerdp
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$(uname -m)" in
- i?86) ARCH=i586 ;;
+ i?86) ARCH=i686 ;;
arm*) readelf /usr/bin/file -A | grep -E -q "Tag_CPU.*[4,5]" && ARCH=arm || ARCH=armv7hl ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) ARCH=$(uname -m) ;;
@@ -47,26 +47,20 @@ fi
NUMJOBS=${NUMJOBS:-" -j $(expr $(nproc) + 1) "}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-O2 -march=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
-elif [ "$ARCH" = "armv7hl" ]; then
- SLKCFLAGS="-O3 -march=armv7-a -mfpu=vfpv3-d16"
- LIBDIRSUFFIX=""
else
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
fi
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=incompatible-pointer-types -Wno-error=int-conversion"
+
TMP=${TMP:-/tmp}
PKG=$TMP/package-$PKGNAM
@@ -85,6 +79,10 @@ find . \
\( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
-exec chmod 644 {} \+
+# FFmpeg 7:
+cat $CWD/1ef7b9e3.patch | patch -p1 --verbose || exit 1
+cat $CWD/d0c5b1ae.patch | patch -p1 --verbose || exit 1
+
# Configure, build, and install:
mkdir cmake-build
cd cmake-build
diff --git a/source/xap/fvwm/fvwm.SlackBuild b/source/xap/fvwm/fvwm.SlackBuild
index 5a41c9c3a..9de111625 100755
--- a/source/xap/fvwm/fvwm.SlackBuild
+++ b/source/xap/fvwm/fvwm.SlackBuild
@@ -60,6 +60,9 @@ else
LIBDIRSUFFIX=""
fi
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=incompatible-pointer-types -Wno-error=int-conversion"
+
TMP=${TMP:-/tmp}
PKG=$TMP/package-$PKGNAM
diff --git a/source/xap/geeqie/fix-build-re-docs.diff b/source/xap/geeqie/fix-build-re-docs.diff
deleted file mode 100644
index 279d8566e..000000000
--- a/source/xap/geeqie/fix-build-re-docs.diff
+++ /dev/null
@@ -1,26 +0,0 @@
-diff -Nur geeqie-1.4.orig/Makefile.am geeqie-1.4/Makefile.am
---- geeqie-1.4.orig/Makefile.am 2017-12-31 06:31:21.000000000 -0600
-+++ geeqie-1.4/Makefile.am 2018-01-02 02:18:15.881141642 -0600
-@@ -9,11 +9,7 @@
-
- readmedir = @readmedir@
-
--if HAVE_MARKDOWN
--readme_DATA = README.md COPYING ChangeLog TODO README.lirc AUTHORS README.html ChangeLog.html
--else
--readme_DATA = README.md COPYING ChangeLog TODO README.lirc AUTHORS ChangeLog.html
--endif
-+readme_DATA = README.md COPYING ChangeLog TODO README.lirc AUTHORS
-
- desktopdir = $(datadir)/applications
- desktop_in_files = geeqie.desktop.in
-@@ -37,9 +33,3 @@
-
- DISTCLEANFILES = config.report
-
--.PHONY: ChangeLog
--ChangeLog.html:
-- ./gen_changelog.sh
--
--README.html: README.md
-- ./gen_readme.sh
diff --git a/source/xap/geeqie/geeqie.SlackBuild b/source/xap/geeqie/geeqie.SlackBuild
index 284650359..bd624a359 100755
--- a/source/xap/geeqie/geeqie.SlackBuild
+++ b/source/xap/geeqie/geeqie.SlackBuild
@@ -41,7 +41,7 @@ VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -61,9 +61,7 @@ NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
if [ "$ARCH" = "i586" ]; then
SLKCFLAGS="-O2 -D_FILE_OFFSET_BITS=64 -march=i586 -mtune=i686"
elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-O2 -D_FILE_OFFSET_BITS=64 -march=i686"
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2 -D_FILE_OFFSET_BITS=64"
+ SLKCFLAGS="-O2 -D_FILE_OFFSET_BITS=64 -march=pentium4 -mtune=generic"
elif [ "$ARCH" = "x86_64" ]; then
SLKCFLAGS="-O2 -D_FILE_OFFSET_BITS=64 -fPIC"
else
@@ -115,7 +113,7 @@ cd ..
mkdir -p $PKG/usr/doc/$PKGNAM-$VERSION
cp -a \
- AUTHORS* CHECKLIST* CODING* COPYING* NEWS* README* TODO* \
+ CHECKLIST* CODE_OF_CONDUCT* CODING* COPYING* ChangeLog DEVELOPER-NOTES* NEWS* README* TESTING* TODO* \
$PKG/usr/doc/$PKGNAM-$VERSION
# If there's a ChangeLog, installing at least part of the recent history
diff --git a/source/xap/gftp/gftp.SlackBuild b/source/xap/gftp/gftp.SlackBuild
index 9431f3ac4..7d42bd65b 100755
--- a/source/xap/gftp/gftp.SlackBuild
+++ b/source/xap/gftp/gftp.SlackBuild
@@ -55,6 +55,9 @@ elif [ "$ARCH" = "x86_64" ]; then
SLKCFLAGS="-O2 -fPIC"
fi
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=incompatible-pointer-types"
+
TMP=${TMP:-/tmp}
PKG=$TMP/package-gftp
diff --git a/source/xap/gimp/gimp.SlackBuild b/source/xap/gimp/gimp.SlackBuild
index 3c54f1cd9..55fe46b4a 100755
--- a/source/xap/gimp/gimp.SlackBuild
+++ b/source/xap/gimp/gimp.SlackBuild
@@ -65,6 +65,9 @@ else
LIBDIRSUFFIX=""
fi
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=incompatible-pointer-types"
+
cd $TMP
rm -rf gimp-$VERSION
tar xvf $CWD/gimp-$VERSION.tar.?z || exit 1
diff --git a/source/xap/gnuchess/gnuchess.SlackBuild b/source/xap/gnuchess/gnuchess.SlackBuild
index a0be62186..cac5e2091 100755
--- a/source/xap/gnuchess/gnuchess.SlackBuild
+++ b/source/xap/gnuchess/gnuchess.SlackBuild
@@ -65,6 +65,9 @@ PKG=/tmp/package-gnuchess
rm -rf $PKG
mkdir -p $TMP $PKG
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=implicit-int -Wno-error=implicit-function-declaration"
+
### gnuchess
cd $TMP
rm -rf gnuchess-$VERGNUCHESS
diff --git a/source/xap/gucharmap/gucharmap.SlackBuild b/source/xap/gucharmap/gucharmap.SlackBuild
index b1755008c..934acc4e5 100755
--- a/source/xap/gucharmap/gucharmap.SlackBuild
+++ b/source/xap/gucharmap/gucharmap.SlackBuild
@@ -29,7 +29,7 @@ BUILD=${BUILD:-1}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -46,14 +46,11 @@ fi
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
@@ -124,4 +121,3 @@ cat $CWD/slack-desc > $PKG/install/slack-desc
cd $PKG
/sbin/makepkg -l y -c n $TMP/gucharmap-$VERSION-$ARCH-$BUILD.txz
-
diff --git a/source/xap/gucharmap/gucharmap.url b/source/xap/gucharmap/gucharmap.url
index 30458a768..25f1a68f5 100644
--- a/source/xap/gucharmap/gucharmap.url
+++ b/source/xap/gucharmap/gucharmap.url
@@ -1 +1,2 @@
https://gitlab.gnome.org/GNOME/gucharmap
+https://gitlab.gnome.org/GNOME/gucharmap/-/archive/16.0.1/gucharmap-16.0.1.tar.gz
diff --git a/source/xap/hexchat/hexchat.SlackBuild b/source/xap/hexchat/hexchat.SlackBuild
index d1baf6d30..75d706127 100755
--- a/source/xap/hexchat/hexchat.SlackBuild
+++ b/source/xap/hexchat/hexchat.SlackBuild
@@ -24,7 +24,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=hexchat
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-3}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
diff --git a/source/xap/mozilla-firefox/mozilla-firefox.SlackBuild b/source/xap/mozilla-firefox/mozilla-firefox.SlackBuild
index 92d0f6e84..25e5c4b54 100755
--- a/source/xap/mozilla-firefox/mozilla-firefox.SlackBuild
+++ b/source/xap/mozilla-firefox/mozilla-firefox.SlackBuild
@@ -134,13 +134,7 @@ export RUSTFLAGS="-Cdebuginfo=0"
# PGO is disabled by default:
PGO=${PGO:-no}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-g0"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-g0"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
+if [ "$ARCH" = "i686" ]; then
SLKCFLAGS="-g0"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
@@ -149,9 +143,6 @@ elif [ "$ARCH" = "x86_64" ]; then
elif [ "$ARCH" = "arm" ]; then
SLKCFLAGS="-g0 -march=armv4 -mtune=xscale"
LIBDIRSUFFIX=""
-elif [ "$ARCH" = "armel" ]; then
- SLKCFLAGS="-g0 -march=armv4t"
- LIBDIRSUFFIX=""
else
SLKCFLAGS="-g0"
LIBDIRSUFFIX=""
diff --git a/source/xap/mozilla-thunderbird/mozilla-thunderbird.SlackBuild b/source/xap/mozilla-thunderbird/mozilla-thunderbird.SlackBuild
index b02f7aaca..0ca601dfa 100755
--- a/source/xap/mozilla-thunderbird/mozilla-thunderbird.SlackBuild
+++ b/source/xap/mozilla-thunderbird/mozilla-thunderbird.SlackBuild
@@ -54,7 +54,6 @@ MOZ_ALLOW_DOWNGRADE=${MOZ_ALLOW_DOWNGRADE:-YES}
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
i?86) export ARCH=i686 ;;
- armv7hl) export ARCH=armv7hl ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -83,24 +82,15 @@ if [ "$(uname -m)" = "x86_64" -a "$(file -L /usr/bin/gcc | grep 80386 | grep 32-
ARCH=i686
fi
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-g0"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-g0"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-g0"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-g0 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-g0 -fPIC"
+ SLKCFLAGS="-g0 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
elif [ "$ARCH" = "arm" ]; then
SLKCFLAGS="-g0 -march=armv4 -mtune=xscale"
LIBDIRSUFFIX=""
-elif [ "$ARCH" = "armel" ]; then
- SLKCFLAGS="-g0 -march=armv4t"
- LIBDIRSUFFIX=""
else
SLKCFLAGS="-g0"
LIBDIRSUFFIX=""
@@ -178,6 +168,9 @@ fi
# Don't define a function that's included starting in glibc-2.36:
zcat $CWD/arc4random_buf.glibc-2.36.diff.gz | patch -p1 --verbose || exit 1
+# Accept sha1 signatures for a while longer:
+sed -i 's|pref("mail.smime.accept_insecure_sha1_message_signatures", false);|pref("mail.smime.accept_insecure_sha1_message_signatures", true);|g' comm/mail/extensions/am-e2e/prefs/e2e-prefs.js
+
# Fetch localization, if requested:
if [ ! -z $MOZLOCALIZE ]; then
LOC_TAG="THUNDERBIRD_$( echo $VERSION | tr \. _ )_RELEASE"
diff --git a/source/xap/mpv/doinst.sh b/source/xap/mpv/doinst.sh
new file mode 100644
index 000000000..f125cba0e
--- /dev/null
+++ b/source/xap/mpv/doinst.sh
@@ -0,0 +1,26 @@
+config() {
+ NEW="$1"
+ OLD="$(dirname $NEW)/$(basename $NEW .new)"
+ # If there's no config file by that name, mv it over:
+ if [ ! -r $OLD ]; then
+ mv $NEW $OLD
+ elif [ "$(cat $OLD | md5sum)" = "$(cat $NEW | md5sum)" ]; then
+ # toss the redundant copy
+ rm $NEW
+ fi
+ # Otherwise, we leave the .new copy for the admin to consider...
+}
+
+for config in etc/mpv/*.conf.new ; do
+ config $config
+done
+
+if [ -x /usr/bin/update-desktop-database ]; then
+ /usr/bin/update-desktop-database -q usr/share/applications >/dev/null 2>&1
+fi
+
+if [ -e usr/share/icons/hicolor/icon-theme.cache ]; then
+ if [ -x /usr/bin/gtk-update-icon-cache ]; then
+ /usr/bin/gtk-update-icon-cache -f usr/share/icons/hicolor >/dev/null 2>&1
+ fi
+fi
diff --git a/source/xap/mpv/dynamically_generate_desktop_file_protocols.patch b/source/xap/mpv/dynamically_generate_desktop_file_protocols.patch
new file mode 100644
index 000000000..33320e1bc
--- /dev/null
+++ b/source/xap/mpv/dynamically_generate_desktop_file_protocols.patch
@@ -0,0 +1,462 @@
+From f59d358752c2a63c94635511cd963bebb2706d64 Mon Sep 17 00:00:00 2001
+From: Dudemanguy <random342@airmail.cc>
+Date: Wed, 15 May 2024 09:03:14 -0500
+Subject: [PATCH 1/4] av_common: parent mp_get_lavf_demuxer contents to the
+ list
+
+The only usage of this function is freed in mpv's generic property code,
+so no other changes are needed.
+---
+ common/av_common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/common/av_common.c b/common/av_common.c
+index 1a23d766b365..142699d4b4c6 100644
+--- a/common/av_common.c
++++ b/common/av_common.c
+@@ -265,7 +265,7 @@ char **mp_get_lavf_demuxers(void)
+ const AVInputFormat *cur = av_demuxer_iterate(&iter);
+ if (!cur)
+ break;
+- MP_TARRAY_APPEND(NULL, list, num, talloc_strdup(NULL, cur->name));
++ MP_TARRAY_APPEND(NULL, list, num, talloc_strdup(list, cur->name));
+ }
+ MP_TARRAY_APPEND(NULL, list, num, NULL);
+ return list;
+
+From 6692f87b61d48e1523d6e0ef3d311ffff6e89a6e Mon Sep 17 00:00:00 2001
+From: Dudemanguy <random342@airmail.cc>
+Date: Wed, 15 May 2024 19:22:32 -0500
+Subject: [PATCH 2/4] stream: implement get_protocols method for stream_lavf
+
+Previously, all stream protocols were a static list in mpv. This is okay
+for own builtin stuff, but for protocols that depend on ffmpeg it's not
+so great. Support for certain protocols may or may not be enabled in a
+user's ffmpeg and the protocol list that mpv generates should ideally
+match this. Fix this by implementing a get_protocols method for
+stream_lavf that will have different results depending on the ffmpeg mpv
+is built against. We keep the safe and unsafe protocols separation. The
+former is essentially a whitelist. Any protocol that is found in ffmpeg
+but is not in the safe whitelist is considered unsafe. In the stream
+list, ffmpeg is moved to the bottom so any possible protocols that are
+added in the future don't automatically take precedence over any builtin
+mpv ones.
+---
+ common/av_common.c | 12 +++++
+ common/av_common.h | 1 +
+ stream/stream.c | 44 ++++++++++++-------
+ stream/stream.h | 2 +
+ stream/stream_lavf.c | 102 ++++++++++++++++++++++++++++++++++++++-----
+ 5 files changed, 136 insertions(+), 25 deletions(-)
+
+diff --git a/common/av_common.c b/common/av_common.c
+index 142699d4b4c6..a4fa5981ff9f 100644
+--- a/common/av_common.c
++++ b/common/av_common.c
+@@ -271,6 +271,18 @@ char **mp_get_lavf_demuxers(void)
+ return list;
+ }
+
++char **mp_get_lavf_protocols(void)
++{
++ char **list = NULL;
++ int num = 0;
++ void *opaque = NULL;
++ const char *name;
++ while ((name = avio_enum_protocols(&opaque, 0)))
++ MP_TARRAY_APPEND(NULL, list, num, talloc_strdup(list, name));
++ MP_TARRAY_APPEND(NULL, list, num, NULL);
++ return list;
++}
++
+ int mp_codec_to_av_codec_id(const char *codec)
+ {
+ int id = AV_CODEC_ID_NONE;
+diff --git a/common/av_common.h b/common/av_common.h
+index c584085890c2..b019aa88e17a 100644
+--- a/common/av_common.h
++++ b/common/av_common.h
+@@ -42,6 +42,7 @@ void mp_set_avcodec_threads(struct mp_log *l, AVCodecContext *avctx, int threads
+ void mp_add_lavc_decoders(struct mp_decoder_list *list, enum AVMediaType type);
+ void mp_add_lavc_encoders(struct mp_decoder_list *list);
+ char **mp_get_lavf_demuxers(void);
++char **mp_get_lavf_protocols(void);
+ int mp_codec_to_av_codec_id(const char *codec);
+ const char *mp_codec_from_av_codec_id(int codec_id);
+ bool mp_codec_is_lossless(const char *codec);
+diff --git a/stream/stream.c b/stream/stream.c
+index 06dd92930c01..eca44e4afb37 100644
+--- a/stream/stream.c
++++ b/stream/stream.c
+@@ -66,8 +66,6 @@ static const stream_info_t *const stream_list[] = {
+ #if HAVE_CDDA
+ &stream_info_cdda,
+ #endif
+- &stream_info_ffmpeg,
+- &stream_info_ffmpeg_unsafe,
+ &stream_info_avdevice,
+ #if HAVE_DVBIN
+ &stream_info_dvb,
+@@ -92,6 +90,8 @@ static const stream_info_t *const stream_list[] = {
+ &stream_info_slice,
+ &stream_info_fd,
+ &stream_info_cb,
++ &stream_info_ffmpeg,
++ &stream_info_ffmpeg_unsafe,
+ };
+
+ // Because of guarantees documented on STREAM_BUFFER_SIZE.
+@@ -325,12 +325,17 @@ static int stream_create_instance(const stream_info_t *sinfo,
+ if (!sinfo->local_fs)
+ return STREAM_NO_MATCH;
+ } else {
+- for (int n = 0; sinfo->protocols && sinfo->protocols[n]; n++) {
+- path = match_proto(url, sinfo->protocols[n]);
++ char **get_protocols = sinfo->get_protocols ? sinfo->get_protocols() : NULL;
++ char **protocols = get_protocols ? get_protocols : (char **)sinfo->protocols;
++
++ for (int n = 0; protocols && protocols[n]; n++) {
++ path = match_proto(url, protocols[n]);
+ if (path)
+ break;
+ }
+
++ talloc_free(get_protocols);
++
+ if (!path)
+ return STREAM_NO_MATCH;
+ }
+@@ -864,16 +869,17 @@ char **stream_get_proto_list(void)
+ for (int i = 0; i < MP_ARRAY_SIZE(stream_list); i++) {
+ const stream_info_t *stream_info = stream_list[i];
+
+- if (!stream_info->protocols)
+- continue;
++ char **get_protocols = stream_info->get_protocols ? stream_info->get_protocols() : NULL;
++ char **protocols = get_protocols ? get_protocols : (char **)stream_info->protocols;
+
+- for (int j = 0; stream_info->protocols[j]; j++) {
+- if (*stream_info->protocols[j] == '\0')
+- continue;
++ for (int j = 0; protocols && protocols[j]; j++) {
++ if (*protocols[j] == '\0')
++ continue;
+
+- MP_TARRAY_APPEND(NULL, list, num,
+- talloc_strdup(NULL, stream_info->protocols[j]));
++ MP_TARRAY_APPEND(NULL, list, num, talloc_strdup(list, protocols[j]));
+ }
++
++ talloc_free(get_protocols);
+ }
+ MP_TARRAY_APPEND(NULL, list, num, NULL);
+ return list;
+@@ -888,7 +894,6 @@ void stream_print_proto_list(struct mp_log *log)
+ for (int i = 0; list[i]; i++) {
+ mp_info(log, " %s://\n", list[i]);
+ count++;
+- talloc_free(list[i]);
+ }
+ talloc_free(list);
+ mp_info(log, "\nTotal: %d protocols\n", count);
+@@ -899,10 +904,19 @@ bool stream_has_proto(const char *proto)
+ for (int i = 0; i < MP_ARRAY_SIZE(stream_list); i++) {
+ const stream_info_t *stream_info = stream_list[i];
+
+- for (int j = 0; stream_info->protocols && stream_info->protocols[j]; j++) {
+- if (strcmp(stream_info->protocols[j], proto) == 0)
+- return true;
++ bool match = false;
++ char **get_protocols = stream_info->get_protocols ? stream_info->get_protocols() : NULL;
++ char **protocols = get_protocols ? get_protocols : (char **)stream_info->protocols;
++
++ for (int j = 0; protocols && protocols[j]; j++) {
++ if (strcmp(protocols[j], proto) == 0) {
++ match = true;
++ break;
++ }
+ }
++
++ talloc_free(get_protocols);
++ return match;
+ }
+
+ return false;
+diff --git a/stream/stream.h b/stream/stream.h
+index 58b55e1a43ca..866affe1fef0 100644
+--- a/stream/stream.h
++++ b/stream/stream.h
+@@ -114,6 +114,8 @@ typedef struct stream_info_st {
+ // Alternative to open(). Only either open() or open2() can be set.
+ int (*open2)(struct stream *st, const struct stream_open_args *args);
+ const char *const *protocols;
++ // Alternative to protocols. For stream_lavf.
++ char **(*get_protocols)(void);
+ bool can_write; // correctly checks for READ/WRITE modes
+ bool local_fs; // supports STREAM_LOCAL_FS_ONLY
+ int stream_origin; // 0 or set of STREAM_ORIGIN_*; if 0, the same origin
+diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
+index a2db55146668..30c823c58f62 100644
+--- a/stream/stream_lavf.c
++++ b/stream/stream_lavf.c
+@@ -238,6 +238,96 @@ void mp_setup_av_network_options(AVDictionary **dict, const char *target_fmt,
+ talloc_free(temp);
+ }
+
++#define PROTO(...) (const char *[]){__VA_ARGS__, NULL}
++
++// List of safe protocols and their aliases
++static const char **safe_protos[] = {
++ PROTO("data"),
++ PROTO("gopher"),
++ PROTO("gophers"),
++ PROTO("http", "dav", "webdav"),
++ PROTO("httpproxy"),
++ PROTO("https", "davs", "webdavs"),
++ PROTO("ipfs"),
++ PROTO("ipns"),
++ PROTO("mmsh", "mms", "mmshttp"),
++ PROTO("mmst"),
++ PROTO("rist"),
++ PROTO("rtmp"),
++ PROTO("rtmpe"),
++ PROTO("rtmps"),
++ PROTO("rtmpt"),
++ PROTO("rtmpte"),
++ PROTO("rtmpts"),
++ PROTO("rtp"),
++ PROTO("srt"),
++ PROTO("srtp"),
++ NULL,
++};
++
++static char **get_safe_protocols(void)
++{
++ int num = 0;
++ char **protocols = NULL;
++ char **ffmpeg_demuxers = mp_get_lavf_demuxers();
++ char **ffmpeg_protos = mp_get_lavf_protocols();
++
++ for (int i = 0; ffmpeg_protos[i]; i++) {
++ for (int j = 0; safe_protos[j]; j++) {
++ if (strcmp(ffmpeg_protos[i], safe_protos[j][0]) != 0)
++ continue;
++ for (int k = 0; safe_protos[j][k]; k++)
++ MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, safe_protos[j][k]));
++ break;
++ }
++ }
++
++ // rtsp is a demuxer not protocol in ffmpeg so it is handled separately
++ for (int i = 0; ffmpeg_demuxers[i]; i++) {
++ if (strcmp("rtsp", ffmpeg_demuxers[i]) == 0) {
++ MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, "rtsp"));
++ MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, "rtsps"));
++ break;
++ }
++ }
++
++ MP_TARRAY_APPEND(NULL, protocols, num, NULL);
++
++ talloc_free(ffmpeg_demuxers);
++ talloc_free(ffmpeg_protos);
++
++ return protocols;
++}
++
++static char **get_unsafe_protocols(void)
++{
++ int num = 0;
++ char **protocols = NULL;
++ char **safe_protocols = get_safe_protocols();
++ char **ffmpeg_protos = mp_get_lavf_protocols();
++
++ for (int i = 0; ffmpeg_protos[i]; i++) {
++ bool safe_protocol = false;
++ for (int j = 0; safe_protocols[j]; j++) {
++ if (strcmp(ffmpeg_protos[i], safe_protocols[j]) == 0) {
++ safe_protocol = true;
++ break;
++ }
++ }
++ if (!safe_protocol)
++ MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, ffmpeg_protos[i]));
++ }
++
++ MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, "ffmpeg"));
++ MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, "lavf"));
++
++ MP_TARRAY_APPEND(NULL, protocols, num, NULL);
++
++ talloc_free(ffmpeg_protos);
++ talloc_free(safe_protocols);
++ return protocols;
++}
++
+ // Escape http URLs with unescaped, invalid characters in them.
+ // libavformat's http protocol does not do this, and a patch to add this
+ // in a 100% safe case (spaces only) was rejected.
+@@ -431,12 +431,7 @@ done:
+ const stream_info_t stream_info_ffmpeg = {
+ .name = "ffmpeg",
+ .open = open_f,
+- .protocols = (const char *const[]){
+- "rtmp", "rtsp", "rtsps", "http", "https", "mms", "mmst", "mmsh", "mmshttp",
+- "rtp", "httpproxy", "rtmpe", "rtmps", "rtmpt", "rtmpte", "rtmpts", "srt",
+- "rist", "srtp", "gopher", "gophers", "data", "ipfs", "ipns", "dav",
+- "davs", "webdav", "webdavs",
+- NULL },
++ .get_protocols = get_safe_protocols,
+ .can_write = true,
+ .stream_origin = STREAM_ORIGIN_NET,
+ };
+@@ -448,10 +443,7 @@ const stream_info_t stream_info_ffmpeg = {
+ const stream_info_t stream_info_ffmpeg_unsafe = {
+ .name = "ffmpeg",
+ .open = open_f,
+- .protocols = (const char *const[]){
+- "lavf", "ffmpeg", "udp", "ftp", "tcp", "tls", "unix", "sftp", "md5",
+- "concat", "smb",
+- NULL },
++ .get_protocols = get_unsafe_protocols,
+ .stream_origin = STREAM_ORIGIN_UNSAFE,
+ .can_write = true,
+ };
+
+From 0f4fa329357f27d0c57f8f13b426d7450a29cfa4 Mon Sep 17 00:00:00 2001
+From: Dudemanguy <random342@airmail.cc>
+Date: Tue, 14 May 2024 13:32:18 -0500
+Subject: [PATCH 3/4] build: dynamically generate mpv.desktop file protocols
+
+If we can run the built mpv binary, then it is possible to use a custom
+target that reads the protocols we have available in mpv and write the
+mpv.desktop file based on the output. For cases where this is not
+possible (e.g. cross compiling), then just install the unmodified
+mpv.desktop file like before. Fixes #8731 and fixes #14124.
+---
+ TOOLS/gen-mpv-desktop.py | 45 ++++++++++++++++++++++++++++++++++++++++
+ meson.build | 17 ++++++++++++++-
+ 2 files changed, 61 insertions(+), 1 deletion(-)
+ create mode 100755 TOOLS/gen-mpv-desktop.py
+
+diff --git a/TOOLS/gen-mpv-desktop.py b/TOOLS/gen-mpv-desktop.py
+new file mode 100755
+index 000000000000..2b05de1ec4cc
+--- /dev/null
++++ b/TOOLS/gen-mpv-desktop.py
+@@ -0,0 +1,45 @@
++#!/usr/bin/env python3
++
++# Modify X-KDE-Protocols in the mpv.desktop file based on output from
++# mpv --list-protocols.
++
++#
++# This file is part of mpv.
++#
++# mpv 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.1 of the License, or (at your option) any later version.
++#
++# mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
++#
++
++import sys
++from subprocess import check_output
++
++if __name__ == "__main__":
++ with open(sys.argv[1], "r", encoding="UTF-8") as f:
++ next(f)
++ mpv_desktop = dict([line.split("=", 1) for line in f])
++
++ if not mpv_desktop["X-KDE-Protocols"]:
++ raise ValueError("Missing X-KDE-Protocols entry in mpv.desktop file")
++
++ mpv_protocols = check_output([sys.argv[2], "--list-protocols"], encoding="UTF-8")
++ mpv_protocols = set(line.strip(" :/") for line in mpv_protocols.splitlines() if "://" in line)
++ if len(mpv_protocols) == 0:
++ raise ValueError("Unable to parse any protocols from mpv '--list-protocols'")
++
++ protocol_list = set(mpv_desktop["X-KDE-Protocols"].strip().split(","))
++ mpv_desktop["X-KDE-Protocols"] = ",".join(sorted(mpv_protocols & protocol_list)) + "\n"
++
++ with open(sys.argv[3], "w", encoding="UTF-8") as f:
++ f.write("[Desktop Entry]" + "\n")
++ for key, value in mpv_desktop.items():
++ f.write(f"{key}={value}")
+diff --git a/meson.build b/meson.build
+index c14bf47d5614..ae1eb9cfd903 100644
+--- a/meson.build
++++ b/meson.build
+@@ -581,6 +581,7 @@ tools_directory = join_paths(source_root, 'TOOLS')
+ docutils_wrapper = find_program(join_paths(tools_directory, 'docutils-wrapper.py'))
+ file2string = find_program(join_paths(tools_directory, 'file2string.py'))
+ matroska = find_program(join_paths(tools_directory, 'matroska.py'))
++mpv_desktop = find_program(join_paths(tools_directory, 'gen-mpv-desktop.py'))
+
+ ebml_defs = custom_target('ebml_defs.inc',
+ output: 'ebml_defs.inc',
+@@ -1796,7 +1797,6 @@ if get_option('cplayer')
+ zsh_install_dir = join_paths(datadir, 'zsh', 'site-functions')
+ install_data('etc/_mpv.zsh', install_dir: zsh_install_dir, rename: '_mpv')
+
+- install_data('etc/mpv.desktop', install_dir: join_paths(datadir, 'applications'))
+ install_data('etc/mpv.metainfo.xml', install_dir: join_paths(datadir, 'metainfo'))
+ install_data('etc/encoding-profiles.conf', install_dir: join_paths(confdir, 'mpv'))
+
+@@ -1827,6 +1827,21 @@ if get_option('cplayer')
+ command: [osxbundle, mpv.full_path(), '@SOURCE_ROOT@'],
+ )
+ endif
++
++ if not win32 and not darwin
++ if meson.can_run_host_binaries()
++ mpv_desktop_path = join_paths(source_root, 'etc', 'mpv.desktop')
++ custom_target('mpv.desktop',
++ depends: mpv,
++ output: 'mpv.desktop',
++ command: [mpv_desktop, mpv_desktop_path, mpv.full_path(), '@OUTPUT@'],
++ install: true,
++ install_dir: join_paths(datadir, 'applications'),
++ )
++ else
++ install_data('etc/mpv.desktop', install_dir: join_paths(datadir, 'applications'))
++ endif
++ endif
+ endif
+
+ if get_option('tests')
+
+From 00506d51892c48cd91d3c88423f31df7b9328499 Mon Sep 17 00:00:00 2001
+From: Dudemanguy <random342@airmail.cc>
+Date: Wed, 22 May 2024 10:27:40 -0500
+Subject: [PATCH 4/4] stream_lavf: don't add ffmpeg bluray or dvd protocols
+
+The naming of these conflict with existing mpv protocols, so skip if we
+get them. Users can still use them via lavf://bluray: or lavf://dvd: if
+they wish.
+---
+ stream/stream_lavf.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
+index 30c823c58f62..369f9cecc402 100644
+--- a/stream/stream_lavf.c
++++ b/stream/stream_lavf.c
+@@ -314,6 +314,10 @@ static char **get_unsafe_protocols(void)
+ break;
+ }
+ }
++ // Skip to avoid name conflict with builtin mpv protocol.
++ if (strcmp(ffmpeg_protos[i], "bluray") == 0 || strcmp(ffmpeg_protos[i], "dvd") == 0)
++ continue;
++
+ if (!safe_protocol)
+ MP_TARRAY_APPEND(NULL, protocols, num, talloc_strdup(protocols, ffmpeg_protos[i]));
+ }
diff --git a/source/xap/mpv/mpv.SlackBuild b/source/xap/mpv/mpv.SlackBuild
new file mode 100755
index 000000000..760ca3fff
--- /dev/null
+++ b/source/xap/mpv/mpv.SlackBuild
@@ -0,0 +1,158 @@
+#!/bin/bash
+
+# Copyright 2015 John Vogel Corning, NY USA
+# Copyright 2017, 2018 (versions 0.25.0-0.29.1) Andreas Guldstrand
+# Copyright 2020-2023 Christoph Willing Brisbane Australia
+# Copyright 2024 Patrick J. Volkerding, Sebeka, Minnesota, USA
+# All rights reserved.
+#
+# Redistribution and use of this script, with or without modification, is
+# permitted provided that the following conditions are met:
+#
+# 1. Redistributions of this script must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+cd $(dirname $0) ; CWD=$(pwd)
+
+PKGNAM=mpv
+VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
+BUILD=${BUILD:-5}
+
+# Automatically determine the architecture we're building on:
+if [ -z "$ARCH" ]; then
+ case "$(uname -m)" in
+ i?86) ARCH=i686 ;;
+ arm*) readelf /usr/bin/file -A | egrep -q "Tag_CPU.*[4,5]" && ARCH=arm || ARCH=armv7hl ;;
+ # Unless $ARCH is already set, use uname -m for all other archs:
+ *) ARCH=$(uname -m) ;;
+ esac
+ export ARCH
+fi
+
+# If the variable PRINT_PACKAGE_NAME is set, then this script will report what
+# the name of the created package would be, and then exit. This information
+# could be useful to other scripts.
+if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
+ echo "$PKGNAM-$VERSION-$ARCH-$BUILD.txz"
+ exit 0
+fi
+
+NUMJOBS=${NUMJOBS:-" -j $(expr $(nproc) + 1) "}
+
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "x86_64" ]; then
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
+ LIBDIRSUFFIX="64"
+else
+ SLKCFLAGS="-O2"
+ LIBDIRSUFFIX=""
+fi
+
+TMP=${TMP:-/tmp}
+PKG=$TMP/package-$PKGNAM
+
+rm -rf $PKG
+mkdir -p $TMP $PKG
+
+cd $TMP
+rm -rf $PKGNAM-$VERSION
+tar xvf $CWD/$PKGNAM-$VERSION.tar.?z || exit 1
+cd $PKGNAM-$VERSION || exit 1
+
+chown -R root:root .
+find . \
+ \( -perm 777 -o -perm 775 -o -perm 711 -o -perm 555 -o -perm 511 \) \
+ -exec chmod 755 {} \+ -o \
+ \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
+ -exec chmod 644 {} \+
+
+cat $CWD/dynamically_generate_desktop_file_protocols.patch | patch -p1 --verbose || exit 1
+
+# Configure, build, and install:
+export CFLAGS="$SLKCFLAGS"
+export CXXFLAGS="$SLKCFLAGS"
+mkdir meson-build
+cd meson-build
+meson setup \
+ --prefix=/usr \
+ --libdir=lib${LIBDIRSUFFIX} \
+ --libexecdir=/usr/libexec \
+ --bindir=/usr/bin \
+ --sbindir=/usr/sbin \
+ --includedir=/usr/include \
+ --datadir=/usr/share \
+ --mandir=/usr/man \
+ --sysconfdir=/etc \
+ --localstatedir=/var \
+ --buildtype=release \
+ -Dmanpage-build=enabled \
+ -Dlibmpv=true \
+ -Dcdda=enabled \
+ -Ddvdnav=enabled \
+ -Ddvbin=enabled \
+ -Dcplugins=enabled \
+ -Diconv=enabled \
+ -Dlibarchive=enabled \
+ -Dlibbluray=enabled \
+ -Dsdl2=enabled \
+ -Dgl-x11=enabled \
+ -Dsdl2-gamepad=enabled \
+ -Dpulse=enabled \
+ -Dpipewire=enabled \
+ -Dsdl2-audio=enabled \
+ -Dopenal=enabled \
+ -Dlua=luajit \
+ -Djavascript=enabled \
+ .. || exit 1
+ "${NINJA:=ninja}" $NUMJOBS || exit 1
+ DESTDIR=$PKG $NINJA install || exit 1
+cd ..
+
+# This seems like a silly place to put the config files:
+rm -rf $PKG/usr/share/doc
+
+# Install all sample config files:
+cp -a etc/*.conf $PKG/etc/mpv
+chmod 644 $PKG/etc/mpv/*
+
+# Make config files .new:
+for config in $PKG/etc/mpv/* ; do
+ mv $config ${config}.new
+done
+
+# Strip binaries:
+find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
+
+# Compress manual pages:
+find $PKG/usr/man -type f -exec gzip -9 {} \+
+for i in $( find $PKG/usr/man -type l ) ; do
+ ln -s $( readlink $i ).gz $i.gz
+ rm $i
+done
+
+# Add a documentation directory:
+mkdir -p $PKG/usr/doc/${PKGNAM}-$VERSION
+cp -a \
+ Copyright* LICENSE* README* RELEASE_NOTES* \
+ DOCS/*.{md,rst,txt} \
+ $PKG/usr/doc/${PKGNAM}-$VERSION
+
+mkdir -p $PKG/install
+cat $CWD/doinst.sh > $PKG/install/doinst.sh
+cat $CWD/slack-desc > $PKG/install/slack-desc
+
+cd $PKG
+/sbin/makepkg -l y -c n $TMP/$PKGNAM-$VERSION-$ARCH-$BUILD.txz
diff --git a/source/xap/mpv/mpv.url b/source/xap/mpv/mpv.url
new file mode 100644
index 000000000..8c68abff1
--- /dev/null
+++ b/source/xap/mpv/mpv.url
@@ -0,0 +1 @@
+https://github.com/mpv-player/mpv
diff --git a/source/xap/mpv/slack-desc b/source/xap/mpv/slack-desc
new file mode 100644
index 000000000..dd1606f6c
--- /dev/null
+++ b/source/xap/mpv/slack-desc
@@ -0,0 +1,19 @@
+# HOW TO EDIT THIS FILE:
+# The "handy ruler" below makes it easier to edit a package description.
+# Line up the first '|' above the ':' following the base package name, and
+# the '|' on the right side marks the last column you can put a character in.
+# You must make exactly 11 lines for the formatting to be correct. It's also
+# customary to leave one space after the ':' except on otherwise blank lines.
+
+ |-----handy-ruler------------------------------------------------------|
+mpv: mpv (a command-line media player)
+mpv:
+mpv: mpv is a free (as in freedom) media player for the command line. It
+mpv: supports a wide variety of media file formats, audio and video codecs,
+mpv: and subtitle types. Powerful scripting capabilities can make the
+mpv: player do almost anything. While mpv strives for minimalism and
+mpv: provides no real GUI, it has a small controller on top of the video
+mpv: for basic control.
+mpv:
+mpv: Homepage: https://mpv.io/
+mpv:
diff --git a/source/xap/pan/pan.SlackBuild b/source/xap/pan/pan.SlackBuild
index fb7db80ab..1310a1068 100755
--- a/source/xap/pan/pan.SlackBuild
+++ b/source/xap/pan/pan.SlackBuild
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2018, 2019, 2021, 2023 Patrick J. Volkerding, Sebeka, MN, USA
+# Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2018, 2019, 2021, 2023, 2024 Patrick J. Volkerding, Sebeka, MN, USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -29,7 +29,7 @@ BUILD=${BUILD:-1}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -47,14 +47,15 @@ fi
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
+ LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
+ LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
+ LIBDIRSUFFIX=""
fi
TMP=${TMP:-/tmp}
@@ -75,38 +76,33 @@ find . \
\( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
-exec chmod 644 {} \+
-# Configure:
-if [ ! -r configure ]; then
- if [ -x ./autogen.sh ]; then
- NOCONFIGURE=1 ./autogen.sh
- else
- autoreconf -vif
- fi
-fi
-CFLAGS="$SLKCFLAGS" \
-CXXFLAGS="$SLKCFLAGS" \
-./configure \
- --prefix=/usr \
- --localstatedir=/var/lib \
- --sysconfdir=/etc \
- --mandir=/usr/man \
- --with-gnutls \
- --with-gmime-crypto \
- --with-gtkspell \
- --enable-libnotify \
- --enable-gkr \
- --program-prefix= \
- --program-suffix= \
- --build=$ARCH-slackware-linux || exit 1
-
-# Build and install:
-make $NUMJOBS || make || exit 1
-make install DESTDIR=$PKG || exit 1
+# Configure, build, and install:
+mkdir cmake-build
+cd cmake-build
+ cmake \
+ -DCMAKE_C_FLAGS="$SLKCFLAGS" \
+ -DCMAKE_CXX_FLAGS="$SLKCFLAGS" \
+ -DCMAKE_INSTALL_PREFIX=/usr \
+ -DLIB_SUFFIX="$LIBDIRSUFFIX" \
+ -DDOC_INSTALL_DIR="doc" \
+ -DMAN_INSTALL_DIR=/usr/man \
+ -DWANT_GNUTLS=ON \
+ -DWANT_GMIME_CRYPTO=ON \
+ -DWANT_GTKSPELL=ON \
+ -DWANT_NOTIFY=ON \
+ -DWANT_GKR=ON \
+ .. || exit 1
+ make $NUMJOBS || make || exit 1
+ make install DESTDIR=$PKG || exit 1
+cd ..
# Strip binaries:
find $PKG | xargs file | grep -e "executable" -e "shared object" \
| grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
+# Move this since there's no config option for /usr/man:
+mv $PKG/usr/share/man $PKG/usr/man
+
# Compress and link manpages, if any:
if [ -d $PKG/usr/man ]; then
( cd $PKG/usr/man
@@ -122,18 +118,10 @@ if [ -d $PKG/usr/man ]; then
)
fi
-# Compress info files, if any:
-if [ -d $PKG/usr/info ]; then
- ( cd $PKG/usr/info
- rm -f dir
- gzip -9 *
- )
-fi
-
# Add a documentation directory:
mkdir -p $PKG/usr/doc/${PKGNAM}-$VERSION
cp -a \
- AUTHORS COPYING* NEWS README* TODO \
+ AUTHORS* COPYING* NEWS* README* TODO* \
$PKG/usr/doc/${PKGNAM}-$VERSION
# junk removal
rm -f $PKG/usr/doc/${PKGNAM}-$VERSION/{README.mingw,README.windows*}
diff --git a/source/xap/pan/pan.url b/source/xap/pan/pan.url
index c9b9c2991..803fef43e 100644
--- a/source/xap/pan/pan.url
+++ b/source/xap/pan/pan.url
@@ -1 +1,2 @@
https://gitlab.gnome.org/GNOME/pan/
+https://gitlab.gnome.org/GNOME/pan/-/archive/v0.160/pan-v0.160.tar.gz
diff --git a/source/xap/pavucontrol/pavucontrol.SlackBuild b/source/xap/pavucontrol/pavucontrol.SlackBuild
index db8b576ba..ee1e05151 100755
--- a/source/xap/pavucontrol/pavucontrol.SlackBuild
+++ b/source/xap/pavucontrol/pavucontrol.SlackBuild
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright 2015, 2018 Patrick J. Volkerding, Sebeka, Minnesota, USA
+# Copyright 2015, 2018, 2024 Patrick J. Volkerding, Sebeka, Minnesota, USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -30,7 +30,7 @@ NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) ARCH=i586 ;;
+ i?86) ARCH=i686 ;;
arm*) ARCH=arm ;;
*) ARCH=$( uname -m ) ;;
esac
@@ -47,14 +47,11 @@ fi
TMP=${TMP:-/tmp}
PKG=$TMP/package-$PKGNAM
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-O2 -march=i686 -mtune=i686"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
@@ -76,25 +73,38 @@ find -L . \
\( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
-o -perm 440 -o -perm 400 \) -exec chmod 644 {} \+
-CFLAGS="$SLKCFLAGS" \
-CXXFLAGS="$SLKCFLAGS -std=c++11" \
-./configure \
+# Configure, build, and install:
+export CFLAGS="$SLKCFLAGS"
+export CXXFLAGS="$SLKCFLAGS"
+mkdir meson-build
+cd meson-build
+meson setup \
--prefix=/usr \
- --libdir=/usr/lib${LIBDIRSUFFIX} \
+ --libdir=lib${LIBDIRSUFFIX} \
+ --libexecdir=/usr/libexec \
+ --bindir=/usr/bin \
+ --sbindir=/usr/sbin \
+ --includedir=/usr/include \
+ --datadir=/usr/share \
+ --mandir=/usr/man \
--sysconfdir=/etc \
--localstatedir=/var \
- --mandir=/usr/man \
- --docdir=/usr/doc/$PKGNAM-$VERSION \
- --build=$ARCH-slackware-linux || exit 1
+ --buildtype=release \
+ .. || exit 1
+ "${NINJA:=ninja}" $NUMJOBS || exit 1
+ DESTDIR=$PKG $NINJA install || exit 1
+cd ..
-make $NUMJOBS || make || exit 1
-make install DESTDIR=$PKG || exit 1
+# move this stuff
+mkdir -p $PKG/usr/doc
+mv $PKG/usr/share/doc/pavucontrol $PKG/usr/doc/$PKGNAM-$VERSION
+rm -rf $PKG/usr/share/doc
find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \
| cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
mkdir -p $PKG/usr/doc/$PKGNAM-$VERSION
-cp -a COPYING* doc/README* LICENSE $PKG/usr/doc/$PKGNAM-$VERSION
+cp -a LICENSE* $PKG/usr/doc/$PKGNAM-$VERSION
mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc
diff --git a/source/xap/pidgin/pidgin.SlackBuild b/source/xap/pidgin/pidgin.SlackBuild
index 18362ef80..6fab57a2d 100755
--- a/source/xap/pidgin/pidgin.SlackBuild
+++ b/source/xap/pidgin/pidgin.SlackBuild
@@ -25,7 +25,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=pidgin
VERSION=${VERSION:-$(echo $PKGNAM-2.*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
PIDGINENC=${PIDGINENC:-3.1}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
@@ -74,6 +74,9 @@ else
ARCHQUADLET=""
fi
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=int-conversion"
+
cd $TMP
rm -rf ${PKGNAM}-${VERSION}
tar xvf $CWD/${PKGNAM}-$VERSION.tar.?z || exit 1
@@ -173,6 +176,8 @@ done
PIDGIN_LIBS="-L${PKG}/usr/lib${LIBDIRSUFFIX}" \
PURPLE_CFLAGS="-I${PKG}/usr/include/libpurple" \
PURPLE_LIBS="-L${PKG}/usr/lib${LIBDIRSUFFIX}" \
+ CFLAGS="$SLKCFLAGS" \
+ CXXFLAGS="$SLKCFLAGS" \
./configure \
--prefix=/usr \
--libdir=/usr/lib${LIBDIRSUFFIX} \
diff --git a/source/xap/rdesktop/rdesktop.SlackBuild b/source/xap/rdesktop/rdesktop.SlackBuild
index 63086bb5b..ce1b5235f 100755
--- a/source/xap/rdesktop/rdesktop.SlackBuild
+++ b/source/xap/rdesktop/rdesktop.SlackBuild
@@ -55,6 +55,9 @@ elif [ "$ARCH" = "x86_64" ]; then
LIBDIRSUFFIX="64"
fi
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=incompatible-pointer-types"
+
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
TMP=${TMP:-/tmp}
diff --git a/source/xap/rxvt-unicode/rxvt-unicode.SlackBuild b/source/xap/rxvt-unicode/rxvt-unicode.SlackBuild
index 0135cdab3..b161d2d34 100755
--- a/source/xap/rxvt-unicode/rxvt-unicode.SlackBuild
+++ b/source/xap/rxvt-unicode/rxvt-unicode.SlackBuild
@@ -24,7 +24,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=rxvt-unicode
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-3}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
diff --git a/source/xap/sane/sane.SlackBuild b/source/xap/sane/sane.SlackBuild
index 3e700ba30..d8e40d7f3 100755
--- a/source/xap/sane/sane.SlackBuild
+++ b/source/xap/sane/sane.SlackBuild
@@ -23,7 +23,7 @@
cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=sane
-BACKVER=1.3.0
+BACKVER=1.3.1
FRONTVER=1.0.14
VERSION=${VERSION:-$BACKVER}
BUILD=${BUILD:-1}
@@ -62,6 +62,9 @@ else
LIBDIRSUFFIX=""
fi
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=implicit-function-declaration"
+
TMP=${TMP:-/tmp}
PKG=$TMP/package-sane
@@ -70,9 +73,9 @@ mkdir -p $TMP $PKG
# First, we'll build the backends
cd $TMP
-rm -rf backends-$BACKVER
-tar xvf $CWD/backends-$BACKVER.tar.?z || exit 1
-cd backends-$BACKVER || exit 1
+rm -rf sane-backends-$BACKVER
+tar xvf $CWD/sane-backends-$BACKVER.tar.?z || exit 1
+cd sane-backends-$BACKVER || exit 1
chown -R root:root .
# Put the SANE_CAP_ALWAYS_SETTABLE definition back until
diff --git a/source/xap/seamonkey/seamonkey.SlackBuild b/source/xap/seamonkey/seamonkey.SlackBuild
index 542f7ba2a..acda41178 100755
--- a/source/xap/seamonkey/seamonkey.SlackBuild
+++ b/source/xap/seamonkey/seamonkey.SlackBuild
@@ -1,6 +1,6 @@
#!/bin/bash
-# Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2020, 2021, 2022, 2023 Patrick J. Volkerding, Sebeka, MN, USA
+# Copyright 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2020, 2021, 2022, 2023, 2024 Patrick J. Volkerding, Sebeka, MN, USA
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@@ -151,6 +151,7 @@ OPTIONS="\
--disable-debug \
--disable-install-strip \
--disable-necko-wifi \
+ --disable-rust-simd \
--disable-strip \
--disable-updater \
--enable-accessibility \
@@ -174,6 +175,7 @@ OPTIONS="\
export BUILD_OFFICIAL=1
export MOZILLA_OFFICIAL=1
export MOZ_MAKE_FLAGS="$NUMJOBS"
+export MACH_USE_SYSTEM_PYTHON="1"
# Clear some variables that could break the build
unset DBUS_SESSION_BUS_ADDRESS ORBIT_SOCKETDIR SESSION_MANAGER \
diff --git a/source/xap/seamonkey/seamonkey.url b/source/xap/seamonkey/seamonkey.url
new file mode 100644
index 000000000..8292880c0
--- /dev/null
+++ b/source/xap/seamonkey/seamonkey.url
@@ -0,0 +1 @@
+https://archive.seamonkey-project.org/releases/2.53.19/source/seamonkey-2.53.19.source.tar.xz
diff --git a/source/xap/seyon/seyon.SlackBuild b/source/xap/seyon/seyon.SlackBuild
index ae3087113..9b478f420 100755
--- a/source/xap/seyon/seyon.SlackBuild
+++ b/source/xap/seyon/seyon.SlackBuild
@@ -93,7 +93,7 @@ sed -i "s/getline/seyon_getline/g" *
chmod 755 makever.sh
xmkmf
# Add -fcommon to CFLAGS:
-sed -i -e 's/-fno-strict-aliasing/-fno-strict-aliasing -fcommon/' Makefile
+sed -i -e 's/-fno-strict-aliasing/-fno-strict-aliasing -fcommon -Wno-error=implicit-function-declaration/' Makefile
make || exit 1
mkdir -p $PKG/usr/lib${LIBDIRSUFFIX}/X11
diff --git a/source/xap/ssr/0010-plthook.patch b/source/xap/ssr/0010-plthook.patch
new file mode 100644
index 000000000..86a26e6c3
--- /dev/null
+++ b/source/xap/ssr/0010-plthook.patch
@@ -0,0 +1,2349 @@
+From 83b8f9f5d9c9ab06152657e57f85b6f71954a6b9 Mon Sep 17 00:00:00 2001
+From: Maarten Baert <maarten-baert@hotmail.com>
+Date: Sun, 1 May 2022 22:48:24 +0200
+Bug: https://github.com/MaartenBaert/ssr/issues/947
+Bug-Debian: https://bugs.debian.org/1040375
+Forwarded: not-needed
+Origin: https://github.com/MaartenBaert/ssr/commit/83b8f9f5d9c9ab06152657e57f85b6f71954a6b9
+Last-Updated: 2024-05-07
+Subject: [PATCH] Switch to PLT hooks to make GLInject work with new
+ dlopen/dlsym in libc
+
+---
+ data/resources/about.htm | 4 +-
+ glinject/CMakeLists.txt | 4 +-
+ glinject/Hook.cpp | 425 ++++++++++----------
+ glinject/ShmStructs.h | 2 +
+ glinject/elfhacks.c | 611 -----------------------------
+ glinject/elfhacks.h | 213 ----------
+ glinject/plthook.h | 67 ++++
+ glinject/plthook_elf.c | 821 +++++++++++++++++++++++++++++++++++++++
+ src/GUI/PageWelcome.cpp | 4 +-
+ 9 files changed, 1091 insertions(+), 1060 deletions(-)
+ delete mode 100644 glinject/elfhacks.c
+ delete mode 100644 glinject/elfhacks.h
+ create mode 100644 glinject/plthook.h
+ create mode 100644 glinject/plthook_elf.c
+
+Index: simplescreenrecorder-salsa/data/resources/about.htm
+===================================================================
+--- simplescreenrecorder-salsa.orig/data/resources/about.htm 2024-05-07 08:50:15.918773109 +0200
++++ simplescreenrecorder-salsa/data/resources/about.htm 2024-05-07 08:50:15.910773036 +0200
+@@ -21,8 +21,8 @@
+ <p>%USES%</p>
+ <ul>
+ <li>%USES_QT%
+-<li>%USES_LIBAV_FFMPEG%
+-<li>%USES_ELFHACKS%
++<li>%USES_FFMPEG%
++<li>%USES_PLTHOOK%
+ </ul>
+
+ <p><i>%VERSIONINFO%</i></p>
+Index: simplescreenrecorder-salsa/glinject/CMakeLists.txt
+===================================================================
+--- simplescreenrecorder-salsa.orig/glinject/CMakeLists.txt 2024-05-07 08:50:15.918773109 +0200
++++ simplescreenrecorder-salsa/glinject/CMakeLists.txt 2024-05-07 08:50:15.910773036 +0200
+@@ -5,14 +5,14 @@
+ find_package(OpenGL REQUIRED)
+
+ set(sources
+- elfhacks.c
+- elfhacks.h
+ GLInject.cpp
+ GLInject.h
+ Global.h
+ GLXFrameGrabber.cpp
+ GLXFrameGrabber.h
+ Hook.cpp
++ plthook_elf.c
++ plthook.h
+ ShmStructs.h
+ SSRVideoStreamWriter.cpp
+ SSRVideoStreamWriter.h
+Index: simplescreenrecorder-salsa/glinject/Hook.cpp
+===================================================================
+--- simplescreenrecorder-salsa.orig/glinject/Hook.cpp 2024-05-07 08:50:15.918773109 +0200
++++ simplescreenrecorder-salsa/glinject/Hook.cpp 2024-05-07 08:50:15.910773036 +0200
+@@ -8,152 +8,130 @@
+
+ #include "Global.h"
+
+-#include "elfhacks.h"
+ #include "GLInject.h"
+ #include "GLXFrameGrabber.h"
++#include "plthook.h"
++
++#include <dlfcn.h>
++#include <link.h>
+
+ #include <GL/glx.h>
+ #include <X11/X.h>
+
++// global variable from the standard library that holds all environment variables
+ extern char **environ;
+
++// return type of glXGetProcAddressARB
+ typedef void (*GLXextFuncPtr)(void);
+
+-void InitGLInject();
+-void FreeGLInject();
++// hook replacement function prototypes
++void* glinject_hook_dlsym(void* handle, const char* symbol);
++void* glinject_hook_dlvsym(void* handle, const char* symbol, const char* version);
++int glinject_hook_execl(const char* filename, const char* arg, ...);
++int glinject_hook_execlp(const char* filename, const char* arg, ...);
++int glinject_hook_execle(const char* filename, const char* arg, ...);
++int glinject_hook_execv(const char* filename, char* const argv[]);
++int glinject_hook_execve(const char* filename, char* const argv[], char* const envp[]);
++int glinject_hook_execvp(const char* filename, char* const argv[]);
++int glinject_hook_execvpe(const char* filename, char* const argv[], char* const envp[]);
++GLXWindow glinject_hook_glXCreateWindow(Display* dpy, GLXFBConfig config, Window win, const int* attrib_list);
++void glinject_hook_glXDestroyWindow(Display* dpy, GLXWindow win);
++int glinject_hook_XDestroyWindow(Display* dpy, Window win);
++void glinject_hook_glXSwapBuffers(Display* dpy, GLXDrawable drawable);
++GLXextFuncPtr glinject_hook_glXGetProcAddressARB(const GLubyte *proc_name);
+
+-GLXWindow glinject_my_glXCreateWindow(Display* dpy, GLXFBConfig config, Window win, const int* attrib_list);
+-void glinject_my_glXDestroyWindow(Display* dpy, GLXWindow win);
+-int glinject_my_XDestroyWindow(Display* dpy, Window win);
+-void glinject_my_glXSwapBuffers(Display* dpy, GLXDrawable drawable);
+-GLXextFuncPtr glinject_my_glXGetProcAddressARB(const GLubyte *proc_name);
+-int glinject_my_XNextEvent(Display* display, XEvent* event_return);
+-
+-void *(*g_glinject_real_dlsym)(void*, const char*) = NULL;
+-void *(*g_glinject_real_dlvsym)(void*, const char*, const char*) = NULL;
+-int (*g_glinject_real_execv)(const char*, char* const*) = NULL;
+-int (*g_glinject_real_execve)(const char*, char* const*, char* const*) = NULL;
+-int (*g_glinject_real_execvp)(const char*, char* const*) = NULL;
+-int (*g_glinject_real_execvpe)(const char*, char* const*, char* const*) = NULL;
+-GLXWindow (*g_glinject_real_glXCreateWindow)(Display*, GLXFBConfig, Window, const int*) = NULL;
+-void (*g_glinject_real_glXDestroyWindow)(Display*, GLXWindow) = NULL;
+-int (*g_glinject_real_XDestroyWindow)(Display*, Window) = NULL;
+-void (*g_glinject_real_glXSwapBuffers)(Display*, GLXDrawable) = NULL;
+-GLXextFuncPtr (*g_glinject_real_glXGetProcAddressARB)(const GLubyte*) = NULL;
+-int (*g_glinject_real_XNextEvent)(Display*, XEvent*) = NULL;
++// hook table
++struct GLInjectHook {
++ const char *name;
++ void *address;
++};
++std::initializer_list<GLInjectHook> glinject_hook_table = {
++ {"dlsym" , (void*) &glinject_hook_dlsym},
++ {"dlvsym" , (void*) &glinject_hook_dlvsym},
++ {"execl" , (void*) &glinject_hook_execl},
++ {"execlp" , (void*) &glinject_hook_execlp},
++ {"execle" , (void*) &glinject_hook_execle},
++ {"execv" , (void*) &glinject_hook_execv},
++ {"execve" , (void*) &glinject_hook_execve},
++ {"execvp" , (void*) &glinject_hook_execvp},
++ {"execvpe" , (void*) &glinject_hook_execvpe},
++ {"glXCreateWindow" , (void*) &glinject_hook_glXCreateWindow},
++ {"glXDestroyWindow" , (void*) &glinject_hook_glXDestroyWindow},
++ {"XDestroyWindow" , (void*) &glinject_hook_XDestroyWindow},
++ {"glXSwapBuffers" , (void*) &glinject_hook_glXSwapBuffers},
++ {"glXGetProcAddressARB", (void*) &glinject_hook_glXGetProcAddressARB},
++};
+
++// main glinject object and mutex
+ static GLInject *g_glinject = NULL;
+ static std::mutex g_glinject_mutex;
+
+-void InitGLInject() {
+- std::lock_guard<std::mutex> lock(g_glinject_mutex);
++// hook initializer
++static struct GLInjectHooksInitializer {
++ GLInjectHooksInitializer() {
++
++ // get the link table of the glinject library (we can use any global variable for this)
++ Dl_info glinject_dlinfo;
++ struct link_map *glinject_lmap = NULL;
++ if(dladdr1((void*) &glinject_hook_table, &glinject_dlinfo, (void**) &glinject_lmap, RTLD_DL_LINKMAP) == 0) {
++ GLINJECT_PRINT("Error: Failed to get link map of glinject library!");
++ return;
++ }
+
+- if(g_glinject != NULL)
+- return;
++ // replace PLT entries everywhere except in the glinject library
++ void *mainhandle = dlopen(NULL, RTLD_NOW);
++ if(mainhandle == NULL) {
++ GLINJECT_PRINT("Error: Failed to get main program handle!");
++ return;
++ }
++ struct link_map *lmap = NULL;
++ if(dlinfo(mainhandle, RTLD_DI_LINKMAP, &lmap) != 0) {
++ GLINJECT_PRINT("Error: Failed to get link map of main program!");
++ return;
++ }
++ while(lmap) {
++ if(lmap != glinject_lmap) {
++ plthook_t *plthook;
++ if(plthook_open_by_linkmap(&plthook, lmap) == 0) {
++ for(const GLInjectHook &hook : glinject_hook_table) {
++ void *oldfunc;
++ if(plthook_replace(plthook, hook.name, hook.address, &oldfunc) == 0) {
++ GLINJECT_PRINT("Hooked " << hook.name << " PLT entry in '" << lmap->l_name << "'.");
++ }
++ }
++ plthook_close(plthook);
++ }
++ }
++ lmap = lmap->l_next;
++ }
++ dlclose(mainhandle);
+
+- // part 1: get dlsym and dlvsym
+- eh_obj_t libdl;
+- if(eh_find_obj(&libdl, "*/libdl.so*")) {
+- GLINJECT_PRINT("Error: Can't open libdl.so!");
+- exit(1);
+- }
+- if(eh_find_sym(&libdl, "dlsym", (void**) &g_glinject_real_dlsym)) {
+- GLINJECT_PRINT("Error: Can't get dlsym address!");
+- eh_destroy_obj(&libdl);
+- exit(1);
+- }
+- if(eh_find_sym(&libdl, "dlvsym", (void**) &g_glinject_real_dlvsym)) {
+- GLINJECT_PRINT("Error: Can't get dlvsym address!");
+- eh_destroy_obj(&libdl);
+- exit(1);
+- }
+- eh_destroy_obj(&libdl);
+-
+- // part 2: get everything else
+- g_glinject_real_execv = (int (*)(const char*, char* const*)) g_glinject_real_dlsym(RTLD_NEXT, "execv");
+- if(g_glinject_real_execv == NULL) {
+- GLINJECT_PRINT("Error: Can't get execv address!");
+- exit(1);
+- }
+- g_glinject_real_execve = (int (*)(const char*, char* const*, char* const*)) g_glinject_real_dlsym(RTLD_NEXT, "execve");
+- if(g_glinject_real_execve == NULL) {
+- GLINJECT_PRINT("Error: Can't get execve address!");
+- exit(1);
+- }
+- g_glinject_real_execvp = (int (*)(const char*, char* const*)) g_glinject_real_dlsym(RTLD_NEXT, "execvp");
+- if(g_glinject_real_execvp == NULL) {
+- GLINJECT_PRINT("Error: Can't get execvp address!");
+- exit(1);
+- }
+- g_glinject_real_execvpe = (int (*)(const char*, char* const*, char* const*)) g_glinject_real_dlsym(RTLD_NEXT, "execvpe");
+- if(g_glinject_real_execvpe == NULL) {
+- GLINJECT_PRINT("Error: Can't get execvpe address!");
+- exit(1);
+- }
+- g_glinject_real_glXCreateWindow = (GLXWindow (*)(Display*, GLXFBConfig, Window, const int*)) g_glinject_real_dlsym(RTLD_NEXT, "glXCreateWindow");
+- if(g_glinject_real_glXCreateWindow == NULL) {
+- GLINJECT_PRINT("Error: Can't get glXCreateWindow address!");
+- exit(1);
+- }
+- g_glinject_real_glXDestroyWindow = (void (*)(Display*, GLXWindow)) g_glinject_real_dlsym(RTLD_NEXT, "glXDestroyWindow");
+- if(g_glinject_real_glXDestroyWindow == NULL) {
+- GLINJECT_PRINT("Error: Can't get glXDestroyWindow address!");
+- exit(1);
+- }
+- g_glinject_real_XDestroyWindow = (int (*)(Display*, Window)) g_glinject_real_dlsym(RTLD_NEXT, "XDestroyWindow");
+- if(g_glinject_real_XDestroyWindow == NULL) {
+- GLINJECT_PRINT("Error: Can't get XDestroyWindow address!");
+- exit(1);
+- }
+- g_glinject_real_glXSwapBuffers = (void (*)(Display*, GLXDrawable)) g_glinject_real_dlsym(RTLD_NEXT, "glXSwapBuffers");
+- if(g_glinject_real_glXSwapBuffers == NULL) {
+- GLINJECT_PRINT("Error: Can't get glXSwapBuffers address!");
+- exit(1);
+- }
+- g_glinject_real_glXGetProcAddressARB = (GLXextFuncPtr (*)(const GLubyte*)) g_glinject_real_dlsym(RTLD_NEXT, "glXGetProcAddressARB");
+- if(g_glinject_real_glXGetProcAddressARB == NULL) {
+- GLINJECT_PRINT("Error: Can't get glXGetProcAddressARB address!");
+- exit(1);
+- }
+- g_glinject_real_XNextEvent = (int (*)(Display*, XEvent*)) g_glinject_real_dlsym(RTLD_NEXT, "XNextEvent");
+- if(g_glinject_real_XNextEvent == NULL) {
+- GLINJECT_PRINT("Error: Can't get XNextEvent address!");
+- exit(1);
+ }
++} glinject_hooks_initializer;
+
+- g_glinject = new GLInject();
+-
+- atexit(FreeGLInject);
++void GLInjectInit();
++void GLInjectFree();
+
++void GLInjectInit() {
++ if(g_glinject != NULL)
++ return;
++ g_glinject = new GLInject();
++ atexit(GLInjectFree);
+ }
+
+-void FreeGLInject() {
+- std::lock_guard<std::mutex> lock(g_glinject_mutex);
++void GLInjectFree() {
+ if(g_glinject != NULL) {
+ delete g_glinject;
+ g_glinject = NULL;
+ }
+ }
+
+-struct Hook {
+- const char *name;
+- void *address;
+-};
+-static Hook hook_table[] = {
+- {"glXCreateWindow" , (void*) &glinject_my_glXCreateWindow},
+- {"glXDestroyWindow" , (void*) &glinject_my_glXDestroyWindow},
+- {"XDestroyWindow" , (void*) &glinject_my_XDestroyWindow},
+- {"glXSwapBuffers" , (void*) &glinject_my_glXSwapBuffers},
+- {"glXGetProcAddressARB", (void*) &glinject_my_glXGetProcAddressARB},
+- {"XNextEvent" , (void*) &glinject_my_XNextEvent},
+-};
+-static const char* exec_blacklist[] = {
+- "ping",
+- "/bin/ping",
+- "/usr/bin/ping",
+-};
+-
+ void FilterEnviron(const char* filename, std::vector<char*>* out, char* const* in) {
++ const char* exec_blacklist[] = {
++ "ping",
++ "/bin/ping",
++ "/usr/bin/ping",
++ };
+ bool filter = false;
+ for(unsigned int i = 0; i < sizeof(exec_blacklist) / sizeof(const char*); ++i) {
+ if(strcmp(exec_blacklist[i], filename) == 0) {
+@@ -169,90 +147,35 @@
+ out->push_back(NULL);
+ }
+
+-GLXWindow glinject_my_glXCreateWindow(Display* dpy, GLXFBConfig config, Window win, const int* attrib_list) {
+- GLXWindow res = g_glinject_real_glXCreateWindow(dpy, config, win, attrib_list);
+- if(res == 0)
+- return 0;
+- std::lock_guard<std::mutex> lock(g_glinject_mutex);
+- g_glinject->NewGLXFrameGrabber(dpy, win, res);
+- return res;
+-}
+-
+-void glinject_my_glXDestroyWindow(Display* dpy, GLXWindow win) {
+- g_glinject_real_glXDestroyWindow(dpy, win);
+- std::lock_guard<std::mutex> lock(g_glinject_mutex);
+- g_glinject->DeleteGLXFrameGrabberByDrawable(dpy, win);
+-}
+-
+-int glinject_my_XDestroyWindow(Display* dpy, Window win) {
+- int res = g_glinject_real_XDestroyWindow(dpy, win);
+- std::lock_guard<std::mutex> lock(g_glinject_mutex);
+- g_glinject->DeleteGLXFrameGrabberByWindow(dpy, win);
+- return res;
+-}
+-
+-void glinject_my_glXSwapBuffers(Display* dpy, GLXDrawable drawable) {
+- {
+- std::lock_guard<std::mutex> lock(g_glinject_mutex);
+- GLXFrameGrabber *fg = g_glinject->FindGLXFrameGrabber(dpy, drawable);
+- if(fg == NULL) {
+- GLINJECT_PRINT("Warning: glXSwapBuffers called without existing frame grabber, creating one assuming window == drawable.");
+- fg = g_glinject->NewGLXFrameGrabber(dpy, drawable, drawable);
+- }
+- fg->GrabFrame();
+- }
+- g_glinject_real_glXSwapBuffers(dpy, drawable);
+-}
+-
+-GLXextFuncPtr glinject_my_glXGetProcAddressARB(const GLubyte *proc_name) {
+- for(unsigned int i = 0; i < sizeof(hook_table) / sizeof(Hook); ++i) {
+- if(strcmp(hook_table[i].name, (const char*) proc_name) == 0) {
+- std::lock_guard<std::mutex> lock(g_glinject_mutex);
+- GLINJECT_PRINT("Hooked: glXGetProcAddressARB(" << proc_name << ").");
+- return (GLXextFuncPtr) hook_table[i].address;
+- }
+- }
+- return g_glinject_real_glXGetProcAddressARB(proc_name);
+-}
+-
+-int glinject_my_XNextEvent(Display* display, XEvent* event_return) {
+- int res = g_glinject_real_XNextEvent(display, event_return);
+- /*std::lock_guard<std::mutex> lock(g_glinject_mutex);
+- if(g_hotkey_info.enabled && event_return->type == KeyPress && event_return->xkey.keycode == g_hotkey_info.keycode
+- && (event_return->xkey.state & ~LockMask & ~Mod2Mask) == g_hotkey_info.modifiers) {
+- g_hotkey_pressed = true;
+- }*/
+- return res;
+-}
+-
+-// override existing functions
+-
+-extern "C" void* dlsym(void* handle, const char* symbol) {
+- InitGLInject();
+- for(unsigned int i = 0; i < sizeof(hook_table) / sizeof(Hook); ++i) {
+- if(strcmp(hook_table[i].name, symbol) == 0) {
++void* glinject_hook_dlsym(void* handle, const char* symbol) {
++ const char *str = "(In glinject_hook_dlsym)\n";
++ write(2, str, strlen(str));
++ for(const GLInjectHook &hook : glinject_hook_table) {
++ if(strcmp(hook.name, symbol) == 0) {
+ std::lock_guard<std::mutex> lock(g_glinject_mutex);
+- GLINJECT_PRINT("Hooked: dlsym(" << symbol << ").");
+- return hook_table[i].address;
++ GLINJECT_PRINT("Hooked dlsym(" << symbol << ").");
++ return hook.address;
+ }
+ }
+- return g_glinject_real_dlsym(handle, symbol);
++ return dlsym(handle, symbol);
+ }
+
+-extern "C" void* dlvsym(void* handle, const char* symbol, const char* version) {
+- InitGLInject();
+- for(unsigned int i = 0; i < sizeof(hook_table) / sizeof(Hook); ++i) {
+- if(strcmp(hook_table[i].name, symbol) == 0) {
++void* glinject_hook_dlvsym(void* handle, const char* symbol, const char* version) {
++ const char *str = "(In glinject_hook_dlvsym)\n";
++ write(2, str, strlen(str));
++ for(const GLInjectHook &hook : glinject_hook_table) {
++ if(strcmp(hook.name, symbol) == 0) {
+ std::lock_guard<std::mutex> lock(g_glinject_mutex);
+- GLINJECT_PRINT("Hooked: dlvsym(" << symbol << "," << version << ").");
+- return hook_table[i].address;
++ GLINJECT_PRINT("Hooked dlvsym(" << symbol << ").");
++ return hook.address;
+ }
+ }
+- return g_glinject_real_dlvsym(handle, symbol, version);
++ return dlvsym(handle, symbol, version);
+ }
+
+-extern "C" int execl(const char* filename, const char* arg, ...) {
+- InitGLInject();
++int glinject_hook_execl(const char* filename, const char* arg, ...) {
++ const char *str = "(In glinject_hook_execl)\n";
++ write(2, str, strlen(str));
+ std::vector<char*> args;
+ args.push_back((char*) arg);
+ va_list vl;
+@@ -263,11 +186,12 @@
+ va_end(vl);
+ std::vector<char*> filtered_environ;
+ FilterEnviron(filename, &filtered_environ, environ);
+- return g_glinject_real_execve(filename, args.data(), filtered_environ.data());
++ return execve(filename, args.data(), filtered_environ.data());
+ }
+
+-extern "C" int execlp(const char* filename, const char* arg, ...) {
+- InitGLInject();
++int glinject_hook_execlp(const char* filename, const char* arg, ...) {
++ const char *str = "(In glinject_hook_execlp)\n";
++ write(2, str, strlen(str));
+ std::vector<char*> args;
+ args.push_back((char*) arg);
+ va_list vl;
+@@ -278,11 +202,12 @@
+ va_end(vl);
+ std::vector<char*> filtered_environ;
+ FilterEnviron(filename, &filtered_environ, environ);
+- return g_glinject_real_execvpe(filename, args.data(), filtered_environ.data());
++ return execvpe(filename, args.data(), filtered_environ.data());
+ }
+
+-extern "C" int execle(const char* filename, const char* arg, ...) {
+- InitGLInject();
++int glinject_hook_execle(const char* filename, const char* arg, ...) {
++ const char *str = "(In glinject_hook_execle)\n";
++ write(2, str, strlen(str));
+ std::vector<char*> args;
+ args.push_back((char*) arg);
+ va_list vl;
+@@ -294,63 +219,103 @@
+ va_end(vl);
+ std::vector<char*> filtered_environ;
+ FilterEnviron(filename, &filtered_environ, envp);
+- return g_glinject_real_execvpe(filename, args.data(), filtered_environ.data());
++ return execvpe(filename, args.data(), filtered_environ.data());
+ }
+
+-extern "C" int execv(const char* filename, char* const argv[]) {
+- InitGLInject();
++int glinject_hook_execv(const char* filename, char* const argv[]) {
++ const char *str = "(In glinject_hook_execv)\n";
++ write(2, str, strlen(str));
+ std::vector<char*> filtered_environ;
+ FilterEnviron(filename, &filtered_environ, environ);
+- return g_glinject_real_execve(filename, argv, filtered_environ.data());
++ return execve(filename, argv, filtered_environ.data());
+ }
+
+-extern "C" int execve(const char* filename, char* const argv[], char* const envp[]) {
+- InitGLInject();
++int glinject_hook_execve(const char* filename, char* const argv[], char* const envp[]) {
++ const char *str = "(In glinject_hook_execve)\n";
++ write(2, str, strlen(str));
+ std::vector<char*> filtered_environ;
+ FilterEnviron(filename, &filtered_environ, envp);
+- return g_glinject_real_execve(filename, argv, filtered_environ.data());
++ return execve(filename, argv, filtered_environ.data());
+ }
+
+-extern "C" int execvp(const char* filename, char* const argv[]) {
+- InitGLInject();
++int glinject_hook_execvp(const char* filename, char* const argv[]) {
++ const char *str = "(In glinject_hook_execvp)\n";
++ write(2, str, strlen(str));
+ std::vector<char*> filtered_environ;
+ FilterEnviron(filename, &filtered_environ, environ);
+- return g_glinject_real_execvpe(filename, argv, filtered_environ.data());
++ return execvpe(filename, argv, filtered_environ.data());
+ }
+
+-extern "C" int execvpe(const char* filename, char* const argv[], char* const envp[]) {
+- InitGLInject();
++int glinject_hook_execvpe(const char* filename, char* const argv[], char* const envp[]) {
++ const char *str = "(In glinject_hook_execvpe)\n";
++ write(2, str, strlen(str));
+ std::vector<char*> filtered_environ;
+ FilterEnviron(filename, &filtered_environ, envp);
+- return g_glinject_real_execvpe(filename, argv, filtered_environ.data());
++ return execvpe(filename, argv, filtered_environ.data());
+ }
+
+-extern "C" GLXWindow glXCreateWindow(Display* dpy, GLXFBConfig config, Window win, const int* attrib_list) {
+- InitGLInject();
+- return glinject_my_glXCreateWindow(dpy, config, win, attrib_list);
+-}
+-
+-extern "C" void glXDestroyWindow(Display* dpy, GLXWindow win) {
+- InitGLInject();
+- glinject_my_glXDestroyWindow(dpy, win);
++GLXWindow glinject_hook_glXCreateWindow(Display* dpy, GLXFBConfig config, Window win, const int* attrib_list) {
++ const char *str = "(In glinject_hook_glXCreateWindow)\n";
++ write(2, str, strlen(str));
++ GLXWindow res = glXCreateWindow(dpy, config, win, attrib_list);
++ if(res == 0)
++ return 0;
++ {
++ std::lock_guard<std::mutex> lock(g_glinject_mutex);
++ GLInjectInit();
++ g_glinject->NewGLXFrameGrabber(dpy, win, res);
++ }
++ return res;
+ }
+
+-extern "C" int XDestroyWindow(Display* dpy, Window win) {
+- InitGLInject();
+- return glinject_my_XDestroyWindow(dpy, win);
++void glinject_hook_glXDestroyWindow(Display* dpy, GLXWindow win) {
++ const char *str = "(In glinject_hook_glXDestroyWindow)\n";
++ write(2, str, strlen(str));
++ glXDestroyWindow(dpy, win);
++ {
++ std::lock_guard<std::mutex> lock(g_glinject_mutex);
++ GLInjectInit();
++ g_glinject->DeleteGLXFrameGrabberByDrawable(dpy, win);
++ }
+ }
+
+-extern "C" void glXSwapBuffers(Display* dpy, GLXDrawable drawable) {
+- InitGLInject();
+- glinject_my_glXSwapBuffers(dpy, drawable);
++int glinject_hook_XDestroyWindow(Display* dpy, Window win) {
++ const char *str = "(In glinject_hook_XDestroyWindow)\n";
++ write(2, str, strlen(str));
++ int res = XDestroyWindow(dpy, win);
++ {
++ std::lock_guard<std::mutex> lock(g_glinject_mutex);
++ GLInjectInit();
++ g_glinject->DeleteGLXFrameGrabberByWindow(dpy, win);
++ }
++ return res;
+ }
+
+-extern "C" GLXextFuncPtr glXGetProcAddressARB(const GLubyte* proc_name) {
+- InitGLInject();
+- return glinject_my_glXGetProcAddressARB(proc_name);
++void glinject_hook_glXSwapBuffers(Display* dpy, GLXDrawable drawable) {
++ const char *str = "(In glinject_hook_glXSwapBuffers)\n";
++ write(2, str, strlen(str));
++ {
++ std::lock_guard<std::mutex> lock(g_glinject_mutex);
++ GLInjectInit();
++ GLXFrameGrabber *fg = g_glinject->FindGLXFrameGrabber(dpy, drawable);
++ if(fg == NULL) {
++ GLINJECT_PRINT("Warning: glXSwapBuffers called without existing frame grabber, creating one assuming window == drawable.");
++ fg = g_glinject->NewGLXFrameGrabber(dpy, drawable, drawable);
++ }
++ fg->GrabFrame();
++ }
++ glXSwapBuffers(dpy, drawable);
+ }
+
+-extern "C" int XNextEvent(Display* display, XEvent* event_return) {
+- InitGLInject();
+- return glinject_my_XNextEvent(display, event_return);
++GLXextFuncPtr glinject_hook_glXGetProcAddressARB(const GLubyte *proc_name) {
++ const char *str = "(In glinject_hook_glXGetProcAddressARB)\n";
++ write(2, str, strlen(str));
++ for(const GLInjectHook &hook : glinject_hook_table) {
++ if(strcmp(hook.name, (const char*) proc_name) == 0) {
++ std::lock_guard<std::mutex> lock(g_glinject_mutex);
++ GLINJECT_PRINT("Hooked glXGetProcAddressARB(" << proc_name << ").");
++ return (GLXextFuncPtr) hook.address;
++ }
++ }
++ return glXGetProcAddressARB(proc_name);
+ }
+Index: simplescreenrecorder-salsa/glinject/ShmStructs.h
+===================================================================
+--- simplescreenrecorder-salsa.orig/glinject/ShmStructs.h 2024-05-07 08:50:15.918773109 +0200
++++ simplescreenrecorder-salsa/glinject/ShmStructs.h 2024-05-07 08:50:15.910773036 +0200
+@@ -8,6 +8,8 @@
+
+ #pragma once
+
++#include <stdint.h>
++
+ /*
+ A captured video stream is transmitted to SimpleScreenRecorder using shared memory files (i.e. files in /dev/shm).
+ The system is entirely lock-free and thread-safe, but supports only a single reader and a single writer.
+Index: simplescreenrecorder-salsa/glinject/elfhacks.c
+===================================================================
+--- simplescreenrecorder-salsa.orig/glinject/elfhacks.c 2024-05-07 08:50:15.918773109 +0200
++++ /dev/null 1970-01-01 00:00:00.000000000 +0000
+@@ -1,611 +0,0 @@
+-/**
+- * \file src/elfhacks.c
+- * \brief various ELF run-time hacks
+- * \author Pyry Haulos <pyry.haulos@gmail.com>
+- * \date 2007-2008
+- * For conditions of distribution and use, see copyright notice in elfhacks.h
+- */
+-
+-#ifndef _GNU_SOURCE
+-#define _GNU_SOURCE
+-#endif
+-
+-#include <stdlib.h>
+-#include <stdio.h>
+-#include <string.h>
+-#include <errno.h>
+-#include <elf.h>
+-#include <link.h>
+-#include <fnmatch.h>
+-#include "elfhacks.h"
+-
+-/**
+- * \addtogroup elfhacks
+- * \{
+- */
+-
+-struct eh_iterate_callback_args {
+- eh_iterate_obj_callback_func callback;
+- void *arg;
+-};
+-
+-int eh_check_addr(eh_obj_t *obj, const void *addr);
+-int eh_find_callback(struct dl_phdr_info *info, size_t size, void *argptr);
+-int eh_find_next_dyn(eh_obj_t *obj, ElfW_Sword tag, int i, ElfW(Dyn) **next);
+-int eh_init_obj(eh_obj_t *obj);
+-
+-int eh_set_rela_plt(eh_obj_t *obj, int p, const char *sym, void *val);
+-int eh_set_rel_plt(eh_obj_t *obj, int p, const char *sym, void *val);
+-
+-int eh_iterate_rela_plt(eh_obj_t *obj, int p, eh_iterate_rel_callback_func callback, void *arg);
+-int eh_iterate_rel_plt(eh_obj_t *obj, int p, eh_iterate_rel_callback_func callback, void *arg);
+-
+-int eh_find_sym_hash(eh_obj_t *obj, const char *name, eh_sym_t *sym);
+-int eh_find_sym_gnu_hash(eh_obj_t *obj, const char *name, eh_sym_t *sym);
+-
+-ElfW(Word) eh_hash_elf(const char *name);
+-Elf32_Word eh_hash_gnu(const char *name);
+-
+-int eh_find_callback(struct dl_phdr_info *info, size_t size, void *argptr)
+-{
+- (void) (size);
+- eh_obj_t *find = (eh_obj_t *) argptr;
+-
+- if (find->name == NULL) {
+- if (strcmp(info->dlpi_name, ""))
+- return 0;
+- } else if (fnmatch(find->name, info->dlpi_name, 0))
+- return 0;
+-
+- if (find->name == NULL) /* TODO readlink? */
+- find->name = "/proc/self/exe";
+- else
+- find->name = info->dlpi_name;
+- find->addr = info->dlpi_addr;
+-
+- /* segment headers */
+- find->phdr = info->dlpi_phdr;
+- find->phnum = info->dlpi_phnum;
+-
+- return 0;
+-}
+-
+-int eh_iterate_callback(struct dl_phdr_info *info, size_t size, void *argptr)
+-{
+- (void) (size);
+- struct eh_iterate_callback_args *args = (struct eh_iterate_callback_args*) argptr;
+- eh_obj_t obj;
+- int ret = 0;
+-
+- /* eh_init_obj needs phdr and phnum */
+- obj.phdr = info->dlpi_phdr;
+- obj.phnum = info->dlpi_phnum;
+- obj.addr = info->dlpi_addr;
+- obj.name = info->dlpi_name;
+-
+- if ((ret = eh_init_obj(&obj))) {
+- if (ret == ENOTSUP) /* just skip */
+- return 0;
+- return ret;
+- }
+-
+- if ((ret = args->callback(&obj, args->arg)))
+- return ret;
+-
+- if ((ret = eh_destroy_obj(&obj)))
+- return ret;
+-
+- return 0;
+-}
+-
+-int eh_iterate_obj(eh_iterate_obj_callback_func callback, void *arg)
+-{
+- int ret;
+- struct eh_iterate_callback_args args;
+-
+- args.callback = callback;
+- args.arg = arg;
+-
+- if ((ret = dl_iterate_phdr(eh_iterate_callback, &args)))
+- return ret;
+-
+- return 0;
+-}
+-
+-int eh_find_obj(eh_obj_t *obj, const char *soname)
+-{
+- /* This function uses glibc-specific dl_iterate_phdr().
+- Another way could be parsing /proc/self/exe or using
+- pmap() on Solaris or *BSD */
+- obj->phdr = NULL;
+- obj->name = soname;
+- dl_iterate_phdr(eh_find_callback, obj);
+-
+- if (!obj->phdr)
+- return EAGAIN;
+-
+- return eh_init_obj(obj);
+-}
+-
+-int eh_check_addr(eh_obj_t *obj, const void *addr)
+-{
+- /*
+- Check that given address is inside program's
+- memory maps. PT_LOAD program headers tell us
+- where program has been loaded into.
+- */
+- int p;
+- for (p = 0; p < obj->phnum; p++) {
+- if (obj->phdr[p].p_type == PT_LOAD) {
+- if (((ElfW(Addr)) addr < obj->phdr[p].p_memsz + obj->phdr[p].p_vaddr + obj->addr) &&
+- ((ElfW(Addr)) addr >= obj->phdr[p].p_vaddr + obj->addr))
+- return 0;
+- }
+- }
+-
+- return EINVAL;
+-}
+-
+-int eh_init_obj(eh_obj_t *obj)
+-{
+- /*
+- ELF spec says in section header documentation, that:
+- "An object file may have only one dynamic section."
+-
+- Let's assume it means that object has only one PT_DYNAMIC
+- as well.
+- */
+- int p;
+- obj->dynamic = NULL;
+- for (p = 0; p < obj->phnum; p++) {
+- if (obj->phdr[p].p_type == PT_DYNAMIC) {
+- if (obj->dynamic)
+- return ENOTSUP;
+-
+- obj->dynamic = (ElfW(Dyn) *) (obj->phdr[p].p_vaddr + obj->addr);
+- }
+- }
+-
+- if (!obj->dynamic)
+- return ENOTSUP;
+-
+- /*
+- ELF spec says that program is allowed to have more than one
+- .strtab but does not describe how string table indexes translate
+- to multiple string tables.
+-
+- And spec says that only one SHT_HASH is allowed, does it mean that
+- obj has only one DT_HASH?
+-
+- About .symtab it does not mention anything about if multiple
+- symbol tables are allowed or not.
+-
+- Maybe st_shndx is the key here?
+- */
+- obj->strtab = NULL;
+- obj->hash = NULL;
+- obj->gnu_hash = NULL;
+- obj->symtab = NULL;
+- p = 0;
+- while (obj->dynamic[p].d_tag != DT_NULL) {
+- if (obj->dynamic[p].d_tag == DT_STRTAB) {
+- if (obj->strtab)
+- return ENOTSUP;
+-
+- obj->strtab = (const char *) obj->dynamic[p].d_un.d_ptr;
+- } else if (obj->dynamic[p].d_tag == DT_HASH) {
+- if (obj->hash)
+- return ENOTSUP;
+-
+- obj->hash = (ElfW(Word) *) obj->dynamic[p].d_un.d_ptr;
+- } else if (obj->dynamic[p].d_tag == DT_GNU_HASH) {
+- if (obj->gnu_hash)
+- return ENOTSUP;
+-
+- obj->gnu_hash = (Elf32_Word *) obj->dynamic[p].d_un.d_ptr;
+- } else if (obj->dynamic[p].d_tag == DT_SYMTAB) {
+- if (obj->symtab)
+- return ENOTSUP;
+-
+- obj->symtab = (ElfW(Sym) *) obj->dynamic[p].d_un.d_ptr;
+- }
+- p++;
+- }
+-
+- /* This is here to catch b0rken headers (vdso) */
+- if ((eh_check_addr(obj, (const void *) obj->strtab)) |
+- (eh_check_addr(obj, (const void *) obj->symtab)))
+- return ENOTSUP;
+-
+- if (obj->hash) {
+- /* DT_HASH found */
+- if (eh_check_addr(obj, (void *) obj->hash))
+- obj->hash = NULL;
+- } else if (obj->gnu_hash) {
+- /* DT_GNU_HASH found */
+- if (eh_check_addr(obj, (void *) obj->gnu_hash))
+- obj->gnu_hash = NULL;
+- }
+-
+- return 0;
+-}
+-
+-int eh_find_sym(eh_obj_t *obj, const char *name, void **to)
+-{
+- eh_sym_t sym;
+-
+- /* DT_GNU_HASH is faster ;) */
+- if (obj->gnu_hash) {
+- if (!eh_find_sym_gnu_hash(obj, name, &sym)) {
+- *to = (void *) (sym.sym->st_value + obj->addr);
+- return 0;
+- }
+- }
+-
+- /* maybe it is in DT_HASH or DT_GNU_HASH is not present */
+- if (obj->hash) {
+- if (!eh_find_sym_hash(obj, name, &sym)) {
+- *to = (void *) (sym.sym->st_value + obj->addr);
+- return 0;
+- }
+- }
+-
+- return EAGAIN;
+-}
+-
+-ElfW(Word) eh_hash_elf(const char *name)
+-{
+- ElfW(Word) tmp, hash = 0;
+- const unsigned char *uname = (const unsigned char *) name;
+- int c;
+-
+- while ((c = *uname++) != '\0') {
+- hash = (hash << 4) + c;
+- if ((tmp = (hash & 0xf0000000)) != 0) {
+- hash ^= tmp >> 24;
+- hash ^= tmp;
+- }
+- }
+-
+- return hash;
+-}
+-
+-int eh_find_sym_hash(eh_obj_t *obj, const char *name, eh_sym_t *sym)
+-{
+- ElfW(Word) hash, *chain;
+- ElfW(Sym) *esym;
+- unsigned int bucket_idx, idx;
+-
+- if (!obj->hash)
+- return ENOTSUP;
+-
+- if (obj->hash[0] == 0)
+- return EAGAIN;
+-
+- hash = eh_hash_elf(name);
+- /*
+- First item in DT_HASH is nbucket, second is nchain.
+- hash % nbucket gives us our bucket index.
+- */
+- bucket_idx = obj->hash[2 + (hash % obj->hash[0])];
+- chain = &obj->hash[2 + obj->hash[0] + bucket_idx];
+-
+- idx = 0;
+- sym->sym = NULL;
+-
+- /* we have to check symtab[bucket_idx] first */
+- esym = &obj->symtab[bucket_idx];
+- if (esym->st_name) {
+- if (!strcmp(&obj->strtab[esym->st_name], name))
+- sym->sym = esym;
+- }
+-
+- while ((sym->sym == NULL) &&
+- (chain[idx] != STN_UNDEF)) {
+- esym = &obj->symtab[chain[idx]];
+-
+- if (esym->st_name) {
+- if (!strcmp(&obj->strtab[esym->st_name], name))
+- sym->sym = esym;
+- }
+-
+- idx++;
+- }
+-
+- /* symbol not found */
+- if (sym->sym == NULL)
+- return EAGAIN;
+-
+- sym->obj = obj;
+- sym->name = &obj->strtab[sym->sym->st_name];
+-
+- return 0;
+-}
+-
+-Elf32_Word eh_hash_gnu(const char *name)
+-{
+- Elf32_Word hash = 5381;
+- const unsigned char *uname = (const unsigned char *) name;
+- int c;
+-
+- while ((c = *uname++) != '\0')
+- hash = (hash << 5) + hash + c;
+-
+- return hash & 0xffffffff;
+-}
+-
+-int eh_find_sym_gnu_hash(eh_obj_t *obj, const char *name, eh_sym_t *sym)
+-{
+- Elf32_Word *buckets, *chain_zero, *hasharr;
+- ElfW(Addr) *bitmask, bitmask_word;
+- Elf32_Word symbias, bitmask_nwords, bucket,
+- nbuckets, bitmask_idxbits, shift;
+- Elf32_Word hash, hashbit1, hashbit2;
+- ElfW(Sym) *esym;
+-
+- if (!obj->gnu_hash)
+- return ENOTSUP;
+-
+- if (obj->gnu_hash[0] == 0)
+- return EAGAIN;
+-
+- sym->sym = NULL;
+-
+- /*
+- Initialize our hash table stuff
+-
+- DT_GNU_HASH is(?):
+- [nbuckets] [symbias] [bitmask_nwords] [shift]
+- [bitmask_nwords * ElfW(Addr)] <- bitmask
+- [nbuckets * Elf32_Word] <- buckets
+- ...chains? - symbias...
+- */
+- nbuckets = obj->gnu_hash[0];
+- symbias = obj->gnu_hash[1];
+- bitmask_nwords = obj->gnu_hash[2]; /* must be power of two */
+- bitmask_idxbits = bitmask_nwords - 1;
+- shift = obj->gnu_hash[3];
+- bitmask = (ElfW(Addr) *) &obj->gnu_hash[4];
+- buckets = &obj->gnu_hash[4 + (__ELF_NATIVE_CLASS / 32) * bitmask_nwords];
+- chain_zero = &buckets[nbuckets] - symbias;
+-
+- /* hash our symbol */
+- hash = eh_hash_gnu(name);
+-
+- /* bitmask stuff... no idea really :D */
+- bitmask_word = bitmask[(hash / __ELF_NATIVE_CLASS) & bitmask_idxbits];
+- hashbit1 = hash & (__ELF_NATIVE_CLASS - 1);
+- hashbit2 = (hash >> shift) & (__ELF_NATIVE_CLASS - 1);
+-
+- /* wtf this does actually? */
+- if (!((bitmask_word >> hashbit1) & (bitmask_word >> hashbit2) & 1))
+- return EAGAIN;
+-
+- /* locate bucket */
+- bucket = buckets[hash % nbuckets];
+- if (bucket == 0)
+- return EAGAIN;
+-
+- /* and find match in chain */
+- hasharr = &chain_zero[bucket];
+- do {
+- if (((*hasharr ^ hash) >> 1) == 0) {
+- /* hash matches, but does the name? */
+- esym = &obj->symtab[hasharr - chain_zero];
+- if (esym->st_name) {
+- if (!strcmp(&obj->strtab[esym->st_name], name)) {
+- sym->sym = esym;
+- break;
+- }
+- }
+- }
+- } while ((*hasharr++ & 1u) == 0);
+-
+- /* symbol not found */
+- if (sym->sym == NULL)
+- return EAGAIN;
+-
+- sym->obj = obj;
+- sym->name = &obj->strtab[sym->sym->st_name];
+-
+- return 0;
+-}
+-
+-int eh_iterate_sym(eh_obj_t *obj, eh_iterate_sym_callback_func callback, void *arg)
+-{
+- (void) (obj);
+- (void) (callback);
+- (void) (arg);
+- return ENOTSUP;
+-}
+-
+-int eh_find_next_dyn(eh_obj_t *obj, ElfW_Sword tag, int i, ElfW(Dyn) **next)
+-{
+- /* first from i + 1 to end, then from start to i - 1 */
+- int p;
+- *next = NULL;
+-
+- p = i + 1;
+- while (obj->dynamic[p].d_tag != DT_NULL) {
+- if (obj->dynamic[p].d_tag == tag) {
+- *next = &obj->dynamic[p];
+- return 0;
+- }
+- p++;
+- }
+-
+- p = 0;
+- while ((obj->dynamic[i].d_tag != DT_NULL) && (p < i)) {
+- if (obj->dynamic[p].d_tag == tag) {
+- *next = &obj->dynamic[p];
+- return 0;
+- }
+- p++;
+- }
+-
+- return EAGAIN;
+-}
+-
+-int eh_set_rela_plt(eh_obj_t *obj, int p, const char *sym, void *val)
+-{
+- ElfW(Rela) *rela = (ElfW(Rela) *) obj->dynamic[p].d_un.d_ptr;
+- ElfW(Dyn) *relasize;
+- unsigned int i;
+-
+- /* DT_PLTRELSZ contains PLT relocs size in bytes */
+- if (eh_find_next_dyn(obj, DT_PLTRELSZ, p, &relasize))
+- return EINVAL; /* b0rken elf :/ */
+-
+- for (i = 0; i < relasize->d_un.d_val / sizeof(ElfW(Rela)); i++) {
+- if (!obj->symtab[ELFW_R_SYM(rela[i].r_info)].st_name)
+- continue;
+-
+- if (!strcmp(&obj->strtab[obj->symtab[ELFW_R_SYM(rela[i].r_info)].st_name], sym))
+- *((void **) (rela[i].r_offset + obj->addr)) = val;
+- }
+-
+- return 0;
+-}
+-
+-int eh_set_rel_plt(eh_obj_t *obj, int p, const char *sym, void *val)
+-{
+- ElfW(Rel) *rel = (ElfW(Rel) *) obj->dynamic[p].d_un.d_ptr;
+- ElfW(Dyn) *relsize;
+- unsigned int i;
+-
+- if (eh_find_next_dyn(obj, DT_PLTRELSZ, p, &relsize))
+- return EINVAL; /* b0rken elf :/ */
+-
+- for (i = 0; i < relsize->d_un.d_val / sizeof(ElfW(Rel)); i++) {
+- if (!obj->symtab[ELFW_R_SYM(rel[i].r_info)].st_name)
+- continue;
+-
+- if (!strcmp(&obj->strtab[obj->symtab[ELFW_R_SYM(rel[i].r_info)].st_name], sym))
+- *((void **) (rel[i].r_offset + obj->addr)) = val;
+- }
+-
+- return 0;
+-}
+-
+-int eh_set_rel(eh_obj_t *obj, const char *sym, void *val)
+-{
+- /*
+- Elf spec states that object is allowed to have multiple
+- .rel.plt and .rela.plt tables, so we will support 'em - here.
+- */
+- ElfW(Dyn) *pltrel;
+- int ret, p = 0;
+-
+- while (obj->dynamic[p].d_tag != DT_NULL) {
+- /* DT_JMPREL contains .rel.plt or .rela.plt */
+- if (obj->dynamic[p].d_tag == DT_JMPREL) {
+- /* DT_PLTREL tells if it is Rela or Rel */
+- eh_find_next_dyn(obj, DT_PLTREL, p, &pltrel);
+-
+- if (pltrel->d_un.d_val == DT_RELA) {
+- if ((ret = eh_set_rela_plt(obj, p, sym, val)))
+- return ret;
+- } else if (pltrel->d_un.d_val == DT_REL) {
+- if ((ret = eh_set_rel_plt(obj, p, sym, val)))
+- return ret;
+- } else
+- return EINVAL;
+- }
+- p++;
+- }
+-
+- return 0;
+-}
+-
+-int eh_iterate_rela_plt(eh_obj_t *obj, int p, eh_iterate_rel_callback_func callback, void *arg)
+-{
+- ElfW(Rela) *rela = (ElfW(Rela) *) obj->dynamic[p].d_un.d_ptr;
+- ElfW(Dyn) *relasize;
+- eh_rel_t rel;
+- eh_sym_t sym;
+- unsigned int i, ret;
+-
+- rel.sym = &sym;
+- rel.rel = NULL;
+- rel.obj = obj;
+-
+- if (eh_find_next_dyn(obj, DT_PLTRELSZ, p, &relasize))
+- return EINVAL;
+-
+- for (i = 0; i < relasize->d_un.d_val / sizeof(ElfW(Rela)); i++) {
+- rel.rela = &rela[i];
+- sym.sym = &obj->symtab[ELFW_R_SYM(rel.rela->r_info)];
+- if (sym.sym->st_name)
+- sym.name = &obj->strtab[sym.sym->st_name];
+- else
+- sym.name = NULL;
+-
+- if ((ret = callback(&rel, arg)))
+- return ret;
+- }
+-
+- return 0;
+-}
+-
+-int eh_iterate_rel_plt(eh_obj_t *obj, int p, eh_iterate_rel_callback_func callback, void *arg)
+-{
+- ElfW(Rel) *relp = (ElfW(Rel) *) obj->dynamic[p].d_un.d_ptr;
+- ElfW(Dyn) *relsize;
+- eh_rel_t rel;
+- eh_sym_t sym;
+- unsigned int i, ret;
+-
+- rel.sym = &sym;
+- rel.rela = NULL;
+- rel.obj = obj;
+-
+- if (eh_find_next_dyn(obj, DT_PLTRELSZ, p, &relsize))
+- return EINVAL;
+-
+- for (i = 0; i < relsize->d_un.d_val / sizeof(ElfW(Rel)); i++) {
+- rel.rel = &relp[i];
+- sym.sym = &obj->symtab[ELFW_R_SYM(rel.rel->r_info)];
+- if (sym.sym->st_name)
+- sym.name = &obj->strtab[sym.sym->st_name];
+- else
+- sym.name = NULL;
+-
+- if ((ret = callback(&rel, arg)))
+- return ret;
+- }
+-
+- return 0;
+-}
+-
+-int eh_iterate_rel(eh_obj_t *obj, eh_iterate_rel_callback_func callback, void *arg)
+-{
+- ElfW(Dyn) *pltrel;
+- int ret, p = 0;
+-
+- while (obj->dynamic[p].d_tag != DT_NULL) {
+- if (obj->dynamic[p].d_tag == DT_JMPREL) {
+- eh_find_next_dyn(obj, DT_PLTREL, p, &pltrel);
+-
+- if (pltrel->d_un.d_val == DT_RELA) {
+- if ((ret = eh_iterate_rela_plt(obj, p, callback, arg)))
+- return ret;
+- } else if (pltrel->d_un.d_val == DT_REL) {
+- if ((ret = eh_iterate_rel_plt(obj, p, callback, arg)))
+- return ret;
+- } else
+- return EINVAL;
+- }
+- p++;
+- }
+-
+- return 0;
+-}
+-
+-int eh_destroy_obj(eh_obj_t *obj)
+-{
+- obj->phdr = NULL;
+-
+- return 0;
+-}
+-
+-/** \} */
+Index: simplescreenrecorder-salsa/glinject/plthook.h
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ simplescreenrecorder-salsa/glinject/plthook.h 2024-05-07 08:50:15.914773073 +0200
+@@ -0,0 +1,67 @@
++/* -*- indent-tabs-mode: nil -*-
++ *
++ * plthook.h -- the header file of plthook
++ *
++ * URL: https://github.com/kubo/plthook
++ *
++ * ------------------------------------------------------
++ *
++ * Copyright 2013-2014 Kubo Takehiro <kubo@jiubao.org>
++ *
++ * Redistribution and use in source and binary forms, with or without modification, are
++ * permitted provided that the following conditions are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright notice, this list of
++ * conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
++ * of conditions and the following disclaimer in the documentation and/or other materials
++ * provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
++ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
++ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * The views and conclusions contained in the software and documentation are those of the
++ * authors and should not be interpreted as representing official policies, either expressed
++ * or implied, of the authors.
++ *
++ */
++#ifndef PLTHOOK_H
++#define PLTHOOK_H 1
++
++#define PLTHOOK_SUCCESS 0
++#define PLTHOOK_FILE_NOT_FOUND 1
++#define PLTHOOK_INVALID_FILE_FORMAT 2
++#define PLTHOOK_FUNCTION_NOT_FOUND 3
++#define PLTHOOK_INVALID_ARGUMENT 4
++#define PLTHOOK_OUT_OF_MEMORY 5
++#define PLTHOOK_INTERNAL_ERROR 6
++#define PLTHOOK_NOT_IMPLEMENTED 7
++
++typedef struct plthook plthook_t;
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++int plthook_open(plthook_t **plthook_out, const char *filename);
++int plthook_open_by_handle(plthook_t **plthook_out, void *handle);
++int plthook_open_by_address(plthook_t **plthook_out, void *address);
++int plthook_open_by_linkmap(plthook_t **plthook_out, void *linkmap);
++int plthook_enum(plthook_t *plthook, unsigned int *pos, const char **name_out, void ***addr_out);
++int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, void **oldfunc);
++void plthook_close(plthook_t *plthook);
++const char *plthook_error(void);
++
++#ifdef __cplusplus
++} /* extern "C" */
++#endif
++
++#endif
+Index: simplescreenrecorder-salsa/glinject/plthook_elf.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ simplescreenrecorder-salsa/glinject/plthook_elf.c 2024-05-07 08:50:15.914773073 +0200
+@@ -0,0 +1,821 @@
++/* -*- indent-tabs-mode: nil -*-
++ *
++ * plthook_elf.c -- implementation of plthook for ELF format
++ *
++ * URL: https://github.com/kubo/plthook
++ *
++ * ------------------------------------------------------
++ *
++ * Copyright 2013-2019 Kubo Takehiro <kubo@jiubao.org>
++ *
++ * Redistribution and use in source and binary forms, with or without modification, are
++ * permitted provided that the following conditions are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright notice, this list of
++ * conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
++ * of conditions and the following disclaimer in the documentation and/or other materials
++ * provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED
++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
++ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
++ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ *
++ * The views and conclusions contained in the software and documentation are those of the
++ * authors and should not be interpreted as representing official policies, either expressed
++ * or implied, of the authors.
++ *
++ */
++#if defined(__sun) && defined(_XOPEN_SOURCE) && !defined(__EXTENSIONS__)
++#define __EXTENSIONS__
++#endif
++#if defined(__linux__) && !defined(_GNU_SOURCE)
++#define _GNU_SOURCE
++#endif
++#include <stdio.h>
++#include <stdarg.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++#include <limits.h>
++#include <sys/mman.h>
++#include <errno.h>
++#include <dlfcn.h>
++#ifdef __sun
++#include <sys/auxv.h>
++#include <procfs.h>
++#define ELF_TARGET_ALL
++#endif /* __sun */
++#ifdef __FreeBSD__
++#include <sys/types.h>
++#include <sys/user.h>
++#include <libutil.h>
++#endif
++#include <elf.h>
++#include <link.h>
++#include "plthook.h"
++
++#if defined __UCLIBC__ && !defined RTLD_NOLOAD
++#define RTLD_NOLOAD 0
++#endif
++
++#ifndef __GNUC__
++#define __attribute__(arg)
++#endif
++
++#if defined __FreeBSD__ && defined __i386__ && __ELF_WORD_SIZE == 64
++#error 32-bit application on 64-bit OS is not supported.
++#endif
++
++#if !defined(R_X86_64_JUMP_SLOT) && defined(R_X86_64_JMP_SLOT)
++#define R_X86_64_JUMP_SLOT R_X86_64_JMP_SLOT
++#endif
++
++#if defined __x86_64__ || defined __x86_64
++#define R_JUMP_SLOT R_X86_64_JUMP_SLOT
++#define R_GLOBAL_DATA R_X86_64_GLOB_DAT
++#elif defined __i386__ || defined __i386
++#define R_JUMP_SLOT R_386_JMP_SLOT
++#define R_GLOBAL_DATA R_386_GLOB_DAT
++#define USE_REL
++#elif defined __arm__ || defined __arm
++#define R_JUMP_SLOT R_ARM_JUMP_SLOT
++#define R_GLOBAL_DATA R_ARM_GLOB_DAT
++#define USE_REL
++#elif defined __aarch64__ || defined __aarch64 /* ARM64 */
++#define R_JUMP_SLOT R_AARCH64_JUMP_SLOT
++#define R_GLOBAL_DATA R_AARCH64_GLOB_DAT
++#elif defined __powerpc64__
++#define R_JUMP_SLOT R_PPC64_JMP_SLOT
++#define R_GLOBAL_DATA R_PPC64_GLOB_DAT
++#elif defined __powerpc__
++#define R_JUMP_SLOT R_PPC_JMP_SLOT
++#define R_GLOBAL_DATA R_PPC_GLOB_DAT
++#elif 0 /* disabled because not tested */ && (defined __sparcv9 || defined __sparc_v9__)
++#define R_JUMP_SLOT R_SPARC_JMP_SLOT
++#elif 0 /* disabled because not tested */ && (defined __sparc || defined __sparc__)
++#define R_JUMP_SLOT R_SPARC_JMP_SLOT
++#elif 0 /* disabled because not tested */ && (defined __ia64 || defined __ia64__)
++#define R_JUMP_SLOT R_IA64_IPLTMSB
++#else
++#error unsupported OS
++#endif
++
++#ifdef USE_REL
++#define Elf_Plt_Rel Elf_Rel
++#define PLT_DT_REL DT_REL
++#define PLT_DT_RELSZ DT_RELSZ
++#define PLT_DT_RELENT DT_RELENT
++#else
++#define Elf_Plt_Rel Elf_Rela
++#define PLT_DT_REL DT_RELA
++#define PLT_DT_RELSZ DT_RELASZ
++#define PLT_DT_RELENT DT_RELAENT
++#endif
++
++#if defined __LP64__
++#ifndef ELF_CLASS
++#define ELF_CLASS ELFCLASS64
++#endif
++#define SIZE_T_FMT "lu"
++#define ELF_WORD_FMT "u"
++#ifdef __ANDROID__
++#define ELF_XWORD_FMT "llu"
++#else
++#define ELF_XWORD_FMT "lu"
++#endif
++#define ELF_SXWORD_FMT "ld"
++#define Elf_Half Elf64_Half
++#define Elf_Xword Elf64_Xword
++#define Elf_Sxword Elf64_Sxword
++#define Elf_Ehdr Elf64_Ehdr
++#define Elf_Phdr Elf64_Phdr
++#define Elf_Sym Elf64_Sym
++#define Elf_Dyn Elf64_Dyn
++#define Elf_Rel Elf64_Rel
++#define Elf_Rela Elf64_Rela
++#ifndef ELF_R_SYM
++#define ELF_R_SYM ELF64_R_SYM
++#endif
++#ifndef ELF_R_TYPE
++#define ELF_R_TYPE ELF64_R_TYPE
++#endif
++#else /* __LP64__ */
++#ifndef ELF_CLASS
++#define ELF_CLASS ELFCLASS32
++#endif
++#define SIZE_T_FMT "u"
++#ifdef __sun
++#define ELF_WORD_FMT "lu"
++#define ELF_XWORD_FMT "lu"
++#define ELF_SXWORD_FMT "ld"
++#else
++#define ELF_WORD_FMT "u"
++#define ELF_XWORD_FMT "u"
++#define ELF_SXWORD_FMT "d"
++#endif
++#define Elf_Half Elf32_Half
++#define Elf_Xword Elf32_Word
++#define Elf_Sxword Elf32_Sword
++#define Elf_Ehdr Elf32_Ehdr
++#define Elf_Phdr Elf32_Phdr
++#define Elf_Sym Elf32_Sym
++#define Elf_Dyn Elf32_Dyn
++#define Elf_Rel Elf32_Rel
++#define Elf_Rela Elf32_Rela
++#ifndef ELF_R_SYM
++#define ELF_R_SYM ELF32_R_SYM
++#endif
++#ifndef ELF_R_TYPE
++#define ELF_R_TYPE ELF32_R_TYPE
++#endif
++#endif /* __LP64__ */
++
++struct plthook {
++ const Elf_Sym *dynsym;
++ const char *dynstr;
++ size_t dynstr_size;
++ const char *plt_addr_base;
++ const Elf_Plt_Rel *rela_plt;
++ size_t rela_plt_cnt;
++#ifdef R_GLOBAL_DATA
++ const Elf_Plt_Rel *rela_dyn;
++ size_t rela_dyn_cnt;
++#endif
++};
++
++static char errmsg[512];
++static size_t page_size;
++#define ALIGN_ADDR(addr) ((void*)((size_t)(addr) & ~(page_size - 1)))
++
++static int plthook_open_executable(plthook_t **plthook_out);
++static int plthook_open_shared_library(plthook_t **plthook_out, const char *filename);
++static const Elf_Dyn *find_dyn_by_tag(const Elf_Dyn *dyn, Elf_Sxword tag);
++static int plthook_open_real(plthook_t **plthook_out, struct link_map *lmap);
++#if defined __FreeBSD__ || defined __sun
++static int check_elf_header(const Elf_Ehdr *ehdr);
++#endif
++static void set_errmsg(const char *fmt, ...) __attribute__((__format__ (__printf__, 1, 2)));
++
++#if defined __ANDROID__ || defined __UCLIBC__
++struct dl_iterate_data {
++ char* addr;
++ struct link_map lmap;
++};
++
++static int dl_iterate_cb(struct dl_phdr_info *info, size_t size, void *cb_data)
++{
++ struct dl_iterate_data *data = (struct dl_iterate_data*)cb_data;
++ Elf_Half idx = 0;
++
++ for (idx = 0; idx < info->dlpi_phnum; ++idx) {
++ const Elf_Phdr *phdr = &info->dlpi_phdr[idx];
++ char* base = (char*)info->dlpi_addr + phdr->p_vaddr;
++ if (base <= data->addr && data->addr < base + phdr->p_memsz) {
++ break;
++ }
++ }
++ if (idx == info->dlpi_phnum) {
++ return 0;
++ }
++ for (idx = 0; idx < info->dlpi_phnum; ++idx) {
++ const Elf_Phdr *phdr = &info->dlpi_phdr[idx];
++ if (phdr->p_type == PT_DYNAMIC) {
++ data->lmap.l_addr = info->dlpi_addr;
++ data->lmap.l_ld = (Elf_Dyn*)(info->dlpi_addr + phdr->p_vaddr);
++ return 1;
++ }
++ }
++ return 0;
++}
++#endif
++
++int plthook_open(plthook_t **plthook_out, const char *filename)
++{
++ *plthook_out = NULL;
++ if (filename == NULL) {
++ return plthook_open_executable(plthook_out);
++ } else {
++ return plthook_open_shared_library(plthook_out, filename);
++ }
++}
++
++int plthook_open_by_handle(plthook_t **plthook_out, void *hndl)
++{
++#if defined __ANDROID__ || defined __UCLIBC__
++ const static char *symbols[] = {
++ "__INIT_ARRAY__",
++ "_end",
++ "_start"
++ };
++ size_t i;
++
++ if (hndl == NULL) {
++ set_errmsg("NULL handle");
++ return PLTHOOK_FILE_NOT_FOUND;
++ }
++ for (i = 0; i < sizeof(symbols)/sizeof(symbols[0]); i++) {
++ char *addr = dlsym(hndl, symbols[i]);
++ if (addr != NULL) {
++ return plthook_open_by_address(plthook_out, addr - 1);
++ }
++ }
++ set_errmsg("Could not find an address in the specified handle.");
++ return PLTHOOK_INTERNAL_ERROR;
++#else
++ struct link_map *lmap = NULL;
++
++ if (hndl == NULL) {
++ set_errmsg("NULL handle");
++ return PLTHOOK_FILE_NOT_FOUND;
++ }
++ if (dlinfo(hndl, RTLD_DI_LINKMAP, &lmap) != 0) {
++ set_errmsg("dlinfo error");
++ return PLTHOOK_FILE_NOT_FOUND;
++ }
++ return plthook_open_real(plthook_out, lmap);
++#endif
++}
++
++int plthook_open_by_address(plthook_t **plthook_out, void *address)
++{
++#if defined __FreeBSD__
++ return PLTHOOK_NOT_IMPLEMENTED;
++#elif defined __ANDROID__ || defined __UCLIBC__
++ struct dl_iterate_data data = {0,};
++ data.addr = address;
++ dl_iterate_phdr(dl_iterate_cb, &data);
++ if (data.lmap.l_ld == NULL) {
++ set_errmsg("Could not find memory region containing address %p", address);
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ return plthook_open_real(plthook_out, &data.lmap);
++#else
++ Dl_info info;
++ struct link_map *lmap = NULL;
++
++ *plthook_out = NULL;
++ if (dladdr1(address, &info, (void**)&lmap, RTLD_DL_LINKMAP) == 0) {
++ set_errmsg("dladdr error");
++ return PLTHOOK_FILE_NOT_FOUND;
++ }
++ return plthook_open_real(plthook_out, lmap);
++#endif
++}
++
++int plthook_open_by_linkmap(plthook_t **plthook_out, void *linkmap)
++{
++ return plthook_open_real(plthook_out, (struct link_map*)linkmap);
++}
++
++static int plthook_open_executable(plthook_t **plthook_out)
++{
++#if defined __ANDROID__ || defined __UCLIBC__
++ return plthook_open_shared_library(plthook_out, NULL);
++#elif defined __linux__
++ return plthook_open_real(plthook_out, _r_debug.r_map);
++#elif defined __sun
++ const char *auxv_file = "/proc/self/auxv";
++#define NUM_AUXV_CNT 10
++ FILE *fp = fopen(auxv_file, "r");
++ auxv_t auxv;
++ struct r_debug *r_debug = NULL;
++
++ if (fp == NULL) {
++ set_errmsg("Could not open %s: %s", auxv_file,
++ strerror(errno));
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ while (fread(&auxv, sizeof(auxv_t), 1, fp) == 1) {
++ if (auxv.a_type == AT_SUN_LDDATA) {
++ r_debug = (struct r_debug *)auxv.a_un.a_ptr;
++ break;
++ }
++ }
++ fclose(fp);
++ if (r_debug == NULL) {
++ set_errmsg("Could not find r_debug");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ return plthook_open_real(plthook_out, r_debug->r_map);
++#elif defined __FreeBSD__
++ return plthook_open_shared_library(plthook_out, NULL);
++#else
++ set_errmsg("Opening the main program is not supported on this platform.");
++ return PLTHOOK_NOT_IMPLEMENTED;
++#endif
++}
++
++static int plthook_open_shared_library(plthook_t **plthook_out, const char *filename)
++{
++ void *hndl = dlopen(filename, RTLD_LAZY | RTLD_NOLOAD);
++#if defined __ANDROID__ || defined __UCLIBC__
++ int rv;
++#else
++ struct link_map *lmap = NULL;
++#endif
++
++ if (hndl == NULL) {
++ set_errmsg("dlopen error: %s", dlerror());
++ return PLTHOOK_FILE_NOT_FOUND;
++ }
++#if defined __ANDROID__ || defined __UCLIBC__
++ rv = plthook_open_by_handle(plthook_out, hndl);
++ dlclose(hndl);
++ return rv;
++#else
++ if (dlinfo(hndl, RTLD_DI_LINKMAP, &lmap) != 0) {
++ set_errmsg("dlinfo error");
++ dlclose(hndl);
++ return PLTHOOK_FILE_NOT_FOUND;
++ }
++ dlclose(hndl);
++ return plthook_open_real(plthook_out, lmap);
++#endif
++}
++
++static const Elf_Dyn *find_dyn_by_tag(const Elf_Dyn *dyn, Elf_Sxword tag)
++{
++ while (dyn->d_tag != DT_NULL) {
++ if (dyn->d_tag == tag) {
++ return dyn;
++ }
++ dyn++;
++ }
++ return NULL;
++}
++
++#ifdef __linux__
++static int get_memory_permission(void *address)
++{
++ unsigned long addr = (unsigned long)address;
++ FILE *fp;
++ char buf[PATH_MAX];
++ char perms[5];
++ int bol = 1;
++
++ fp = fopen("/proc/self/maps", "r");
++ if (fp == NULL) {
++ set_errmsg("failed to open /proc/self/maps");
++ return 0;
++ }
++ while (fgets(buf, PATH_MAX, fp) != NULL) {
++ unsigned long start, end;
++ int eol = (strchr(buf, '\n') != NULL);
++ if (bol) {
++ /* The fgets reads from the beginning of a line. */
++ if (!eol) {
++ /* The next fgets reads from the middle of the same line. */
++ bol = 0;
++ }
++ } else {
++ /* The fgets reads from the middle of a line. */
++ if (eol) {
++ /* The next fgets reads from the beginnig of a line. */
++ bol = 1;
++ }
++ continue;
++ }
++
++ if (sscanf(buf, "%lx-%lx %4s", &start, &end, perms) != 3) {
++ continue;
++ }
++ if (start <= addr && addr < end) {
++ int prot = 0;
++ if (perms[0] == 'r') {
++ prot |= PROT_READ;
++ } else if (perms[0] != '-') {
++ goto unknown_perms;
++ }
++ if (perms[1] == 'w') {
++ prot |= PROT_WRITE;
++ } else if (perms[1] != '-') {
++ goto unknown_perms;
++ }
++ if (perms[2] == 'x') {
++ prot |= PROT_EXEC;
++ } else if (perms[2] != '-') {
++ goto unknown_perms;
++ }
++ if (perms[3] != 'p') {
++ goto unknown_perms;
++ }
++ if (perms[4] != '\0') {
++ perms[4] = '\0';
++ goto unknown_perms;
++ }
++ fclose(fp);
++ return prot;
++ }
++ }
++ fclose(fp);
++ set_errmsg("Could not find memory region containing %p", (void*)addr);
++ return 0;
++unknown_perms:
++ fclose(fp);
++ set_errmsg("Unexcepted memory permission %s at %p", perms, (void*)addr);
++ return 0;
++}
++#elif defined __FreeBSD__
++static int get_memory_permission(void *address)
++{
++ uint64_t addr = (uint64_t)address;
++ struct kinfo_vmentry *top;
++ int i, cnt;
++
++ top = kinfo_getvmmap(getpid(), &cnt);
++ if (top == NULL) {
++ set_errmsg("failed to call kinfo_getvmmap()\n");
++ return 0;
++ }
++ for (i = 0; i < cnt; i++) {
++ struct kinfo_vmentry *kve = top + i;
++
++ if (kve->kve_start <= addr && addr < kve->kve_end) {
++ int prot = 0;
++ if (kve->kve_protection & KVME_PROT_READ) {
++ prot |= PROT_READ;
++ }
++ if (kve->kve_protection & KVME_PROT_WRITE) {
++ prot |= PROT_WRITE;
++ }
++ if (kve->kve_protection & KVME_PROT_EXEC) {
++ prot |= PROT_EXEC;
++ }
++ if (prot == 0) {
++ set_errmsg("Unknown kve_protection 0x%x at %p", kve->kve_protection, (void*)addr);
++ }
++ free(top);
++ return prot;
++ }
++ }
++ free(top);
++ set_errmsg("Could not find memory region containing %p", (void*)addr);
++ return 0;
++}
++#elif defined(__sun)
++#define NUM_MAPS 20
++static int get_memory_permission(void *address)
++{
++ unsigned long addr = (unsigned long)address;
++ FILE *fp;
++ prmap_t maps[NUM_MAPS];
++ size_t num;
++
++ fp = fopen("/proc/self/map", "r");
++ if (fp == NULL) {
++ set_errmsg("failed to open /proc/self/map");
++ return 0;
++ }
++ while ((num = fread(maps, sizeof(prmap_t), NUM_MAPS, fp)) > 0) {
++ size_t i;
++ for (i = 0; i < num; i++) {
++ prmap_t *map = &maps[i];
++
++ if (map->pr_vaddr <= addr && addr < map->pr_vaddr + map->pr_size) {
++ int prot = 0;
++ if (map->pr_mflags & MA_READ) {
++ prot |= PROT_READ;
++ }
++ if (map->pr_mflags & MA_WRITE) {
++ prot |= PROT_WRITE;
++ }
++ if (map->pr_mflags & MA_EXEC) {
++ prot |= PROT_EXEC;
++ }
++ if (prot == 0) {
++ set_errmsg("Unknown pr_mflags 0x%x at %p", map->pr_mflags, (void*)addr);
++ }
++ fclose(fp);
++ return prot;
++ }
++ }
++ }
++ fclose(fp);
++ set_errmsg("Could not find memory region containing %p", (void*)addr);
++ return 0;
++}
++#else
++#error Unsupported platform
++#endif
++
++static int plthook_open_real(plthook_t **plthook_out, struct link_map *lmap)
++{
++ plthook_t plthook = {NULL,};
++ const Elf_Dyn *dyn;
++ const char *dyn_addr_base = NULL;
++
++ if (page_size == 0) {
++ page_size = sysconf(_SC_PAGESIZE);
++ }
++
++#if defined __linux__
++ plthook.plt_addr_base = (char*)lmap->l_addr;
++#if defined __ANDROID__ || defined __UCLIBC__
++ dyn_addr_base = (const char*)lmap->l_addr;
++#endif
++#elif defined __FreeBSD__ || defined __sun
++ const Elf_Ehdr *ehdr = (const Elf_Ehdr*)lmap->l_addr;
++ int rv_ = check_elf_header(ehdr);
++ if (rv_ != 0) {
++ return rv_;
++ }
++ if (ehdr->e_type == ET_DYN) {
++ dyn_addr_base = (const char*)lmap->l_addr;
++ plthook.plt_addr_base = (const char*)lmap->l_addr;
++ }
++#else
++#error unsupported OS
++#endif
++
++ /* get .dynsym section */
++ dyn = find_dyn_by_tag(lmap->l_ld, DT_SYMTAB);
++ if (dyn == NULL) {
++ set_errmsg("failed to find DT_SYMTAB");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ plthook.dynsym = (const Elf_Sym*)(dyn_addr_base + dyn->d_un.d_ptr);
++
++ /* Check sizeof(Elf_Sym) */
++ dyn = find_dyn_by_tag(lmap->l_ld, DT_SYMENT);
++ if (dyn == NULL) {
++ set_errmsg("failed to find DT_SYMTAB");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ if (dyn->d_un.d_val != sizeof(Elf_Sym)) {
++ set_errmsg("DT_SYMENT size %" ELF_XWORD_FMT " != %" SIZE_T_FMT, dyn->d_un.d_val, sizeof(Elf_Sym));
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++
++ /* get .dynstr section */
++ dyn = find_dyn_by_tag(lmap->l_ld, DT_STRTAB);
++ if (dyn == NULL) {
++ set_errmsg("failed to find DT_STRTAB");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ plthook.dynstr = dyn_addr_base + dyn->d_un.d_ptr;
++
++ /* get .dynstr size */
++ dyn = find_dyn_by_tag(lmap->l_ld, DT_STRSZ);
++ if (dyn == NULL) {
++ set_errmsg("failed to find DT_STRSZ");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ plthook.dynstr_size = dyn->d_un.d_val;
++
++ /* get .rela.plt or .rel.plt section */
++ dyn = find_dyn_by_tag(lmap->l_ld, DT_JMPREL);
++ if (dyn != NULL) {
++ plthook.rela_plt = (const Elf_Plt_Rel *)(dyn_addr_base + dyn->d_un.d_ptr);
++ dyn = find_dyn_by_tag(lmap->l_ld, DT_PLTRELSZ);
++ if (dyn == NULL) {
++ set_errmsg("failed to find DT_PLTRELSZ");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ plthook.rela_plt_cnt = dyn->d_un.d_val / sizeof(Elf_Plt_Rel);
++ }
++#ifdef R_GLOBAL_DATA
++ /* get .rela.dyn or .rel.dyn section */
++ dyn = find_dyn_by_tag(lmap->l_ld, PLT_DT_REL);
++ if (dyn != NULL) {
++ size_t total_size, elem_size;
++
++ plthook.rela_dyn = (const Elf_Plt_Rel *)(dyn_addr_base + dyn->d_un.d_ptr);
++ dyn = find_dyn_by_tag(lmap->l_ld, PLT_DT_RELSZ);
++ if (dyn == NULL) {
++ set_errmsg("failed to find PLT_DT_RELSZ");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ total_size = dyn->d_un.d_ptr;
++
++ dyn = find_dyn_by_tag(lmap->l_ld, PLT_DT_RELENT);
++ if (dyn == NULL) {
++ set_errmsg("failed to find PLT_DT_RELENT");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ elem_size = dyn->d_un.d_ptr;
++ plthook.rela_dyn_cnt = total_size / elem_size;
++ }
++#endif
++
++#ifdef R_GLOBAL_DATA
++ if (plthook.rela_plt == NULL && plthook.rela_dyn == NULL) {
++ set_errmsg("failed to find either of DT_JMPREL and DT_REL");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++#else
++ if (plthook.rela_plt == NULL) {
++ set_errmsg("failed to find DT_JMPREL");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++#endif
++
++ *plthook_out = malloc(sizeof(plthook_t));
++ if (*plthook_out == NULL) {
++ set_errmsg("failed to allocate memory: %" SIZE_T_FMT " bytes", sizeof(plthook_t));
++ return PLTHOOK_OUT_OF_MEMORY;
++ }
++ **plthook_out = plthook;
++ return 0;
++}
++
++#if defined __FreeBSD__ || defined __sun
++static int check_elf_header(const Elf_Ehdr *ehdr)
++{
++ static const unsigned short s = 1;
++ /* Check endianness at runtime. */
++ unsigned char elfdata = (*(const char*)&s) ? ELFDATA2LSB : ELFDATA2MSB;
++
++ if (ehdr == NULL) {
++ set_errmsg("invalid elf header address: NULL");
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++
++ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
++ set_errmsg("invalid file signature: 0x%02x,0x%02x,0x%02x,0x%02x",
++ ehdr->e_ident[0], ehdr->e_ident[1], ehdr->e_ident[2], ehdr->e_ident[3]);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
++ set_errmsg("invalid elf class: 0x%02x", ehdr->e_ident[EI_CLASS]);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ if (ehdr->e_ident[EI_DATA] != elfdata) {
++ set_errmsg("invalid elf data: 0x%02x", ehdr->e_ident[EI_DATA]);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
++ set_errmsg("invalid elf version: 0x%02x", ehdr->e_ident[EI_VERSION]);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
++ set_errmsg("invalid file type: 0x%04x", ehdr->e_type);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ if (ehdr->e_version != EV_CURRENT) {
++ set_errmsg("invalid object file version: %" ELF_WORD_FMT, ehdr->e_version);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ if (ehdr->e_ehsize != sizeof(Elf_Ehdr)) {
++ set_errmsg("invalid elf header size: %u", ehdr->e_ehsize);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ if (ehdr->e_phentsize != sizeof(Elf_Phdr)) {
++ set_errmsg("invalid program header table entry size: %u", ehdr->e_phentsize);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ return 0;
++}
++#endif
++
++static int check_rel(const plthook_t *plthook, const Elf_Plt_Rel *plt, Elf_Xword r_type, const char **name_out, void ***addr_out)
++{
++ if (ELF_R_TYPE(plt->r_info) == r_type) {
++ size_t idx = ELF_R_SYM(plt->r_info);
++ idx = plthook->dynsym[idx].st_name;
++ if (idx + 1 > plthook->dynstr_size) {
++ set_errmsg("too big section header string table index: %" SIZE_T_FMT, idx);
++ return PLTHOOK_INVALID_FILE_FORMAT;
++ }
++ *name_out = plthook->dynstr + idx;
++ *addr_out = (void**)(plthook->plt_addr_base + plt->r_offset);
++ return 0;
++ }
++ return -1;
++}
++
++int plthook_enum(plthook_t *plthook, unsigned int *pos, const char **name_out, void ***addr_out)
++{
++ while (*pos < plthook->rela_plt_cnt) {
++ const Elf_Plt_Rel *plt = plthook->rela_plt + *pos;
++ int rv = check_rel(plthook, plt, R_JUMP_SLOT, name_out, addr_out);
++ (*pos)++;
++ if (rv >= 0) {
++ return rv;
++ }
++ }
++#ifdef R_GLOBAL_DATA
++ while (*pos < plthook->rela_plt_cnt + plthook->rela_dyn_cnt) {
++ const Elf_Plt_Rel *plt = plthook->rela_dyn + (*pos - plthook->rela_plt_cnt);
++ int rv = check_rel(plthook, plt, R_GLOBAL_DATA, name_out, addr_out);
++ (*pos)++;
++ if (rv >= 0) {
++ return rv;
++ }
++ }
++#endif
++ *name_out = NULL;
++ *addr_out = NULL;
++ return EOF;
++}
++
++int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, void **oldfunc)
++{
++ size_t funcnamelen = strlen(funcname);
++ unsigned int pos = 0;
++ const char *name;
++ void **addr;
++ int rv;
++
++ if (plthook == NULL) {
++ set_errmsg("invalid argument: The first argument is null.");
++ return PLTHOOK_INVALID_ARGUMENT;
++ }
++ while ((rv = plthook_enum(plthook, &pos, &name, &addr)) == 0) {
++ if (strncmp(name, funcname, funcnamelen) == 0) {
++ if (name[funcnamelen] == '\0' || name[funcnamelen] == '@') {
++ int prot = get_memory_permission(addr);
++ if (prot == 0) {
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ if (!(prot & PROT_WRITE)) {
++ if (mprotect(ALIGN_ADDR(addr), page_size, PROT_READ | PROT_WRITE) != 0) {
++ set_errmsg("Could not change the process memory permission at %p: %s",
++ ALIGN_ADDR(addr), strerror(errno));
++ return PLTHOOK_INTERNAL_ERROR;
++ }
++ }
++ if (oldfunc) {
++ *oldfunc = *addr;
++ }
++ *addr = funcaddr;
++ if (!(prot & PROT_WRITE)) {
++ mprotect(ALIGN_ADDR(addr), page_size, prot);
++ }
++ return 0;
++ }
++ }
++ }
++ if (rv == EOF) {
++ set_errmsg("no such function: %s", funcname);
++ rv = PLTHOOK_FUNCTION_NOT_FOUND;
++ }
++ return rv;
++}
++
++void plthook_close(plthook_t *plthook)
++{
++ if (plthook != NULL) {
++ free(plthook);
++ }
++}
++
++const char *plthook_error(void)
++{
++ return errmsg;
++}
++
++static void set_errmsg(const char *fmt, ...)
++{
++ va_list ap;
++ va_start(ap, fmt);
++ vsnprintf(errmsg, sizeof(errmsg) - 1, fmt, ap);
++ va_end(ap);
++}
+Index: simplescreenrecorder-salsa/src/GUI/PageWelcome.cpp
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/GUI/PageWelcome.cpp 2024-05-07 08:50:15.918773109 +0200
++++ simplescreenrecorder-salsa/src/GUI/PageWelcome.cpp 2024-05-07 08:50:15.914773073 +0200
+@@ -121,8 +121,8 @@
+ html_about.replace("%SOURCECODE%", tr("The source code of this program can be found at:"));
+ html_about.replace("%USES%", tr("This program uses:"));
+ html_about.replace("%USES_QT%", tr("%1 for the graphical user interface").arg("<a href=\"https://qt-project.org/\">Qt</a>"));
+- html_about.replace("%USES_LIBAV_FFMPEG%", tr("%1 or %2 (depending on your distribution) for video/audio encoding").arg("<a href=\"http://libav.org/\">libav</a>").arg("<a href=\"http://ffmpeg.org/\">ffmpeg</a>"));
+- html_about.replace("%USES_ELFHACKS%", tr("%1 for hooking system functions for OpenGL recording").arg("<a href=\"https://github.com/nullkey/elfhacks\">elfhacks</a>"));
++ html_about.replace("%USES_FFMPEG%", tr("%1 for video/audio encoding").arg("<a href=\"https://ffmpeg.org/\">FFmpeg</a>"));
++ html_about.replace("%USES_PLTHOOK%", tr("%1 for hooking system functions for OpenGL recording").arg("<a href=\"https://github.com/kubo/plthook\">PLTHook</a>"));
+ html_about.replace("%VERSION%", SSR_VERSION);
+ html_about.replace("%VERSIONINFO%", GetVersionInfo().replace("\n", "<br>\n"));
+
+Index: simplescreenrecorder-salsa/glinject/elfhacks.h
+===================================================================
+--- simplescreenrecorder-salsa.orig/glinject/elfhacks.h 2024-05-07 08:50:11.850735880 +0200
++++ /dev/null 1970-01-01 00:00:00.000000000 +0000
+@@ -1,208 +0,0 @@
+-/**
+- * \file src/elfhacks.h
+- * \brief elfhacks application interface
+- * \author Pyry Haulos <pyry.haulos@gmail.com>
+- * \date 2007-2008
+- */
+-
+-/* elfhacks.h -- Various ELF run-time hacks
+- version 0.4.1, March 9th, 2008
+-
+- Copyright (C) 2007-2008 Pyry Haulos
+-
+- This software is provided 'as-is', without any express or implied
+- warranty. In no event will the authors be held liable for any damages
+- arising from the use of this software.
+-
+- Permission is granted to anyone to use this software for any purpose,
+- including commercial applications, and to alter it and redistribute it
+- freely, subject to the following restrictions:
+-
+- 1. The origin of this software must not be misrepresented; you must not
+- claim that you wrote the original software. If you use this software
+- in a product, an acknowledgment in the product documentation would be
+- appreciated but is not required.
+- 2. Altered source versions must be plainly marked as such, and must not be
+- misrepresented as being the original software.
+- 3. This notice may not be removed or altered from any source distribution.
+-
+- Pyry Haulos <pyry.haulos@gmail.com>
+-*/
+-
+-#include <elf.h>
+-#include <link.h>
+-
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+-
+-#define __PUBLIC __attribute__ ((visibility ("default")))
+-
+-#ifdef __x86_64__
+-# define __elf64
+-#endif
+-#ifdef __i386__
+-# define __elf32
+-#endif
+-
+-#if defined(__elf64)
+-# define ELFW_R_SYM ELF64_R_SYM
+-# define ElfW_Sword Elf64_Sxword
+-# ifndef ElfW
+-# define ElfW(v) Elf64_##v
+-# endif
+-# ifndef __ELF_NATIVE_CLASS
+-# define __ELF_NATIVE_CLASS 64
+-# endif
+-#elif defined(__elf32)
+-# define ELFW_R_SYM ELF32_R_SYM
+-# define ElfW_Sword Elf32_Sword
+-# ifndef ElfW
+-# define ElfW(v) Elf32_##v
+-# endif
+-# ifndef __ELF_NATIVE_CLASS
+-# define __ELF_NATIVE_CLASS 32
+-# endif
+-#else
+-# error neither __elf32 nor __elf64 is defined
+-#endif
+-
+-/**
+- * \defgroup elfhacks elfhacks
+- * Elfhacks is a collection of functions that aim for retvieving
+- * or modifying progam's dynamic linking information at run-time.
+- * \{
+- */
+-
+-/**
+- * \brief elfhacks program object
+- */
+-typedef struct {
+- /** file name */
+- const char *name;
+- /** base address in memory */
+- ElfW(Addr) addr;
+- /** program headers */
+- const ElfW(Phdr) *phdr;
+- /** number of program headers */
+- ElfW(Half) phnum;
+- /** .dynamic */
+- ElfW(Dyn) *dynamic;
+- /** .symtab */
+- ElfW(Sym) *symtab;
+- /** .strtab */
+- const char *strtab;
+- /** symbol hash table (DT_HASH) */
+- ElfW(Word) *hash;
+- /** symbol hash table (DT_GNU_HASH) */
+- Elf32_Word *gnu_hash;
+-} eh_obj_t;
+-
+-/**
+- * \brief elfhacks symbol
+- */
+-typedef struct {
+- /** symbol name */
+- const char *name;
+- /** corresponding ElfW(Sym) */
+- ElfW(Sym) *sym;
+- /** elfhacks object this symbol is associated to */
+- eh_obj_t *obj;
+-} eh_sym_t;
+-
+-/**
+- * \brief elfhacks relocation
+- */
+-typedef struct {
+- /** symbol this relocation is associated to */
+- eh_sym_t *sym;
+- /** corresponding ElfW(Rel) (NULL if this is Rela) */
+- ElfW(Rel) *rel;
+- /** corresponding ElfW(Rela) (NULL if this is Rel) */
+- ElfW(Rela) *rela;
+- /** elfhacks program object */
+- eh_obj_t *obj;
+-} eh_rel_t;
+-
+-/**
+- * \brief Iterate objects callback
+- */
+-typedef int (*eh_iterate_obj_callback_func)(eh_obj_t *obj, void *arg);
+-/**
+- * \brief Iterate symbols callback
+- */
+-typedef int (*eh_iterate_sym_callback_func)(eh_sym_t *sym, void *arg);
+-/**
+- * \brief Iterate relocations callback
+- */
+-typedef int (*eh_iterate_rel_callback_func)(eh_rel_t *rel, void *arg);
+-
+-/**
+- * \brief Initializes eh_obj_t for given soname
+- *
+- * Matching is done using fnmatch() so wildcards and other standard
+- * filename metacharacters and expressions work.
+- *
+- * If soname is NULL, this function returns the main program object.
+- * \param obj elfhacks object
+- * \param soname object's soname (see /proc/pid/maps) or NULL for main
+- * \return 0 on success otherwise a positive error code
+-*/
+-__PUBLIC int eh_find_obj(eh_obj_t *obj, const char *soname);
+-
+-/**
+- * \brief Walk through list of objects
+- * \param callback callback function
+- * \param arg argument passed to callback function
+- * \return 0 on success otherwise an error code
+- */
+-__PUBLIC int eh_iterate_obj(eh_iterate_obj_callback_func callback, void *arg);
+-
+-/**
+- * \brief Finds symbol in object's .dynsym and retrvieves its value.
+- * \param obj elfhacks program object
+- * \param name symbol to find
+- * \param to returned value
+- * \return 0 on success otherwise a positive error code
+-*/
+-__PUBLIC int eh_find_sym(eh_obj_t *obj, const char *name, void **to);
+-
+-/**
+- * \brief Walk through list of symbols in object
+- * \param obj elfhacks program object
+- * \param callback callback function
+- * \param arg argument passed to callback function
+- * \return 0 on success otherwise an error code
+- */
+-__PUBLIC int eh_iterate_sym(eh_obj_t *obj, eh_iterate_sym_callback_func callback, void *arg);
+-
+-/**
+- * \brief Iterates through object's .rel.plt and .rela.plt and sets every
+- * occurrence of some symbol to the specified value.
+- * \param obj elfhacks program object
+- * \param sym symbol to replace
+- * \param val new value
+- * \return 0 on success otherwise a positive error code
+-*/
+-__PUBLIC int eh_set_rel(eh_obj_t *obj, const char *sym, void *val);
+-
+-/**
+- * \brief Walk through object's .rel.plt and .rela.plt
+- * \param obj elfhacks program object
+- * \param callback callback function
+- * \param arg argument passed to callback function
+- */
+-__PUBLIC int eh_iterate_rel(eh_obj_t *obj, eh_iterate_rel_callback_func callback, void *arg);
+-
+-/**
+- * \brief Destroy eh_obj_t object.
+- * \param obj elfhacks program object
+- * \return 0 on success otherwise a positive error code
+-*/
+-__PUBLIC int eh_destroy_obj(eh_obj_t *obj);
+-
+-/** \} */
+-
+-#ifdef __cplusplus
+-}
+-#endif
diff --git a/source/xap/ssr/0020-ffmpeg-7.patch b/source/xap/ssr/0020-ffmpeg-7.patch
new file mode 100644
index 000000000..88d6c5ab3
--- /dev/null
+++ b/source/xap/ssr/0020-ffmpeg-7.patch
@@ -0,0 +1,54 @@
+Description: Fixes for ffmpeg 7.0
+ The FF_API_OLD_CHANNEL_LAYOUT api was removed in ffmpeg-7.0 so
+ src/AV/Output/AudioEncoder.cpp and src/AV/Output/Synchronizer.cpp fail to
+ compile. Fix this while remaining compatible with older ffmpeg versions.
+Forwarded: https://github.com/MaartenBaert/ssr/pull/1031
+Origin: https://github.com/MaartenBaert/ssr/pull/1031
+Last-Updated: 2024-05-08
+---
+Index: simplescreenrecorder-salsa/src/AV/Output/AudioEncoder.cpp
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/AudioEncoder.cpp 2024-05-08 08:58:55.973284904 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/AudioEncoder.cpp 2024-05-08 08:58:55.969284862 +0200
+@@ -69,7 +69,11 @@
+ }
+
+ unsigned int AudioEncoder::GetChannels() {
++#if LIBAVCODEC_VERSION_MAJOR < 61
+ return GetCodecContext()->channels;
++#else
++ return GetCodecContext()->ch_layout.nb_channels;
++#endif
+ }
+
+ unsigned int AudioEncoder::GetSampleRate() {
+@@ -106,8 +110,13 @@
+ }
+
+ codec_context->bit_rate = bit_rate;
++#if LIBAVCODEC_VERSION_MAJOR < 61
+ codec_context->channels = channels;
+ codec_context->channel_layout = (channels == 1)? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
++#else
++ codec_context->ch_layout.nb_channels = channels;
++ codec_context->ch_layout.u.mask = (channels == 1)? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
++#endif
+ codec_context->sample_rate = sample_rate;
+ codec_context->time_base.num = 1;
+ codec_context->time_base.den = sample_rate;
+Index: simplescreenrecorder-salsa/src/AV/Output/Synchronizer.cpp
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/Synchronizer.cpp 2024-05-08 08:58:55.973284904 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/Synchronizer.cpp 2024-05-08 08:58:55.969284862 +0200
+@@ -180,7 +180,11 @@
+ frame->GetFrame()->nb_samples = samples;
+ #endif
+ #if SSR_USE_AVFRAME_CHANNELS
++#if LIBAVCODEC_VERSION_MAJOR < 61
+ frame->GetFrame()->channels = channels;
++#else
++ frame->GetFrame()->ch_layout.nb_channels = channels;
++#endif
+ #endif
+ #if SSR_USE_AVFRAME_SAMPLE_RATE
+ frame->GetFrame()->sample_rate = sample_rate;
diff --git a/source/xap/ssr/0003-Fix-build-with-ffmpeg-5.0.patch b/source/xap/ssr/1000-Fix-build-with-ffmpeg-5.0.patch
index 1b40715d6..af7a6e6cc 100644
--- a/source/xap/ssr/0003-Fix-build-with-ffmpeg-5.0.patch
+++ b/source/xap/ssr/1000-Fix-build-with-ffmpeg-5.0.patch
@@ -4,6 +4,7 @@ Subject: Fix build with ffmpeg 5.0
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
+Forwarded: https://github.com/MaartenBaert/ssr/pull/934
Adapt to ffmpeg 5.0 requiring more const-ness for AVCodec.
@@ -19,11 +20,11 @@ Signed-off-by: Bernhard Rosenkränzer <bero@lindev.ch>
src/AV/Output/VideoEncoder.h | 4 ++--
8 files changed, 22 insertions(+), 22 deletions(-)
-diff --git a/src/AV/Output/AudioEncoder.cpp b/src/AV/Output/AudioEncoder.cpp
-index 34d015c..cefc2e0 100644
---- a/src/AV/Output/AudioEncoder.cpp
-+++ b/src/AV/Output/AudioEncoder.cpp
-@@ -34,7 +34,7 @@ const std::vector<AudioEncoder::SampleFormatData> AudioEncoder::SUPPORTED_SAMPLE
+Index: simplescreenrecorder-salsa/src/AV/Output/AudioEncoder.cpp
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/AudioEncoder.cpp 2024-05-08 08:58:34.613059892 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/AudioEncoder.cpp 2024-05-08 08:58:34.605059807 +0200
+@@ -34,7 +34,7 @@
const unsigned int AudioEncoder::DEFAULT_FRAME_SAMPLES = 1024;
@@ -32,7 +33,7 @@ index 34d015c..cefc2e0 100644
: BaseEncoder(muxer, stream, codec_context, codec, options) {
#if !SSR_USE_AVCODEC_ENCODE_AUDIO2
-@@ -77,7 +77,7 @@ unsigned int AudioEncoder::GetSampleRate() {
+@@ -81,7 +81,7 @@
}
bool AudioEncoder::AVCodecIsSupported(const QString& codec_name) {
@@ -41,7 +42,7 @@ index 34d015c..cefc2e0 100644
if(codec == NULL)
return false;
if(!av_codec_is_encoder(codec))
-@@ -93,7 +93,7 @@ bool AudioEncoder::AVCodecIsSupported(const QString& codec_name) {
+@@ -97,7 +97,7 @@
return false;
}
@@ -50,11 +51,11 @@ index 34d015c..cefc2e0 100644
unsigned int bit_rate, unsigned int channels, unsigned int sample_rate) {
if(channels == 0) {
-diff --git a/src/AV/Output/AudioEncoder.h b/src/AV/Output/AudioEncoder.h
-index c93278c..ae9c82e 100644
---- a/src/AV/Output/AudioEncoder.h
-+++ b/src/AV/Output/AudioEncoder.h
-@@ -40,7 +40,7 @@ private:
+Index: simplescreenrecorder-salsa/src/AV/Output/AudioEncoder.h
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/AudioEncoder.h 2024-05-08 08:58:34.613059892 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/AudioEncoder.h 2024-05-08 08:58:34.605059807 +0200
+@@ -40,7 +40,7 @@
#endif
public:
@@ -63,7 +64,7 @@ index c93278c..ae9c82e 100644
~AudioEncoder();
// Returns the required frame size, i.e. the number of samples (for each channel).
-@@ -57,7 +57,7 @@ public:
+@@ -57,7 +57,7 @@
public:
static bool AVCodecIsSupported(const QString& codec_name);
@@ -72,11 +73,11 @@ index c93278c..ae9c82e 100644
unsigned int bit_rate, unsigned int channels, unsigned int sample_rate);
private:
-diff --git a/src/AV/Output/BaseEncoder.cpp b/src/AV/Output/BaseEncoder.cpp
-index 7c01ef3..4780aaf 100644
---- a/src/AV/Output/BaseEncoder.cpp
-+++ b/src/AV/Output/BaseEncoder.cpp
-@@ -42,7 +42,7 @@ double ParseCodecOptionDouble(const QString& key, const QString& value, double m
+Index: simplescreenrecorder-salsa/src/AV/Output/BaseEncoder.cpp
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/BaseEncoder.cpp 2024-05-08 08:58:34.613059892 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/BaseEncoder.cpp 2024-05-08 08:58:34.605059807 +0200
+@@ -42,7 +42,7 @@
return clamp(value_double, min, max) * multiply;
}
@@ -85,7 +86,7 @@ index 7c01ef3..4780aaf 100644
m_muxer = muxer;
m_stream = stream;
-@@ -157,7 +157,7 @@ void BaseEncoder::IncrementPacketCounter() {
+@@ -157,7 +157,7 @@
++lock->m_total_packets;
}
@@ -94,11 +95,11 @@ index 7c01ef3..4780aaf 100644
// open codec
if(avcodec_open2(m_codec_context, codec, options) < 0) {
-diff --git a/src/AV/Output/BaseEncoder.h b/src/AV/Output/BaseEncoder.h
-index 3d92f29..7f02bbd 100644
---- a/src/AV/Output/BaseEncoder.h
-+++ b/src/AV/Output/BaseEncoder.h
-@@ -51,7 +51,7 @@ private:
+Index: simplescreenrecorder-salsa/src/AV/Output/BaseEncoder.h
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/BaseEncoder.h 2024-05-08 08:58:34.613059892 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/BaseEncoder.h 2024-05-08 08:58:34.605059807 +0200
+@@ -51,7 +51,7 @@
std::atomic<bool> m_should_stop, m_should_finish, m_is_done, m_error_occurred;
protected:
@@ -107,7 +108,7 @@ index 3d92f29..7f02bbd 100644
public:
virtual ~BaseEncoder(); // encoders will be deleted by Muxer, don't delete them yourself!
-@@ -117,7 +117,7 @@ protected:
+@@ -117,7 +117,7 @@
void IncrementPacketCounter();
private:
@@ -116,11 +117,11 @@ index 3d92f29..7f02bbd 100644
void Free();
void EncoderThread();
-diff --git a/src/AV/Output/Muxer.cpp b/src/AV/Output/Muxer.cpp
-index ad58380..1094dcc 100644
---- a/src/AV/Output/Muxer.cpp
-+++ b/src/AV/Output/Muxer.cpp
-@@ -87,7 +87,7 @@ Muxer::~Muxer() {
+Index: simplescreenrecorder-salsa/src/AV/Output/Muxer.cpp
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/Muxer.cpp 2024-05-08 08:58:34.613059892 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/Muxer.cpp 2024-05-08 08:58:34.605059807 +0200
+@@ -87,7 +87,7 @@
VideoEncoder* Muxer::AddVideoEncoder(const QString& codec_name, const std::vector<std::pair<QString, QString> >& codec_options,
unsigned int bit_rate, unsigned int width, unsigned int height, unsigned int frame_rate) {
@@ -129,7 +130,7 @@ index ad58380..1094dcc 100644
AVCodecContext *codec_context = NULL;
AVStream *stream = AddStream(codec, &codec_context);
VideoEncoder *encoder;
-@@ -111,7 +111,7 @@ VideoEncoder* Muxer::AddVideoEncoder(const QString& codec_name, const std::vecto
+@@ -111,7 +111,7 @@
AudioEncoder* Muxer::AddAudioEncoder(const QString& codec_name, const std::vector<std::pair<QString, QString> >& codec_options,
unsigned int bit_rate, unsigned int channels, unsigned int sample_rate) {
@@ -138,7 +139,7 @@ index ad58380..1094dcc 100644
AVCodecContext *codec_context = NULL;
AVStream *stream = AddStream(codec, &codec_context);
AudioEncoder *encoder;
-@@ -194,7 +194,7 @@ unsigned int Muxer::GetQueuedPacketCount(unsigned int stream_index) {
+@@ -194,7 +194,7 @@
void Muxer::Init() {
// get the format we want (this is just a pointer, we don't have to free this)
@@ -147,7 +148,7 @@ index ad58380..1094dcc 100644
if(format == NULL) {
Logger::LogError("[Muxer::Init] " + Logger::tr("Error: Can't find chosen output format!"));
throw LibavException();
-@@ -261,8 +261,8 @@ void Muxer::Free() {
+@@ -261,8 +261,8 @@
}
}
@@ -158,7 +159,7 @@ index ad58380..1094dcc 100644
if(codec == NULL) {
Logger::LogError("[Muxer::FindCodec] " + Logger::tr("Error: Can't find codec!"));
throw LibavException();
-@@ -270,7 +270,7 @@ AVCodec* Muxer::FindCodec(const QString& codec_name) {
+@@ -270,7 +270,7 @@
return codec;
}
@@ -167,11 +168,11 @@ index ad58380..1094dcc 100644
assert(!m_started);
assert(m_format_context->nb_streams < MUXER_MAX_STREAMS);
-diff --git a/src/AV/Output/Muxer.h b/src/AV/Output/Muxer.h
-index d72347d..b104bcb 100644
---- a/src/AV/Output/Muxer.h
-+++ b/src/AV/Output/Muxer.h
-@@ -114,8 +114,8 @@ private:
+Index: simplescreenrecorder-salsa/src/AV/Output/Muxer.h
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/Muxer.h 2024-05-08 08:58:34.613059892 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/Muxer.h 2024-05-08 08:58:34.605059807 +0200
+@@ -114,8 +114,8 @@
void Init();
void Free();
@@ -182,11 +183,11 @@ index d72347d..b104bcb 100644
void MuxerThread();
-diff --git a/src/AV/Output/VideoEncoder.cpp b/src/AV/Output/VideoEncoder.cpp
-index 8087e8e..fc8b5d1 100644
---- a/src/AV/Output/VideoEncoder.cpp
-+++ b/src/AV/Output/VideoEncoder.cpp
-@@ -34,7 +34,7 @@ const std::vector<VideoEncoder::PixelFormatData> VideoEncoder::SUPPORTED_PIXEL_F
+Index: simplescreenrecorder-salsa/src/AV/Output/VideoEncoder.cpp
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/VideoEncoder.cpp 2024-05-08 08:58:34.613059892 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/VideoEncoder.cpp 2024-05-08 08:58:34.605059807 +0200
+@@ -34,7 +34,7 @@
{"rgb", AV_PIX_FMT_RGB24, false},
};
@@ -195,7 +196,7 @@ index 8087e8e..fc8b5d1 100644
: BaseEncoder(muxer, stream, codec_context, codec, options) {
#if !SSR_USE_AVCODEC_ENCODE_VIDEO2
-@@ -95,7 +95,7 @@ unsigned int VideoEncoder::GetFrameRate() {
+@@ -95,7 +95,7 @@
}
bool VideoEncoder::AVCodecIsSupported(const QString& codec_name) {
@@ -204,7 +205,7 @@ index 8087e8e..fc8b5d1 100644
if(codec == NULL)
return false;
if(!av_codec_is_encoder(codec))
-@@ -111,7 +111,7 @@ bool VideoEncoder::AVCodecIsSupported(const QString& codec_name) {
+@@ -111,7 +111,7 @@
return false;
}
@@ -213,11 +214,11 @@ index 8087e8e..fc8b5d1 100644
unsigned int bit_rate, unsigned int width, unsigned int height, unsigned int frame_rate) {
if(width == 0 || height == 0) {
-diff --git a/src/AV/Output/VideoEncoder.h b/src/AV/Output/VideoEncoder.h
-index cb7ca27..68d872e 100644
---- a/src/AV/Output/VideoEncoder.h
-+++ b/src/AV/Output/VideoEncoder.h
-@@ -40,7 +40,7 @@ private:
+Index: simplescreenrecorder-salsa/src/AV/Output/VideoEncoder.h
+===================================================================
+--- simplescreenrecorder-salsa.orig/src/AV/Output/VideoEncoder.h 2024-05-08 08:58:34.613059892 +0200
++++ simplescreenrecorder-salsa/src/AV/Output/VideoEncoder.h 2024-05-08 08:58:34.605059807 +0200
+@@ -40,7 +40,7 @@
#endif
public:
@@ -226,7 +227,7 @@ index cb7ca27..68d872e 100644
~VideoEncoder();
// Returns the required pixel format.
-@@ -55,7 +55,7 @@ public:
+@@ -55,7 +55,7 @@
public:
static bool AVCodecIsSupported(const QString& codec_name);
diff --git a/source/xap/ssr/1010-appstream-metadata-https-category.patch b/source/xap/ssr/1010-appstream-metadata-https-category.patch
new file mode 100644
index 000000000..4841b471c
--- /dev/null
+++ b/source/xap/ssr/1010-appstream-metadata-https-category.patch
@@ -0,0 +1,87 @@
+Description: Corrected and renamed XDG desktop entry and Appstream metainfo XML.
+ Adjusted based on feedback from the Appstream validator (appstreamcli
+ validate-tree). Changed metainfo ID and file names to use reverse DNS
+ notation. Added categories, homepage URL and icon reference to the
+ metainfo file. Changed URLs to SSL secured variants.
+Author: Petter Reinholdtsen <pere@hungry.com>
+Forwarded: https://github.com/MaartenBaert/ssr/pull/1032
+Reviewed-By: Petter Reinholdtsen <pere@hungry.com>
+Last-Updated: 2024-05-08
+---
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index d2b2937..ec41ef9 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -88,11 +88,11 @@ if(WITH_SIMPLESCREENRECORDER)
+ DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1
+ )
+ install(
+- FILES data/simplescreenrecorder.desktop
++ FILES data/be.maartenbaert.simplescreenrecorder.desktop
+ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/applications
+ )
+ install(
+- FILES data/simplescreenrecorder.metainfo.xml
++ FILES data/be.maartenbaert.simplescreenrecorder.metainfo.xml
+ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/metainfo
+ )
+
+diff --git a/data/simplescreenrecorder.desktop b/data/be.maartenbaert.simplescreenrecorder.desktop
+similarity index 100%
+rename from data/simplescreenrecorder.desktop
+rename to data/be.maartenbaert.simplescreenrecorder.desktop
+diff --git a/data/simplescreenrecorder.metainfo.xml b/data/be.maartenbaert.simplescreenrecorder.metainfo.xml
+similarity index 60%
+rename from data/simplescreenrecorder.metainfo.xml
+rename to data/be.maartenbaert.simplescreenrecorder.metainfo.xml
+index 03d38a2..bbbbc2d 100644
+--- a/data/simplescreenrecorder.metainfo.xml
++++ b/data/be.maartenbaert.simplescreenrecorder.metainfo.xml
+@@ -1,6 +1,6 @@
+ <?xml version="1.0" encoding="UTF-8"?>
+ <component type="desktop">
+- <id>simplescreenrecorder.desktop</id>
++ <id>be.maartenbaert.simplescreenrecorder</id>
+ <metadata_license>CC0-1.0</metadata_license>
+ <project_license>GPL-3.0+</project_license>
+ <name>SimpleScreenRecorder</name>
+@@ -15,19 +15,33 @@
+ <li>Can also do live streaming (experimental).</li>
+ </ul>
+ </description>
++
++ <categories>
++ <category>AudioVideo</category>
++ <category>Video</category>
++ <category>Recorder</category>
++ <category>Qt</category>
++ </categories>
++
++ <launchable type="desktop-id">be.maartenbaert.simplescreenrecorder.desktop</launchable>
++ <icon type="stock">simplescreenrecorder</icon>
+ <screenshots>
+ <screenshot type="default">
+- <image>http://files.maartenbaert.be/simplescreenrecorder/screenshot01.png</image>
++ <image>https://files.maartenbaert.be/simplescreenrecorder/screenshot01.png</image>
+ <caption>The input settings page</caption>
+ </screenshot>
+ <screenshot type="default">
+- <image>http://files.maartenbaert.be/simplescreenrecorder/screenshot02.png</image>
++ <image>https://files.maartenbaert.be/simplescreenrecorder/screenshot02.png</image>
+ <caption>The output settings page</caption>
+ </screenshot>
+ <screenshot type="default">
+- <image>http://files.maartenbaert.be/simplescreenrecorder/screenshot03.png</image>
++ <image>https://files.maartenbaert.be/simplescreenrecorder/screenshot03.png</image>
+ <caption>The recording page</caption>
+ </screenshot>
+ </screenshots>
+- <url type="homepage">http://www.maartenbaert.be/simplescreenrecorder/</url>
+-</component>
+\ No newline at end of file
++ <url type="homepage">https://www.maartenbaert.be/simplescreenrecorder/</url>
++ <content_rating type="oars-1.0">
++ <content_attribute id="social-audio">intense</content_attribute>
++ <content_attribute id="social-contacts">intense</content_attribute>
++ </content_rating>
++</component>
diff --git a/source/xap/ssr/2000-private-glinject.patch b/source/xap/ssr/2000-private-glinject.patch
new file mode 100644
index 000000000..0def5a2b8
--- /dev/null
+++ b/source/xap/ssr/2000-private-glinject.patch
@@ -0,0 +1,40 @@
+From: James Cowgill <jcowgill@debian.org>
+Date: Fri, 14 Aug 2020 13:34:36 +0100
+Subject: Load libssr-glinject.so from private libdir
+
+The libssr-glinject.so library is not a public library. debian/rules sets the
+libdir to a private path, while this patch adjusts the uses of LD_PRELOAD to
+load from the correct directory.
+Author: James Cowgill <jcowgill@debian.org>
+---
+ scripts/ssr-glinject | 5 +++--
+ src/AV/Input/GLInjectInput.cpp | 2 +-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/scripts/ssr-glinject b/scripts/ssr-glinject
+index 2320690..cca58f3 100755
+--- a/scripts/ssr-glinject
++++ b/scripts/ssr-glinject
+@@ -59,6 +59,7 @@ do
+ fi
+ done
+
+-echo "ssr-glinject: LD_PRELOAD = $LD_PRELOAD:libssr-glinject.so" >& 2 || true
++SSR_GLINJECT="/usr/\$LIB/simplescreenrecorder/libssr-glinject.so"
++echo "ssr-glinject: LD_PRELOAD = $LD_PRELOAD:$SSR_GLINJECT" >& 2 || true
+ echo "ssr-glinject: command = $@" >& 2 || true
+-LD_PRELOAD="$LD_PRELOAD:libssr-glinject.so" exec "$@"
++LD_PRELOAD="$LD_PRELOAD:$SSR_GLINJECT" exec "$@"
+diff --git a/src/AV/Input/GLInjectInput.cpp b/src/AV/Input/GLInjectInput.cpp
+index fc98f31..1aee8ad 100644
+--- a/src/AV/Input/GLInjectInput.cpp
++++ b/src/AV/Input/GLInjectInput.cpp
+@@ -207,7 +207,7 @@ void GLInjectInput::SetCapturing(bool capturing) {
+ bool GLInjectInput::LaunchApplication(const QString& channel, bool relax_permissions, const QString& command, const QString& working_directory) {
+
+ // prepare command
+- QString full_command = "LD_PRELOAD=\"libssr-glinject.so\" ";
++ QString full_command = "LD_PRELOAD=\"/usr/" + ShellEscape("$LIB") + "/simplescreenrecorder/libssr-glinject.so\" ";
+ full_command += "SSR_CHANNEL=\"" + ShellEscape(channel) + "\" ";
+ if(relax_permissions)
+ full_command += "SSR_STREAM_RELAX_PERMISSIONS=1 ";
diff --git a/source/xap/ssr/3000-more-ffmpeg7-fixup.patch b/source/xap/ssr/3000-more-ffmpeg7-fixup.patch
new file mode 100644
index 000000000..cdf3d2f29
--- /dev/null
+++ b/source/xap/ssr/3000-more-ffmpeg7-fixup.patch
@@ -0,0 +1,28 @@
+--- ./src/AV/Output/AudioEncoder.cpp.orig 2024-08-08 14:14:12.891073468 -0500
++++ ./src/AV/Output/AudioEncoder.cpp 2024-08-08 14:15:56.952101391 -0500
+@@ -69,11 +69,7 @@
+ }
+
+ unsigned int AudioEncoder::GetChannels() {
+-#if LIBAVCODEC_VERSION_MAJOR < 61
+- return GetCodecContext()->channels;
+-#else
+ return GetCodecContext()->ch_layout.nb_channels;
+-#endif
+ }
+
+ unsigned int AudioEncoder::GetSampleRate() {
+@@ -110,13 +106,8 @@
+ }
+
+ codec_context->bit_rate = bit_rate;
+-#if LIBAVCODEC_VERSION_MAJOR < 61
+- codec_context->channels = channels;
+- codec_context->channel_layout = (channels == 1)? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+-#else
+ codec_context->ch_layout.nb_channels = channels;
+ codec_context->ch_layout.u.mask = (channels == 1)? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+-#endif
+ codec_context->sample_rate = sample_rate;
+ codec_context->time_base.num = 1;
+ codec_context->time_base.den = sample_rate;
diff --git a/source/xap/ssr/3001-disable-non-compiling-channel-support.patch b/source/xap/ssr/3001-disable-non-compiling-channel-support.patch
new file mode 100644
index 000000000..082f77ac1
--- /dev/null
+++ b/source/xap/ssr/3001-disable-non-compiling-channel-support.patch
@@ -0,0 +1,11 @@
+--- ./src/Global.h.orig 2021-05-24 13:56:32.000000000 -0500
++++ ./src/Global.h 2024-08-08 14:26:28.198920359 -0500
+@@ -284,7 +284,7 @@
+ // AV_CODEC_ID_* instead of CODEC_ID_*: lavc 54.51.100 / 54.25.0
+ #define SSR_USE_AV_CODEC_ID TEST_AV_VERSION(LIBAVCODEC, 54, 51, 54, 25)
+ // AVFrame::channels: lavc 54.46.100 / ???
+-#define SSR_USE_AVFRAME_CHANNELS TEST_AV_VERSION(LIBAVCODEC, 54, 46, 999, 999)
++#define SSR_USE_AVFRAME_CHANNELS TEST_AV_VERSION(LIBAVCODEC, 62, 0, 62, 0)
+ // AVFrame::sample_rate: lavc 54.20.100 / 54.13.0
+ #define SSR_USE_AVFRAME_SAMPLE_RATE TEST_AV_VERSION(LIBAVCODEC, 54, 20, 54, 13)
+ // av_codec_is_encoder: lavc 54.8.100 / 54.7.0
diff --git a/source/xap/ssr/ssr.SlackBuild b/source/xap/ssr/ssr.SlackBuild
index faefebadc..0de5f88a0 100755
--- a/source/xap/ssr/ssr.SlackBuild
+++ b/source/xap/ssr/ssr.SlackBuild
@@ -24,12 +24,12 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=ssr
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-2}
+BUILD=${BUILD:-3}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$(uname -m)" in
- i?86) ARCH=i586 ;;
+ i?86) ARCH=i686 ;;
arm*) readelf /usr/bin/file -A | grep -E -q "Tag_CPU.*[4,5]" && ARCH=arm || ARCH=armv7hl ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) ARCH=$(uname -m) ;;
@@ -47,21 +47,12 @@ fi
NUMJOBS=${NUMJOBS:-" -j $(expr $(nproc) + 1) "}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "i686" ]; then
- SLKCFLAGS="-O2 -march=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
-elif [ "$ARCH" = "armv7hl" ]; then
- SLKCFLAGS="-O3 -march=armv7-a -mfpu=vfpv3-d16"
- LIBDIRSUFFIX=""
else
SLKCFLAGS="-O2"
LIBDIRSUFFIX=""
@@ -85,7 +76,16 @@ find . \
\( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
-exec chmod 644 {} \+
-zcat $CWD/0003-Fix-build-with-ffmpeg-5.0.patch.gz | patch -p1 --verbose || exit 1
+cat $CWD/0010-plthook.patch | patch -p1 --verbose || exit 1
+cat $CWD/0020-ffmpeg-7.patch | patch -p1 --verbose || exit 1
+cat $CWD/1000-Fix-build-with-ffmpeg-5.0.patch | patch -p1 --verbose || exit 1
+cat $CWD/1010-appstream-metadata-https-category.patch | patch -p1 --verbose || exit 1
+cat $CWD/2000-private-glinject.patch | patch -p1 --verbose || exit 1
+cat $CWD/3000-more-ffmpeg7-fixup.patch | patch -p1 --verbose || exit 1
+
+# Seems like this could be fixed if I find time to study the pointless
+# churn of ffmpeg7
+cat $CWD/3001-disable-non-compiling-channel-support.patch | patch -p1 --verbose || exit 1
# Configure, build, and install:
mkdir cmake-build
diff --git a/source/xap/xaos/xaos.SlackBuild b/source/xap/xaos/xaos.SlackBuild
index 0bd1f27a8..031f03a9b 100755
--- a/source/xap/xaos/xaos.SlackBuild
+++ b/source/xap/xaos/xaos.SlackBuild
@@ -26,12 +26,11 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=xaos
SRCNAM=XaoS
VERSION=${VERSION:-$(echo $SRCNAM-*.tar.?z | cut -f 2 -d -)}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- # might as well use i686 since it won't listen to our CFLAGS anyway
i?86) ARCH=i686 ;;
arm*) ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
@@ -49,6 +48,26 @@ fi
NUMJOBS=${NUMJOBS:-" -j $(expr $(nproc) + 1) "}
+if [ "$ARCH" = "i586" ]; then
+ SLKCFLAGS="-O2 -march=i586 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "s390" ]; then
+ SLKCFLAGS="-O2"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "x86_64" ]; then
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
+ LIBDIRSUFFIX="64"
+elif [ "$ARCH" = "armv7hl" ]; then
+ SLKCFLAGS="-O3 -march=armv7-a -mfpu=vfpv3-d16"
+ LIBDIRSUFFIX=""
+else
+ SLKCFLAGS="-O2"
+ LIBDIRSUFFIX=""
+fi
+
TMP=${TMP:-/tmp}
PKG=$TMP/package-$PKGNAM
diff --git a/source/xap/xgames/xgames.SlackBuild b/source/xap/xgames/xgames.SlackBuild
index bcccbb5b3..52b817910 100755
--- a/source/xap/xgames/xgames.SlackBuild
+++ b/source/xap/xgames/xgames.SlackBuild
@@ -58,6 +58,7 @@ cd spider || exit 1
zcat $CWD/spider.diff.gz | patch -p1 --verbose || exit 1
xmkmf
zcat $CWD/spider.gcc10.diff.gz | patch -p1 --verbose || exit 1
+sed -i "s| CFLAGS = | CFLAGS = -Wno-error=implicit-int -Wno-error=implicit-function-declaration -Wno-error=return-mismatch |g" Makefile
make $NUMJOBS || make || exit 1
mkdir -p $PKG/usr/bin
cat spider > $PKG/usr/bin/spider
@@ -72,6 +73,7 @@ tar xvf $CWD/maze.tar.lz || exit 1
cd maze || exit 1
zcat $CWD/maze.diff.gz | patch -p1 || exit 1
xmkmf
+sed -i "s| CFLAGS = | CFLAGS = -Wno-error=implicit-int -Wno-error=implicit-function-declaration -Wno-error=return-mismatch -Wno-error=int-conversion |g" Makefile
make $NUMJOBS || make || exit 1
cat maze > $PKG/usr/bin/maze
cat maze.man | gzip -9c > $PKG/usr/man/man6/maze.6.gz
@@ -83,6 +85,7 @@ cd $TMP
tar xvf $CWD/xcolormap.tar.lz || exit 1
cd xcolormap || exit 1
zcat $CWD/xcolormap.diff.gz | patch -p1 || exit 1
+sed -i "s|CFLAGS = |CFLAGS = -Wno-error=implicit-int -Wno-error=implicit-function-declaration -Wno-error=return-mismatch -Wno-error=int-conversion -Wno-error=incompatible-pointer-types |g" Makefile
make $NUMJOBS || make || exit 1
cat xcolormap > $PKG/usr/bin/xcolormap
mkdir -p $PKG/usr/doc/xgames-$VERSION/xcolormap
@@ -94,6 +97,7 @@ tar xvf $CWD/xcuckoo-1.1.tar.lz || exit 1
cd xcuckoo || exit 1
zcat $CWD/xcuckoo.diff.gz | patch -p1 --verbose || exit 1
xmkmf
+sed -i "s| CFLAGS = | CFLAGS = -Wno-error=implicit-int -Wno-error=implicit-function-declaration -Wno-error=return-mismatch -Wno-error=int-conversion |g" Makefile
make $NUMJOBS || make || exit 1
cat xcuckoo > $PKG/usr/bin/xcuckoo
cat xcuckoo.man | gzip -9c > $PKG/usr/man/man6/xcuckoo.6.gz
@@ -107,6 +111,7 @@ cd xlander || exit 1
zcat $CWD/xlander.fixes.diff.gz | patch -p1 || exit 1
zcat $CWD/xlander-2009-07-18.diff.gz | patch -p1 || exit 1
xmkmf
+sed -i "s| CFLAGS = | CFLAGS = -Wno-error=implicit-int -Wno-error=implicit-function-declaration -Wno-error=return-mismatch -Wno-error=int-conversion |g" Makefile
make $NUMJOBS || make || exit 1
cat xlander > $PKG/usr/bin/xlander
cat xlander.man | gzip -9c > $PKG/usr/man/man6/xlander.6.gz
@@ -118,6 +123,7 @@ cd $TMP
tar xvf $CWD/xminesweep3.0.tar.lz || exit 1
cd xminesweep3.0 || exit 1
xmkmf
+sed -i "s| CFLAGS = | CFLAGS = -Wno-error=implicit-int -Wno-error=implicit-function-declaration -Wno-error=return-mismatch -Wno-error=int-conversion |g" Makefile
make $NUMJOBS || make || exit 1
cat xminesweep > $PKG/usr/bin/xminesweep
cat xminesweep.man | gzip -9c > $PKG/usr/man/man6/xminesweep.6.gz
@@ -129,6 +135,7 @@ cd $TMP
tar xvf $CWD/xneko.tar.lz || exit 1
cd xneko || exit 1
xmkmf
+sed -i "s| CFLAGS = | CFLAGS = -Wno-error=implicit-int -Wno-error=implicit-function-declaration -Wno-error=return-mismatch -Wno-error=int-conversion |g" Makefile
make $NUMJOBS || make || exit 1
cat xneko > $PKG/usr/bin/xneko
cat xneko.man | gzip -9c > $PKG/usr/man/man6/xneko.6.gz
@@ -140,6 +147,7 @@ cd $TMP
tar xvf $CWD/xroach.tar.lz || exit 1
cd xroach || exit 1
xmkmf
+sed -i "s| CFLAGS = | CFLAGS = -Wno-error=implicit-int -Wno-error=implicit-function-declaration -Wno-error=return-mismatch -Wno-error=int-conversion |g" Makefile
make $NUMJOBS || make || exit 1
cat xroach > $PKG/usr/bin/xroach
cat xroach.man | gzip -9c > $PKG/usr/man/man6/xroach.6.gz
diff --git a/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg6-compatibility.patch b/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg6-compatibility.patch
new file mode 100644
index 000000000..11056aa8c
--- /dev/null
+++ b/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg6-compatibility.patch
@@ -0,0 +1,196 @@
+# HG changeset patch
+# User Torsten Jager <t.jager@gmx.de>
+# Date 1674929040 -3600
+# Sat Jan 28 19:04:00 2023 +0100
+# Node ID 771f4ae27e582123ff3500444718fc8f96186d74
+# Parent 250f1c09f4244c3e7ca7d414410c57bd387792c3
+ffmpeg compatibility update.
+
+diff -r 250f1c09f424 -r 771f4ae27e58 src/combined/ffmpeg/demux_avformat.c
+--- a/src/combined/ffmpeg/demux_avformat.c Wed Jan 25 17:03:55 2023 +0100
++++ b/src/combined/ffmpeg/demux_avformat.c Sat Jan 28 19:04:00 2023 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2013-2022 the xine project
++ * Copyright (C) 2013-2023 the xine project
+ * Copyright (C) 2013-2020 Petri Hintukainen <phintuka@users.sourceforge.net>
+ *
+ * This file is part of xine, a free video player.
+@@ -423,8 +423,13 @@
+ }
+
+ #ifdef XFF_CODECPAR
++# if XFF_AUDIO_CHANNEL_LAYOUT < 2
+ if (st->codecpar && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
+ st->codecpar->sample_rate != 0 && st->codecpar->channels != 0)
++# else
++ if (st->codecpar && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
++ st->codecpar->sample_rate != 0 && st->codecpar->ch_layout.nb_channels != 0)
++# endif
+ #else
+ if (st->codec && st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
+ st->codec->sample_rate != 0 && st->codec->channels != 0)
+@@ -501,7 +506,11 @@
+ buf->size = extradata_size + sizeof(xine_waveformatex);
+ buf->decoder_info[1] = ctx->sample_rate;
+ buf->decoder_info[2] = ctx->bits_per_coded_sample;
++#if XFF_AUDIO_CHANNEL_LAYOUT < 2
+ buf->decoder_info[3] = ctx->channels;
++#else
++ buf->decoder_info[3] = ctx->ch_layout.nb_channels;
++#endif
+ buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END;
+
+ this->stream->audio_fifo->put (this->stream->audio_fifo, buf);
+diff -r 250f1c09f424 -r 771f4ae27e58 src/combined/ffmpeg/ff_audio_decoder.c
+--- a/src/combined/ffmpeg/ff_audio_decoder.c Wed Jan 25 17:03:55 2023 +0100
++++ b/src/combined/ffmpeg/ff_audio_decoder.c Sat Jan 28 19:04:00 2023 +0100
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2001-2022 the xine project
++ * Copyright (C) 2001-2023 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+@@ -303,7 +303,11 @@
+
+ this->context->bits_per_sample = this->ff_bits;
+ this->context->sample_rate = this->ff_sample_rate;
++#if XFF_AUDIO_CHANNEL_LAYOUT < 2
+ this->context->channels = this->ff_channels;
++#else
++ this->context->ch_layout.nb_channels = this->ff_channels;
++#endif
+ this->context->codec_id = this->codec->id;
+ this->context->codec_type = this->codec->type;
+ this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC);
+@@ -527,16 +531,75 @@
+ this->ao_mode = 0;
+ }
+
++static unsigned int ff_list_channels (uint8_t *list, uint64_t map) {
++ unsigned int n, bit;
++
++ for (n = bit = 0; map; map >>= 1, bit++) {
++ uint32_t b = map & 1;
++
++ list[n] = bit;
++ n += b;
++ }
++ return n;
++}
++
+ static void ff_map_channels (ff_audio_decoder_t *this) {
+ uint64_t ff_map;
++ uint8_t ff_list[64];
++ unsigned int ff_num;
++ const char *type = "native";
+ int caps = this->stream->audio_out->get_capabilities (this->stream->audio_out);
+
++#if XFF_AUDIO_CHANNEL_LAYOUT < 2
++
+ /* safety kludge for very old libavcodec */
+-#ifdef AV_CH_FRONT_LEFT
++# ifdef AV_CH_FRONT_LEFT
+ ff_map = this->context->channel_layout;
+ if (!ff_map) /* wma2 bug */
++# endif
++ ff_map = ((uint64_t)1 << this->context->channels) - 1;
++ ff_num = ff_list_channels (ff_list, ff_map);
++
++#else /* XFF_AUDIO_CHANNEL_LAYOUT == 2 */
++
++ ff_num = this->context->ch_layout.nb_channels;
++ if (ff_num > (int)(sizeof (ff_list) / sizeof (ff_list[0])))
++ ff_num = sizeof (ff_list) / sizeof (ff_list[0]);
++ switch (this->context->ch_layout.order) {
++ const AVChannelCustom *cmap;
++ unsigned int i;
++
++ case AV_CHANNEL_ORDER_UNSPEC:
++ type = "unknown";
++ goto _fallback;
++
++ case AV_CHANNEL_ORDER_NATIVE:
++ ff_map = this->context->ch_layout.u.mask;
++ if (!ff_map) /* wma2 bug */
++ ff_map = ((uint64_t)1 << ff_num) - 1;
++ ff_num = ff_list_channels (ff_list, ff_map);
++ break;
++
++ case AV_CHANNEL_ORDER_CUSTOM:
++ type = "custom";
++ if (!(cmap = this->context->ch_layout.u.map))
++ goto _fallback;
++ ff_map = 0;
++ for (i = 0; i < ff_num; i++) {
++ ff_list[i] = cmap[i].id;
++ ff_map |= (uint64_t)1 << ff_list[i];
++ }
++ break;
++
++ default:
++ type = "unsupported";
++ /* fall through */
++ _fallback:
++ ff_map = ((uint64_t)1 << ff_num) - 1;
++ ff_num = ff_list_channels (ff_list, ff_map);
++ }
++
+ #endif
+- ff_map = ((uint64_t)1 << this->context->channels) - 1;
+
+ if ((caps != this->ao_caps) || (ff_map != this->ff_map)) {
+ unsigned int i, j;
+@@ -562,7 +625,7 @@
+
+ this->ao_caps = caps;
+ this->ff_map = ff_map;
+- this->ff_channels = this->context->channels;
++ this->ff_channels = ff_num;
+
+ /* silence out */
+ for (i = 0; i < MAX_CHANNELS; i++)
+@@ -576,20 +639,23 @@
+ this->left[0] = this->right[0] = 0;
+ tries = wishlist + 0 * num_modes;
+ } else if (this->ff_channels == 2) { /* stereo */
++ /* FIXME: libxine does not yet support audio selection _after_ decoding.
++ * For now, treat the most common "dual mono" case as stereo. */
+ name_map[0] = 0;
+ name_map[1] = 1;
+ this->left[0] = 0;
+ this->right[0] = 1;
+ tries = wishlist + 1 * num_modes;
+ } else {
+- for (i = j = 0; i < sizeof (base_map) / sizeof (base_map[0]); i++) {
+- if ((ff_map >> i) & 1) {
+- int8_t target = base_map[i];
+- if ((target >= 0) && (this->map[target] < 0))
+- this->map[target] = j;
+- name_map[j] = i; /* for debug output below */
+- j++;
+- }
++ for (i = 0; i < ff_num; i++) {
++ int8_t target;
++ uint32_t num = ff_list[i];
++ if (num >= sizeof (base_map) / sizeof (base_map[0]))
++ continue;
++ target = base_map[num];
++ if ((target >= 0) && (this->map[target] < 0))
++ this->map[target] = i;
++ name_map[i] = num; /* for debug output below */
+ }
+ this->left[0] = this->map[0] < 0 ? 0 : this->map[0];
+ this->map[0] = -1;
+@@ -641,8 +707,8 @@
+ "rear center",
+ "side left", "side right"
+ };
+- int8_t buf[200];
+- int p = sprintf (buf, "ff_audio_dec: channel layout: ");
++ int8_t buf[256];
++ int p = sprintf (buf, "ff_audio_dec: %s channel layout: ", type);
+ int8_t *indx = this->left;
+ for (i = 0; i < 2; i++) {
+ buf[p++] = '[';
diff --git a/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg6-compatibility_2.patch b/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg6-compatibility_2.patch
new file mode 100644
index 000000000..d5003ca95
--- /dev/null
+++ b/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg6-compatibility_2.patch
@@ -0,0 +1,475 @@
+# HG changeset patch
+# User Torsten Jager <t.jager@gmx.de>
+# Date 1715025355 -7200
+# Mon May 06 21:55:55 2024 +0200
+# Node ID 1e7b184008860c8be2289c3cefd9dee57f06193a
+# Parent d1954d852980ddc887a67a9f1a26626909561ff5
+ffmpeg compatibility update 1.
+
+diff -r d1954d852980 -r 1e7b18400886 src/combined/ffmpeg/ff_audio_decoder.c
+--- a/src/combined/ffmpeg/ff_audio_decoder.c Mon Apr 08 13:25:10 2024 +0200
++++ b/src/combined/ffmpeg/ff_audio_decoder.c Mon May 06 21:55:55 2024 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2001-2023 the xine project
++ * Copyright (C) 2001-2024 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+@@ -67,6 +67,7 @@
+
+ xine_t *xine;
+ float gain;
++ int bitexact;
+ } ff_audio_class_t;
+
+ typedef struct ff_audio_decoder_s {
+@@ -188,14 +189,25 @@
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: found AAC ADTS syncword after %d bytes\n", i);
+ if (this->buftype == BUF_AUDIO_AAC_LATM) {
++ uint8_t *ed = NULL;
++ int es = 0;
+ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
+ "ffmpeg_audio_dec: stream says LATM but is ADTS -> switching decoders\n");
+- if (this->decoder_ok) {
+- pthread_mutex_lock (&ffmpeg_lock);
+- avcodec_close (this->context);
+- pthread_mutex_unlock (&ffmpeg_lock);
+- this->decoder_ok = 0;
++ pthread_mutex_lock (&ffmpeg_lock);
++ if (this->context) {
++ ed = this->context->extradata;
++ es = this->context->extradata_size;
++ this->context->extradata = NULL;
++ this->context->extradata_size = 0;
++ XFF_FREE_CONTEXT (this->context);
+ }
++ this->decoder_ok = 0;
++ this->context = XFF_ALLOC_CONTEXT ();
++ if (this->context) {
++ this->context->extradata = ed;
++ this->context->extradata_size = es;
++ }
++ pthread_mutex_unlock (&ffmpeg_lock);
+ this->codec = NULL;
+ ff_audio_open_codec (this, BUF_AUDIO_AAC);
+ }
+@@ -349,6 +361,11 @@
+ return -1;
+ }
+
++ if (this->class->bitexact)
++ this->context->flags |= CODEC_FLAG_BITEXACT;
++ else
++ this->context->flags &= ~CODEC_FLAG_BITEXACT;
++
+ pthread_mutex_lock (&ffmpeg_lock);
+ if (XFF_AVCODEC_OPEN (this->context, this->codec) < 0) {
+ pthread_mutex_unlock (&ffmpeg_lock);
+@@ -1377,9 +1394,21 @@
+ }
+ #endif
+ pthread_mutex_lock (&ffmpeg_lock);
+- avcodec_close (this->context);
+- if (XFF_AVCODEC_OPEN (this->context, this->codec) < 0)
++ {
++ uint8_t *ed = this->context->extradata;
++ int es = this->context->extradata_size;
++ this->context->extradata = NULL;
++ this->context->extradata_size = 0;
++ XFF_FREE_CONTEXT (this->context);
+ this->decoder_ok = 0;
++ this->context = XFF_ALLOC_CONTEXT ();
++ if (this->context) {
++ this->context->extradata = ed;
++ this->context->extradata_size = es;
++ }
++ }
++ if (XFF_AVCODEC_OPEN (this->context, this->codec) >= 0)
++ this->decoder_ok = 1;
+ pthread_mutex_unlock (&ffmpeg_lock);
+ }
+
+@@ -1418,20 +1447,20 @@
+ XFF_FREE_FRAME (this->av_frame);
+ }
+ #endif
+- pthread_mutex_lock (&ffmpeg_lock);
+- avcodec_close (this->context);
+- pthread_mutex_unlock (&ffmpeg_lock);
+ }
++ pthread_mutex_lock (&ffmpeg_lock);
++ if (this->context) {
++ _x_freep (&this->context->extradata);
++ this->context->extradata_size = 0;
++ XFF_FREE_CONTEXT (this->context);
++ }
++ pthread_mutex_unlock (&ffmpeg_lock);
+
+ ff_audio_output_close(this);
+
+ xine_free_aligned (this->buf);
+ xine_free_aligned (this->decode_buffer);
+
+- _x_freep (&this->context->extradata);
+- this->context->extradata_size = 0;
+- XFF_FREE_CONTEXT (this->context);
+-
+ XFF_PACKET_UNREF (this->avpkt);
+
+ xine_pts_queue_delete (&this->pts_queue);
+@@ -1513,6 +1542,12 @@
+ free (this);
+ }
+
++static void ff_bitexact_cb (void *user_data, xine_cfg_entry_t *entry) {
++ ff_audio_class_t *class = (ff_audio_class_t *)user_data;
++
++ class->bitexact = entry->num_value;
++}
++
+ void *init_audio_plugin (xine_t *xine, const void *data) {
+
+ ff_audio_class_t *this ;
+@@ -1540,5 +1575,12 @@
+ 10, ff_gain_cb, this)
+ / (float)20);
+
++ this->bitexact = xine->config->register_bool (xine->config,
++ "audio.processing.ffmpeg_bitexact", 0,
++ _("Let FFmpeg use precise but slower math"),
++ _("Get slightly better sound, at the expense of speed.\n"
++ "Takes effect with next stream."),
++ 10, ff_bitexact_cb, this);
++
+ return this;
+ }
+diff -r d1954d852980 -r 1e7b18400886 src/combined/ffmpeg/ff_video_decoder.c
+--- a/src/combined/ffmpeg/ff_video_decoder.c Mon Apr 08 13:25:10 2024 +0200
++++ b/src/combined/ffmpeg/ff_video_decoder.c Mon May 06 21:55:55 2024 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2001-2022 the xine project
++ * Copyright (C) 2001-2024 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+@@ -128,6 +128,7 @@
+
+ int64_t pts;
+ int64_t last_pts;
++ int64_t tagged_pts;
+ int video_step;
+ int reported_video_step;
+ uint8_t pts_tag_pass;
+@@ -551,7 +552,9 @@
+ # ifdef XFF_FRAME_AGE
+ av_frame->age = 1;
+ # endif
++#ifdef XFF_AVCODEC_REORDERED_OPAQUE
+ av_frame->reordered_opaque = context->reordered_opaque;
++#endif
+
+ ffsf = ffsf_new (this);
+ if (!ffsf)
+@@ -862,7 +865,9 @@
+ # endif
+
+ /* take over pts for this frame to have it reordered */
++#ifdef XFF_AVCODEC_REORDERED_OPAQUE
+ av_frame->reordered_opaque = context->reordered_opaque;
++#endif
+
+ return 0;
+ }
+@@ -1142,9 +1147,13 @@
+ if (this->codec->id == CODEC_ID_VC1 &&
+ (!this->bih.biWidth || !this->bih.biHeight)) {
+ /* VC1 codec must be re-opened with correct width and height. */
+- avcodec_close(this->context);
+-
+- if (XFF_AVCODEC_OPEN (this->context, this->codec) < 0) {
++ if (this->context) {
++ _x_freep (&this->context->extradata);
++ this->context->extradata_size = 0;
++ XFF_FREE_CONTEXT (this->context);
++ }
++ this->context = XFF_ALLOC_CONTEXT ();
++ if (!(this->context && XFF_AVCODEC_OPEN (this->context, this->codec) >= 0)) {
+ pthread_mutex_unlock(&ffmpeg_lock);
+ xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
+ _("ffmpeg_video_dec: couldn't open decoder (pass 2)\n"));
+@@ -1211,6 +1220,11 @@
+ /* dont want initial AV_NOPTS_VALUE here */
+ this->context->reordered_opaque = 0;
+ #endif
++
++#ifdef XFF_AVCODEC_FRAME_PTS
++ this->context->time_base.num = 1;
++ this->context->time_base.den = 90000 << 8;
++#endif
+ }
+
+ #ifdef ENABLE_VAAPI
+@@ -1959,7 +1973,26 @@
+ return (pts * 256) | this->pts_tag_pass;
+ }
+
+-static int64_t ff_untag_pts (ff_video_decoder_t *this, int64_t pts) {
++static int64_t ff_untag_pts (ff_video_decoder_t *this, AVFrame *av_frame) {
++ int64_t pts;
++#if defined(XFF_AVCODEC_FRAME_PTS)
++ pts = (av_frame->pts != AV_NOPTS_VALUE) ? av_frame->pts : 0;
++# if defined(XFF_AVCODEC_REORDERED_OPAQUE)
++ /* paranoia !!! */
++ if (pts != av_frame->reordered_opaque) {
++ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,
++ LOG_MODULE ": WARNING: frame pts %" PRId64 " != reordered_opaque %" PRId64 ".\n",
++ pts, av_frame->reordered_opaque);
++ pts = av_frame->reordered_opaque;
++ }
++ av_frame->reordered_opaque = 0;
++# endif
++#elif defined(XFF_AVCODEC_REORDERED_OPAQUE)
++ pts = av_frame->reordered_opaque;
++ av_frame->reordered_opaque = 0;
++#else
++ pts = this->tagged_pts;
++#endif
+ if ((uint8_t)(pts & 0xff) == this->pts_tag_pass) {
+ /* restore sign. */
+ return pts >> 8;
+@@ -1984,7 +2017,9 @@
+ this->avpkt->data = buf;
+ this->avpkt->size = buf_size;
+ this->avpkt->flags = AV_PKT_FLAG_KEY;
+-
++# ifdef XFF_AVCODEC_FRAME_PTS
++ this->avpkt->pts = this->tagged_pts;
++# endif
+ # if XFF_PALETTE == 2 || XFF_PALETTE == 3
+ if (buf && this->palette_changed) {
+ uint8_t *sd = av_packet_new_side_data (this->avpkt, AV_PKT_DATA_PALETTE, 256 * 4);
+@@ -2094,9 +2129,14 @@
+ #endif
+
+ /* apply valid pts to first frame _starting_ thereafter only */
+- if (this->pts && !this->context->reordered_opaque) {
+- this->context->reordered_opaque =
+- this->av_frame->reordered_opaque = ff_tag_pts (this, this->pts);
++ if (this->pts && !this->tagged_pts) {
++ this->tagged_pts = ff_tag_pts (this, this->pts);
++#ifdef XFF_AVCODEC_REORDERED_OPAQUE
++ this->context->reordered_opaque = this->av_frame->reordered_opaque = this->tagged_pts;
++#endif
++#ifdef XFF_AVCODEC_FRAME_PTS
++ this->av_frame->pts = this->tagged_pts;
++#endif
+ this->pts = 0;
+ }
+
+@@ -2207,9 +2247,11 @@
+ img->top_field_first = this->av_frame->top_field_first;
+
+ /* get back reordered pts */
+- img->pts = ff_untag_pts (this, this->av_frame->reordered_opaque);
+- this->av_frame->reordered_opaque = 0;
++ img->pts = ff_untag_pts (this, this->av_frame);
++ this->tagged_pts = 0;
++#ifdef XFF_AVCODEC_REORDERED_OPAQUE
+ this->context->reordered_opaque = 0;
++#endif
+
+ if (this->av_frame->repeat_pict)
+ img->duration = this->video_step * 3 / 2;
+@@ -2330,9 +2372,14 @@
+ }
+
+ if (this->size == 0) {
++ this->tagged_pts = ff_tag_pts (this, this->pts);
+ /* take over pts when we are about to buffer a frame */
+- this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);
+- this->context->reordered_opaque = ff_tag_pts(this, this->pts);
++#ifdef XFF_AVCODEC_REORDERED_OPAQUE
++ this->av_frame->reordered_opaque = this->context->reordered_opaque = this->tagged_pts;
++#endif
++#ifdef XFF_AVCODEC_FRAME_PTS
++ this->av_frame->pts = this->tagged_pts;
++#endif
+ this->pts = 0;
+ }
+
+@@ -2405,7 +2452,10 @@
+ need_unref = 1;
+ #endif
+ /* reset consumed pts value */
+- this->context->reordered_opaque = ff_tag_pts(this, 0);
++ this->tagged_pts = ff_tag_pts (this, 0);
++#ifdef XFF_AVCODEC_REORDERED_OPAQUE
++ this->context->reordered_opaque = this->tagged_pts;
++#endif
+
+ if (err) {
+
+@@ -2439,10 +2489,14 @@
+ ff_check_bufsize(this, this->size);
+ memmove (this->buf, &chunk_buf[offset], this->size);
+ chunk_buf = this->buf;
+-
+ /* take over pts for next access unit */
+- this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);
+- this->context->reordered_opaque = ff_tag_pts(this, this->pts);
++ this->tagged_pts = ff_tag_pts (this, this->pts);
++#ifdef XFF_AVCODEC_REORDERED_OPAQUE
++ this->av_frame->reordered_opaque = this->context->reordered_opaque = this->tagged_pts;
++#endif
++#ifdef XFF_AVCODEC_FRAME_PTS
++ this->av_frame->pts = this->tagged_pts;
++#endif
+ this->pts = 0;
+ }
+ }
+@@ -2559,8 +2613,7 @@
+ ff_convert_frame(this, img, this->av_frame);
+ }
+
+- img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque);
+- this->av_frame->reordered_opaque = 0;
++ img->pts = ff_untag_pts(this, this->av_frame);
+
+ /* workaround for weird 120fps streams */
+ if( video_step_to_use == 750 ) {
+@@ -2600,8 +2653,7 @@
+ this->output_format,
+ VO_BOTH_FIELDS|this->frame_flags);
+ /* set PTS to allow early syncing */
+- img->pts = ff_untag_pts(this, this->av_frame->reordered_opaque);
+- this->av_frame->reordered_opaque = 0;
++ img->pts = ff_untag_pts(this, this->av_frame);
+
+ img->duration = video_step_to_use;
+
+@@ -2783,7 +2835,7 @@
+ ff_convert_frame (this, img, this->av_frame2);
+ }
+
+- img->pts = ff_untag_pts (this, this->av_frame2->reordered_opaque);
++ img->pts = ff_untag_pts (this, this->av_frame2);
+
+ if (video_step_to_use == 750)
+ video_step_to_use = 0;
+@@ -2903,7 +2955,9 @@
+ if (this->decoder_ok) {
+
+ pthread_mutex_lock(&ffmpeg_lock);
+- avcodec_close (this->context);
++ _x_freep (&this->context->extradata);
++ this->context->extradata_size = 0;
++ XFF_FREE_CONTEXT (this->context);
+ pthread_mutex_unlock(&ffmpeg_lock);
+
+ #ifdef ENABLE_DIRECT_RENDERING
+@@ -2912,16 +2966,15 @@
+
+ this->stream->video_out->close(this->stream->video_out, this->stream);
+ this->decoder_ok = 0;
++ } else if (this->context) {
++ _x_freep (&this->context->extradata);
++ this->context->extradata_size = 0;
++ XFF_FREE_CONTEXT (this->context);
+ }
+
+ if (this->slice_offset_table)
+ free (this->slice_offset_table);
+
+- if (this->context) {
+- _x_freep (&this->context->extradata);
+- this->context->extradata_size = 0;
+- XFF_FREE_CONTEXT (this->context);
+- }
+
+ #if XFF_VIDEO > 1
+ XFF_PACKET_UNREF (this->avpkt);
+diff -r d1954d852980 -r 1e7b18400886 src/combined/ffmpeg/ffmpeg_compat.h
+--- a/src/combined/ffmpeg/ffmpeg_compat.h Mon Apr 08 13:25:10 2024 +0200
++++ b/src/combined/ffmpeg/ffmpeg_compat.h Mon May 06 21:55:55 2024 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2000-2022 the xine project
++ * Copyright (C) 2000-2024 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+@@ -54,9 +54,16 @@
+ #endif
+
+ /* reordered_opaque appeared in libavcodec 51.68.0 */
+-#define XFF_AVCODEC_REORDERED_OPAQUE
+-#if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(51,68,0)
+-# undef XFF_AVCODEC_REORDERED_OPAQUE
++#if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(51,68,0) && LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(60,0,0)
++# define XFF_AVCODEC_REORDERED_OPAQUE
++#else
++# undef XFF_AVCODEC_REORDERED_OPAQUE
++#endif
++
++#if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(58,33,100)
++# define XFF_AVCODEC_FRAME_PTS
++#else
++# undef XFF_AVCODEC_FRAME_PTS
+ #endif
+
+ /* colorspace and color_range were added before 52.29.0 */
+@@ -210,9 +217,11 @@
+ #endif
+
+ #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(55,63,100)
+-# define XFF_FREE_CONTEXT(pp) do {av_free(pp); pp = NULL;} while (0)
++# define XFF_FREE_CONTEXT(pp) do {if (pp) avcodec_close (pp); av_free (pp); pp = NULL;} while (0)
++#elif LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(58,33,100)
++# define XFF_FREE_CONTEXT(pp) do {if (pp) avcodec_close (pp); avcodec_free_context (&(pp));} while (0)
+ #else
+-# define XFF_FREE_CONTEXT(pp) avcodec_free_context(&(pp))
++# define XFF_FREE_CONTEXT(pp) avcodec_free_context (&(pp))
+ #endif
+
+ #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(54,59,100)
+@@ -303,4 +312,3 @@
+ #endif /* defined(LIBAVCODEC_VERSION_INT) */
+
+ #endif /* XINE_AVCODEC_COMPAT_H */
+-
+diff -r d1954d852980 -r 1e7b18400886 src/dxr3/ffmpeg_encoder.c
+--- a/src/dxr3/ffmpeg_encoder.c Mon Apr 08 13:25:10 2024 +0200
++++ b/src/dxr3/ffmpeg_encoder.c Mon May 06 21:55:55 2024 +0200
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2000-2022 the xine project
++ * Copyright (C) 2000-2024 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+@@ -127,10 +127,8 @@
+ unsigned char use_quantizer;
+
+ if (this->context) {
+- avcodec_close(this->context);
+- free(this->context);
++ XFF_FREE_CONTEXT (this->context);
+ free(this->picture);
+- this->context = NULL;
+ this->picture = NULL;
+ }
+
+@@ -344,10 +342,8 @@
+ #if XFF_ENCVIDEO > 1
+ XFF_PACKET_UNREF (this->pkt);
+ #endif
+- avcodec_close(this->context);
+ XFF_FREE_CONTEXT (this->context);
+ free(this->picture);
+- this->context = NULL;
+ this->picture = NULL;
+ }
+ return 1;
diff --git a/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg7-compatibility.patch b/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg7-compatibility.patch
new file mode 100644
index 000000000..136750404
--- /dev/null
+++ b/source/xap/xine-lib/xine-lib-1.2.13-ffmpeg7-compatibility.patch
@@ -0,0 +1,318 @@
+# HG changeset patch
+# User Torsten Jager <t.jager@gmx.de>
+# Date 1715160885 -7200
+# Wed May 08 11:34:45 2024 +0200
+# Node ID 73b833e7fe356cd2d9490dda4ebc9bfe16fce958
+# Parent 1e7b184008860c8be2289c3cefd9dee57f06193a
+ffmpeg compatibility update 2.
+
+diff -r 1e7b18400886 -r 73b833e7fe35 src/combined/ffmpeg/ff_audio_decoder.c
+--- a/src/combined/ffmpeg/ff_audio_decoder.c Mon May 06 21:55:55 2024 +0200
++++ b/src/combined/ffmpeg/ff_audio_decoder.c Wed May 08 11:34:45 2024 +0200
+@@ -1393,6 +1393,9 @@
+ XFF_FREE_FRAME (this->av_frame);
+ }
+ #endif
++#if 1
++ avcodec_flush_buffers (this->context);
++#else
+ pthread_mutex_lock (&ffmpeg_lock);
+ {
+ uint8_t *ed = this->context->extradata;
+@@ -1410,6 +1413,7 @@
+ if (XFF_AVCODEC_OPEN (this->context, this->codec) >= 0)
+ this->decoder_ok = 1;
+ pthread_mutex_unlock (&ffmpeg_lock);
++#endif
+ }
+
+ ff_audio_reset_parser(this);
+diff -r 1e7b18400886 -r 73b833e7fe35 src/combined/ffmpeg/ff_video_decoder.c
+--- a/src/combined/ffmpeg/ff_video_decoder.c Mon May 06 21:55:55 2024 +0200
++++ b/src/combined/ffmpeg/ff_video_decoder.c Wed May 08 11:34:45 2024 +0200
+@@ -89,6 +89,11 @@
+ # define ENABLE_EMMS
+ #endif
+
++/*
++#undef XFF_AVCODEC_SLICE_TABLE
++#define XFF_AVCODEC_SLICE_TABLE 1
++*/
++
+ #define VIDEOBUFSIZE (128*1024)
+ #define SLICE_BUFFER_SIZE (1194*1024)
+
+@@ -148,11 +153,11 @@
+ int bufsize;
+ int size;
+ int skipframes;
+-
++#if XFF_AVCODEC_SLICE_TABLE == 1
+ int *slice_offset_table;
+ int slice_offset_size;
+ int slice_offset_pos;
+-
++#endif
+ AVFrame *av_frame;
+ AVFrame *av_frame2;
+ AVCodecContext *context;
+@@ -238,6 +243,13 @@
+ #if XFF_VIDEO > 1
+ XFF_PACKET_DECL (avpkt);
+ #endif
++
++#if XFF_AVCODEC_SLICE_TABLE == 2
++ uint8_t *temp_buf;
++ uint32_t temp_size;
++ int slice_num;
++ uint8_t slice_table[1 + 256 * 8];
++#endif
+ };
+
+ /* import color matrix names */
+@@ -1783,10 +1795,9 @@
+ this->size += buf->size;
+
+ if (buf->decoder_flags & BUF_FLAG_FRAME_END) {
+- int codec_type;
++ uint32_t codec_type = buf->type & 0xFFFF0000;
+
+ lprintf ("header complete\n");
+- codec_type = buf->type & 0xFFFF0000;
+
+ if (buf->decoder_flags & BUF_FLAG_STDHEADER) {
+
+@@ -1912,33 +1923,44 @@
+ #endif
+ }
+ else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) {
+- /* o dear. Multiple decoding threads use individual contexts.
+- av_decode_video2 () does only copy the _pointer_ to the offsets,
+- not the offsets themselves. So we must not overwrite anything
+- that another thread has not yet read. */
+- int i, l, total;
+-
+- lprintf("BUF_SPECIAL_RV_CHUNK_TABLE\n");
+- l = buf->decoder_info[2] + 1;
+-
+- total = l * this->class->thread_count;
+- if (total < SLICE_OFFSET_SIZE)
+- total = SLICE_OFFSET_SIZE;
+- if (total > this->slice_offset_size) {
+- this->slice_offset_table = realloc (this->slice_offset_table, total * sizeof (int));
+- this->slice_offset_size = total;
+- }
+-
+- if (this->slice_offset_pos + l > this->slice_offset_size)
+- this->slice_offset_pos = 0;
+- this->context->slice_offset = this->slice_offset_table + this->slice_offset_pos;
+- this->context->slice_count = l;
+-
+- lprintf ("slice_count=%d\n", l);
+- for (i = 0; i < l; i++) {
+- this->slice_offset_table[this->slice_offset_pos++] =
+- ((uint32_t *)buf->decoder_info_ptr[2])[(2 * i) + 1];
+- lprintf("slice_offset[%d]=%d\n", i, this->context->slice_offset[i]);
++ {
++#if XFF_AVCODEC_SLICE_TABLE == 1
++ /* o dear. Multiple decoding threads use individual contexts.
++ * av_decode_video2 () does only copy the _pointer_ to the offsets,
++ * not the offsets themselves. So we must not overwrite anything
++ * that another thread has not yet read. */
++ int i, l, total;
++
++ lprintf("BUF_SPECIAL_RV_CHUNK_TABLE\n");
++ l = buf->decoder_info[2] + 1;
++
++ total = l * this->class->thread_count;
++ if (total < SLICE_OFFSET_SIZE)
++ total = SLICE_OFFSET_SIZE;
++ if (total > this->slice_offset_size) {
++ this->slice_offset_table = realloc (this->slice_offset_table, total * sizeof (int));
++ this->slice_offset_size = total;
++ }
++
++ if (this->slice_offset_pos + l > this->slice_offset_size)
++ this->slice_offset_pos = 0;
++ this->context->slice_offset = this->slice_offset_table + this->slice_offset_pos;
++ this->context->slice_count = l;
++
++ lprintf ("slice_count=%d\n", l);
++ for (i = 0; i < l; i++) {
++ this->slice_offset_table[this->slice_offset_pos++] =
++ ((uint32_t *)buf->decoder_info_ptr[2])[(2 * i) + 1];
++ lprintf("slice_offset[%d]=%d\n", i, this->context->slice_offset[i]);
++ }
++#elif XFF_AVCODEC_SLICE_TABLE == 2
++ /* (count-1):1, 1:4, (offs[0]):4, 1:4, (offs[1]:4, ... just in front of the frame bitstream.
++ * reverse engineered from ffmpeg/libavcodec/rv34.c. they seem to expect no
++ * external use of rv decoders, and did not document this. */
++ this->slice_table[0] = buf->decoder_info[2];
++ this->slice_num = this->slice_table[0] + 1;
++ memcpy (this->slice_table + 1, buf->decoder_info_ptr[2], 8 * this->slice_num);
++#endif
+ }
+ }
+ }
+@@ -2004,6 +2026,7 @@
+
+ static int decode_video_wrapper (ff_video_decoder_t *this,
+ AVFrame *av_frame, int *err, void *buf, size_t buf_size) {
++ uint32_t tsize = 0;
+ int len;
+
+ #if ENABLE_VAAPI
+@@ -2013,9 +2036,32 @@
+ }
+ #endif /* ENABLE_VAAPI */
+
++#if XFF_AVCODEC_SLICE_TABLE == 2
++ if ((this->slice_num > 0) && buf) {
++ uint32_t nsize;
++ tsize = 1 + this->slice_num * 8;
++ nsize = tsize + buf_size + AV_INPUT_BUFFER_PADDING_SIZE;
++ if (this->temp_size < nsize) {
++ nsize = nsize * 3 / 2;
++ free (this->temp_buf);
++ this->temp_buf = malloc (nsize);
++ if (!this->temp_buf)
++ nsize = 0;
++ this->temp_size = nsize;
++ nsize = tsize + buf_size + AV_INPUT_BUFFER_PADDING_SIZE;
++ }
++ if (this->temp_size >= nsize) {
++ memcpy (this->temp_buf, this->slice_table, tsize);
++ memcpy (this->temp_buf + tsize, buf, buf_size + AV_INPUT_BUFFER_PADDING_SIZE);
++ buf = this->temp_buf;
++ }
++ this->slice_num = 0;
++ }
++#endif
++
+ #if XFF_VIDEO > 1
+ this->avpkt->data = buf;
+- this->avpkt->size = buf_size;
++ this->avpkt->size = buf_size + tsize;
+ this->avpkt->flags = AV_PKT_FLAG_KEY;
+ # ifdef XFF_AVCODEC_FRAME_PTS
+ this->avpkt->pts = this->tagged_pts;
+@@ -2486,7 +2532,6 @@
+ this->size -= len;
+
+ if (this->size > 0) {
+- ff_check_bufsize(this, this->size);
+ memmove (this->buf, &chunk_buf[offset], this->size);
+ chunk_buf = this->buf;
+ /* take over pts for next access unit */
+@@ -2615,8 +2660,8 @@
+
+ img->pts = ff_untag_pts(this, this->av_frame);
+
+- /* workaround for weird 120fps streams */
+- if( video_step_to_use == 750 ) {
++ /* workaround for weird 120fps streams, as well as some rv20 with frame duration 3pts. */
++ if (video_step_to_use <= 750) {
+ /* fallback to the VIDEO_PTS_MODE */
+ video_step_to_use = 0;
+ }
+@@ -2837,7 +2882,7 @@
+
+ img->pts = ff_untag_pts (this, this->av_frame2);
+
+- if (video_step_to_use == 750)
++ if (video_step_to_use <= 750)
+ video_step_to_use = 0;
+ img->duration = this->av_frame2->repeat_pict ? video_step_to_use * 3 / 2 : video_step_to_use;
+ img->progressive_frame = !this->av_frame2->interlaced_frame;
+@@ -2941,6 +2986,9 @@
+ mpeg_parser_reset(this->mpeg_parser);
+
+ /* this->pts_tag_pass = 0; */
++#if XFF_AVCODEC_SLICE_TABLE == 2
++ this->slice_num = 0;
++#endif
+ }
+
+ static void ff_dispose (video_decoder_t *this_gen) {
+@@ -2953,12 +3001,15 @@
+ rgb2yuy2_free (this->rgb2yuy2);
+
+ if (this->decoder_ok) {
++ uint8_t *ed;
+
+ pthread_mutex_lock(&ffmpeg_lock);
+- _x_freep (&this->context->extradata);
++ ed = this->context->extradata;
++ this->context->extradata = NULL;
+ this->context->extradata_size = 0;
+ XFF_FREE_CONTEXT (this->context);
+ pthread_mutex_unlock(&ffmpeg_lock);
++ _x_freep (&ed);
+
+ #ifdef ENABLE_DIRECT_RENDERING
+ ff_free_dr1_frames (this, 1);
+@@ -2972,9 +3023,11 @@
+ XFF_FREE_CONTEXT (this->context);
+ }
+
+- if (this->slice_offset_table)
+- free (this->slice_offset_table);
+-
++#if XFF_AVCODEC_SLICE_TABLE == 1
++ free (this->slice_offset_table);
++#elif XFF_AVCODEC_SLICE_TABLE == 2
++ free (this->temp_buf);
++#endif
+
+ #if XFF_VIDEO > 1
+ XFF_PACKET_UNREF (this->avpkt);
+@@ -3062,21 +3115,25 @@
+ this->decoder_ok = 0;
+ this->aspect_ratio = 0;
+ this->pts_tag_pass = 0;
+-#ifdef HAVE_POSTPROC
++# ifdef HAVE_POSTPROC
+ this->pp_quality = 0;
+ this->our_context = NULL;
+ this->our_mode = NULL;
+-#endif
++# endif
+ this->mpeg_parser = NULL;
+ this->set_stream_info = 0;
+ this->rgb2yuy2 = NULL;
+-#ifdef ENABLE_VAAPI
++# ifdef ENABLE_VAAPI
+ this->accel = NULL;
+ this->accel_img = NULL;
+-#endif
+-#if XFF_VIDEO == 3
++# endif
++# if XFF_VIDEO == 3
+ this->flush_packet_sent = 0;
+-#endif
++# endif
++# if XFF_AVCODEC_SLICE_TABLE == 2
++ this->temp_size = 0;
++ this->temp_buf = NULL;
++# endif
+ #endif
+
+ this->video_decoder.decode_data = ff_decode_data;
+diff -r 1e7b18400886 -r 73b833e7fe35 src/combined/ffmpeg/ffmpeg_compat.h
+--- a/src/combined/ffmpeg/ffmpeg_compat.h Mon May 06 21:55:55 2024 +0200
++++ b/src/combined/ffmpeg/ffmpeg_compat.h Wed May 08 11:34:45 2024 +0200
+@@ -139,6 +139,14 @@
+ # define XFF_PALETTE 3
+ #endif
+
++#if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(59,42,100)
++/* AVCodecContext.slice_{offset,count} */
++# define XFF_AVCODEC_SLICE_TABLE 1
++#else
++/* inline offset table before the frame. */
++# define XFF_AVCODEC_SLICE_TABLE 2
++#endif
++
+ #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(59,0,100) /** << revise this */
+ # define XFF_VAAPI 1 /** << libavcodec/vaapi.h */
+ #else
diff --git a/source/xap/xine-lib/xine-lib-configure-c99.patch b/source/xap/xine-lib/xine-lib-configure-c99.patch
new file mode 100644
index 000000000..a6bf2e62f
--- /dev/null
+++ b/source/xap/xine-lib/xine-lib-configure-c99.patch
@@ -0,0 +1,116 @@
+configure: Add fake prototypes for C99 compatibility
+
+The xxmc-related configure probes assume that the compiler
+supports implicit function declarations because it tries to
+call the functions without including the appropriate headers,
+for link testing.
+
+As the headers are not determined yet at this point, use
+a fake prototype (the same that autoconf uses) to avoid
+the implicit function declarations.
+
+This avoids altering the outcome of these checks with future
+compilers which do not support implicit function declarations.
+
+Submitted upstream:
+
+ <https://sourceforge.net/p/xine/xine-lib-1.2/merge-requests/2/>
+
+diff --git a/configure b/configure
+index a4009e857777b5cf..3a83b40efda8fd5d 100755
+--- a/configure
++++ b/configure
+@@ -28563,7 +28563,7 @@ $as_echo "" >&6; }
+ LIBS="$XXMC_LIBS $X_LIBS $XV_LIBS $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-
++char XvMCPutSlice(void);
+ int
+ main ()
+ {
+@@ -28578,7 +28578,7 @@ else
+ LIBS="$XXMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS $DYNAMIC_LD_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-
++char XvMCPutSlice(void);
+ int
+ main ()
+ {
+@@ -28616,7 +28616,7 @@ done
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-
++char XvMCCreateContext(void);
+ int
+ main ()
+ {
+@@ -28631,7 +28631,7 @@ else
+ LIBS="$XXMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-
++char XvMCCreateContext(void);
+ int
+ main ()
+ {
+@@ -28675,7 +28675,7 @@ $as_echo "" >&6; }
+ LIBS="$XVMC_LIBS $X_LIBS $XV_LIBS $LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-
++char XvMCCreateContext(void);
+ int
+ main ()
+ {
+@@ -28690,7 +28690,7 @@ else
+ LIBS="$XVMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS $DYNAMIC_LD_LIBS"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ /* end confdefs.h. */
+-
++char XvMCCreateContext(void);
+ int
+ main ()
+ {
+diff --git a/m4/video_out.m4 b/m4/video_out.m4
+index 150b477697297c03..8aa1f4a3b9267ff9 100644
+--- a/m4/video_out.m4
++++ b/m4/video_out.m4
+@@ -496,9 +496,9 @@ AC_DEFUN([XINE_VIDEO_OUT_PLUGINS], [
+ AC_MSG_CHECKING([whether to enable the xxmc plugin with VLD extensions])
+ AC_MSG_RESULT([])
+ LIBS="$XXMC_LIBS $X_LIBS $XV_LIBS $LIBS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[XvMCPutSlice()]])], [have_xxmc=yes],
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCPutSlice(void);]], [[XvMCPutSlice()]])], [have_xxmc=yes],
+ [LIBS="$XXMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS $DYNAMIC_LD_LIBS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[XvMCPutSlice()]])],
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCPutSlice(void);]], [[XvMCPutSlice()]])],
+ [have_xxmc=yes XXMC_LIBS="$XXMC_LIBS -lXvMC"])])
+ if test x"$have_xxmc" = x"yes"; then
+ AC_CHECK_HEADERS([X11/extensions/vldXvMC.h],
+@@ -506,9 +506,9 @@ AC_DEFUN([XINE_VIDEO_OUT_PLUGINS], [
+ AC_DEFINE([HAVE_VLDXVMC], 1, [Define if you have vldXvMC.h])],
+ [have_vldexts=no])
+ else
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[XvMCCreateContext()]])], [have_xxmc=yes],
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCCreateContext(void);]], [[XvMCCreateContext()]])], [have_xxmc=yes],
+ [LIBS="$XXMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[XvMCCreateContext()]])],
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCCreateContext(void);]], [[XvMCCreateContext()]])],
+ [have_xxmc=yes XXMC_LIBS="$XXMC_LIBS -lXvMC"])])
+ fi
+ if test x"$have_xxmc" = x"yes"; then
+@@ -521,9 +521,9 @@ AC_DEFUN([XINE_VIDEO_OUT_PLUGINS], [
+ AC_MSG_CHECKING([whether to enable the xvmc plugin])
+ AC_MSG_RESULT([])
+ LIBS="$XVMC_LIBS $X_LIBS $XV_LIBS $LIBS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[XvMCCreateContext()]])], [have_xvmc=yes],
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCCreateContext(void);]], [[XvMCCreateContext()]])], [have_xvmc=yes],
+ [LIBS="$XVMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS $DYNAMIC_LD_LIBS"
+- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[XvMCCreateContext()]])],
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCCreateContext(void);]], [[XvMCCreateContext()]])],
+ [have_xvmc=yes XVMC_LIBS="$XVMC_LIBS -lXvMC"])])
+ if test x"$have_xvmc" = x"yes"; then
+ AC_CHECK_HEADERS([X11/extensions/XvMC.h], [], [have_xvmc=no])
diff --git a/source/xap/xine-lib/xine-lib.SlackBuild b/source/xap/xine-lib/xine-lib.SlackBuild
index f6b796fbc..806d9a30f 100755
--- a/source/xap/xine-lib/xine-lib.SlackBuild
+++ b/source/xap/xine-lib/xine-lib.SlackBuild
@@ -32,12 +32,12 @@ DIRVER=1.2.13
# Version used for the Slackware package
PKGVER=1.2.13
-BUILD=${BUILD:-7}
+BUILD=${BUILD:-8}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -51,7 +51,7 @@ NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
if [ "$ARCH" = "x86_64" ]; then
LIBDIRSUFFIX="64"
FFARCHOPTS="--arch=x86_64 --enable-pic"
-elif [ "$ARCH" = "i586" ]; then
+elif [ "$ARCH" = "i686" ]; then
LIBDIRSUFFIX=""
# 32bit x86 fails without this... let me know if you have a fix
FFARCHOPTS="--disable-asm"
@@ -93,6 +93,13 @@ find . \
# Fix build with binutils 2.39:
sed '/xine_set_flags/s/XINE_PROTECTED//' -i include/xine.h
+cat $CWD/xine-lib-1.2.13-ffmpeg6-compatibility.patch | patch -p1 --verbose || exit 1
+cat $CWD/xine-lib-1.2.13-ffmpeg6-compatibility_2.patch | patch -p1 --verbose || exit 1
+cat $CWD/xine-lib-1.2.13-ffmpeg7-compatibility.patch | patch -p1 --verbose || exit 1
+cat $CWD/xine-lib-configure-c99.patch | patch -p1 --verbose || exit 1
+
+autoreconf -vif || exit 1
+
XINE_BUILD=$TARGET \
./configure \
--prefix=/usr \
diff --git a/source/xap/xlockmore/xlockmore.SlackBuild b/source/xap/xlockmore/xlockmore.SlackBuild
index 25322d6c6..0abcdcf11 100755
--- a/source/xap/xlockmore/xlockmore.SlackBuild
+++ b/source/xap/xlockmore/xlockmore.SlackBuild
@@ -29,7 +29,7 @@ BUILD=${BUILD:-1}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -44,11 +44,8 @@ if [ ! -z "${PRINT_PACKAGE_NAME}" ]; then
exit 0
fi
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
SLKCFLAGS="-O2 -fPIC -lcrypt"
diff --git a/source/xap/xmms/xmms.SlackBuild b/source/xap/xmms/xmms.SlackBuild
index 63f4cbeda..2ee85e524 100755
--- a/source/xap/xmms/xmms.SlackBuild
+++ b/source/xap/xmms/xmms.SlackBuild
@@ -62,6 +62,9 @@ else
ARCHOPTS=""
fi
+# GCC^H^H^Hclang "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=implicit-function-declaration"
+
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
TMP=${TMP:-/tmp}
@@ -85,6 +88,7 @@ find . \
\( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
-exec chmod 644 {} \+
+CC=clang \
CFLAGS="$SLKCFLAGS" \
CXXFLAGS="$SLKCFLAGS" \
LIBS="-ldl" \
@@ -93,6 +97,7 @@ LIBS="-ldl" \
--libdir=/usr/lib${LIBDIRSUFFIX} \
--localstatedir=/var/lib \
--disable-static \
+ --disable-simd \
--enable-ipv6 \
$ARCHOPTS \
--build=$ARCH-slackware-linux || exit 1
diff --git a/source/xap/xsane/xsane.SlackBuild b/source/xap/xsane/xsane.SlackBuild
index 4f71ff8cf..0a3d9fb96 100755
--- a/source/xap/xsane/xsane.SlackBuild
+++ b/source/xap/xsane/xsane.SlackBuild
@@ -63,6 +63,9 @@ else
LIBDIRSUFFIX=""
fi
+# GCC 14 "fix":
+SLKCFLAGS="$SLKCFLAGS -Wno-error=implicit-function-declaration"
+
rm -rf $PKG
mkdir -p $TMP $PKG
cd $TMP
diff --git a/source/xap/xscreensaver/xscreensaver.SlackBuild b/source/xap/xscreensaver/xscreensaver.SlackBuild
index ffc957672..c108fe9fe 100755
--- a/source/xap/xscreensaver/xscreensaver.SlackBuild
+++ b/source/xap/xscreensaver/xscreensaver.SlackBuild
@@ -29,7 +29,7 @@ BUILD=${BUILD:-2}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then
case "$( uname -m )" in
- i?86) export ARCH=i586 ;;
+ i?86) export ARCH=i686 ;;
arm*) export ARCH=arm ;;
# Unless $ARCH is already set, use uname -m for all other archs:
*) export ARCH=$( uname -m ) ;;
@@ -46,14 +46,11 @@ fi
NUMJOBS=${NUMJOBS:-" -j$(expr $(nproc) + 1) "}
-if [ "$ARCH" = "i586" ]; then
- SLKCFLAGS="-O2 -march=i586 -mtune=i686"
- LIBDIRSUFFIX=""
-elif [ "$ARCH" = "s390" ]; then
- SLKCFLAGS="-O2"
+if [ "$ARCH" = "i686" ]; then
+ SLKCFLAGS="-O2 -march=pentium4 -mtune=generic"
LIBDIRSUFFIX=""
elif [ "$ARCH" = "x86_64" ]; then
- SLKCFLAGS="-O2 -fPIC"
+ SLKCFLAGS="-O2 -march=x86-64 -mtune=generic -fPIC"
LIBDIRSUFFIX="64"
else
SLKCFLAGS="-O2"
@@ -71,20 +68,6 @@ rm -rf xscreensaver-$VERSION
tar xvf $CWD/xscreensaver-$VERSION.tar.?z || exit 1
cd xscreensaver-$VERSION
-if [ -L /lib${LIBDIRSUFFIX}/libpam.so.? ]; then
- USE_PAM="--with-pam"
- unset USE_SHADOW
-else
- ## NOTE: The patch below (and support for setgid shadow) is broken and
- ## unmaintained. But the broken bits will be left as hints for anyone
- ## down the line who might care.
- # Allow xscreensaver to work setgid shadow. I'd rather avoid requiring
- # setuid root on this if at all possible...
- #zcat $CWD/xscreensaver.setuid.diff.gz | patch -p1 --verbose --backup --suffix=.orig || exit 1
- unset USE_PAM
- USE_SHADOW="--with-shadow"
-fi
-
# Add support for the electricsheep distributed screensaver:
zcat $CWD/xscreensaver.electricsheep.diff.gz | patch -p1 --verbose --backup --suffix=.orig || exit 1
@@ -110,8 +93,7 @@ CXXFLAGS="$SLKCFLAGS" \
--mandir=/usr/man \
--with-app-defaults=/etc/X11/app-defaults \
--with-text-file=/usr/doc/netdate/COPYRIGHT \
- $USE_SHADOW \
- $USE_PAM \
+ --with-pam \
--without-kerberos \
--with-jpeg \
--with-gl \
@@ -121,22 +103,10 @@ CXXFLAGS="$SLKCFLAGS" \
make $NUMJOBS || make || exit 1
make install_prefix=$PKG install-strip || exit 1
-if [ -z $USE_PAM ]; then
- # Needed for password unlock:
- chown root:shadow $PKG/usr/bin/xscreensaver
- chmod 2751 $PKG/usr/bin/xscreensaver
-else
- ## Commenting out the chmod below, since as of v6.00 this binary is no longer
- ## made setuid at installation. But if that changes, we'll go along with it
- ## since jwz says it may be required to prevent OOM killer abuse from
- ## unlocking the screen.
- # No special perms needed with PAM:
- #chmod 755 $PKG/usr/bin/xscreensaver
- mkdir -p $PKG/etc/pam.d
- cat $CWD/xscreensaver.pam > $PKG/etc/pam.d/xscreensaver.new
- mkdir -p $PKG/install
- zcat $CWD/doinst.sh.gz > $PKG/install/doinst.sh
-fi
+# No special perms needed with PAM:
+#chmod 755 $PKG/usr/bin/xscreensaver
+mkdir -p $PKG/etc/pam.d
+cat $CWD/xscreensaver.pam > $PKG/etc/pam.d/xscreensaver.new
# This is needed for the menus:
mkdir -p $PKG/usr/share/pixmaps
@@ -168,6 +138,7 @@ fi
cat $CWD/xscreensaver-getimage-file-5.14 > $PKG/usr/bin/xscreensaver-getimage-file
mkdir -p $PKG/install
+zcat $CWD/doinst.sh.gz > $PKG/install/doinst.sh
cat $CWD/slack-desc > $PKG/install/slack-desc
cd $PKG
diff --git a/source/xap/xscreensaver/xscreensaver.setuid.diff b/source/xap/xscreensaver/xscreensaver.setuid.diff
deleted file mode 100644
index c6810af55..000000000
--- a/source/xap/xscreensaver/xscreensaver.setuid.diff
+++ /dev/null
@@ -1,179 +0,0 @@
---- ./driver/setuid.c.orig 2006-02-08 20:28:38.000000000 -0600
-+++ ./driver/setuid.c 2006-04-04 16:48:08.000000000 -0500
-@@ -1,5 +1,5 @@
- /* setuid.c --- management of runtime privileges.
-- * xscreensaver, Copyright (c) 1993-1998, 2005 Jamie Zawinski <jwz@jwz.org>
-+ * xscreensaver, Copyright (c) 1993-1998 Jamie Zawinski <jwz@jwz.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
-@@ -41,7 +41,7 @@
- struct group *g = 0;
- p = getpwuid (uid);
- g = getgrgid (gid);
-- sprintf (buf, "%.100s/%.100s (%ld/%ld)",
-+ sprintf (buf, "%s/%s (%ld/%ld)",
- (p && p->pw_name ? p->pw_name : "???"),
- (g && g->gr_name ? g->gr_name : "???"),
- (long) uid, (long) gid);
-@@ -74,50 +74,11 @@
- }
-
-
--/* Returns true if we need to call setgroups().
--
-- Without calling setgroups(), the process will retain any supplementary
-- gids associated with the uid, e.g.:
--
-- % groups root
-- root : root bin daemon sys adm disk wheel
--
-- However, setgroups() can only be called by root, and returns EPERM
-- for other users even if the call would be a no-op (e.g., setting the
-- group list to the current list.) So, to avoid that spurious error,
-- before calling setgroups() we first check whether the current list
-- of groups contains only one element, our target group. If so, we
-- don't need to call setgroups().
-- */
--static int
--setgroups_needed_p (uid_t target_group)
--{
-- gid_t groups[1024];
-- int n, size;
-- size = sizeof(groups) / sizeof(gid_t);
-- n = getgroups (size - 1, groups);
-- if (n < 0)
-- {
-- char buf [1024];
-- sprintf (buf, "%s: getgroups(%ld, ...)", blurb(), (long int)(size - 1));
-- perror (buf);
-- return 1;
-- }
-- else if (n == 0) /* an empty list means only egid is in effect. */
-- return 0;
-- else if (n == 1 && groups[0] == target_group) /* one element, the target */
-- return 0;
-- else /* more than one, or the wrong one. */
-- return 1;
--}
--
--
- static int
- set_ids_by_number (uid_t uid, gid_t gid, char **message_ret)
- {
- int uid_errno = 0;
- int gid_errno = 0;
-- int sgs_errno = 0;
- struct passwd *p = getpwuid (uid);
- struct group *g = getgrgid (gid);
-
-@@ -136,11 +97,6 @@
- if (uid == (uid_t) -1) uid = (uid_t) -2;
-
- errno = 0;
-- if (setgroups_needed_p (gid) &&
-- setgroups (1, &gid) < 0)
-- sgs_errno = errno ? errno : -1;
--
-- errno = 0;
- if (setgid (gid) != 0)
- gid_errno = errno ? errno : -1;
-
-@@ -148,10 +104,10 @@
- if (setuid (uid) != 0)
- uid_errno = errno ? errno : -1;
-
-- if (uid_errno == 0 && gid_errno == 0 && sgs_errno == 0)
-+ if (uid_errno == 0 && gid_errno == 0)
- {
- static char buf [1024];
-- sprintf (buf, "changed uid/gid to %.100s/%.100s (%ld/%ld).",
-+ sprintf (buf, "changed uid/gid to %s/%s (%ld/%ld).",
- (p && p->pw_name ? p->pw_name : "???"),
- (g && g->gr_name ? g->gr_name : "???"),
- (long) uid, (long) gid);
-@@ -162,71 +118,28 @@
- else
- {
- char buf [1024];
-- gid_t groups[1024];
-- int n, size;
--
-- if (sgs_errno)
-- {
-- sprintf (buf, "%s: couldn't setgroups to %.100s (%ld)",
-- blurb(),
-- (g && g->gr_name ? g->gr_name : "???"),
-- (long) gid);
-- if (sgs_errno == -1)
-- fprintf(stderr, "%s: unknown error\n", buf);
-- else
-- {
-- errno = sgs_errno;
-- perror(buf);
-- }
--
-- fprintf (stderr, "%s: effective group list: ", blurb());
-- size = sizeof(groups) / sizeof(gid_t);
-- n = getgroups (size - 1, groups);
-- if (n < 0)
-- fprintf (stderr, "unknown!\n");
-- else
-- {
-- int i;
-- fprintf (stderr, "[");
-- for (i = 0; i < n; i++)
-- {
-- g = getgrgid (groups[i]);
-- if (i > 0) fprintf (stderr, ", ");
-- if (g && g->gr_name) fprintf (stderr, "%s", g->gr_name);
-- else fprintf (stderr, "%ld", (long) groups[i]);
-- }
-- fprintf (stderr, "]\n");
-- }
-- }
--
- if (gid_errno)
- {
-- sprintf (buf, "%s: couldn't set gid to %.100s (%ld)",
-+ sprintf (buf, "%s: couldn't set gid to %s (%ld)",
- blurb(),
- (g && g->gr_name ? g->gr_name : "???"),
- (long) gid);
- if (gid_errno == -1)
- fprintf(stderr, "%s: unknown error\n", buf);
- else
-- {
-- errno = gid_errno;
-- perror(buf);
-- }
-+ perror(buf);
- }
-
- if (uid_errno)
- {
-- sprintf (buf, "%s: couldn't set uid to %.100s (%ld)",
-+ sprintf (buf, "%s: couldn't set uid to %s (%ld)",
- blurb(),
- (p && p->pw_name ? p->pw_name : "???"),
- (long) uid);
- if (uid_errno == -1)
- fprintf(stderr, "%s: unknown error\n", buf);
- else
-- {
-- errno = uid_errno;
-- perror(buf);
-- }
-+ perror(buf);
- }
-
- return -1;
-@@ -350,7 +263,7 @@
- !strcmp (p->pw_name, "games"))
- {
- static char buf [1024];
-- sprintf (buf, "running as %.100s",
-+ sprintf (buf, "running as %s",
- (p && p->pw_name && *p->pw_name
- ? p->pw_name : "<unknown>"));
- si->nolock_reason = buf;
diff --git a/source/xap/xsnow/xsnow.SlackBuild b/source/xap/xsnow/xsnow.SlackBuild
index def5c0d2f..dc4f87749 100755
--- a/source/xap/xsnow/xsnow.SlackBuild
+++ b/source/xap/xsnow/xsnow.SlackBuild
@@ -24,7 +24,7 @@ cd $(dirname $0) ; CWD=$(pwd)
PKGNAM=xsnow
VERSION=${VERSION:-$(echo $PKGNAM-*.tar.?z | rev | cut -f 3- -d . | cut -f 1 -d - | rev)}
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
# Automatically determine the architecture we're building on:
if [ -z "$ARCH" ]; then