diff options
Diffstat (limited to 'source/xap')
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 |