diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 1cacf53..a0d0b79 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -2,7 +2,7 @@ name: Publish Assets
on:
push:
- branches: [master]
+ branches: [master, upgrade_p4a]
jobs:
build_arm64_aar:
@@ -20,16 +20,19 @@ jobs:
echo "NEXUS_SIGNING_KEYRING_FILE=$GITHUB_WORKSPACE/signing2.pgp" >> $GITHUB_ENV
echo "BUILD_VERSION=${B_VERSION}" >> $GITHUB_ENV
export PATH=/usr/bin:$PATH
- wget -q 'https://eu.crystax.net/download/crystax-ndk-10.3.2-linux-x86_64.tar.xz' -P ~/.buildozer/android/
- tar -xf ~/.buildozer/android/crystax-ndk-10.3.2-linux-x86_64.tar.xz -C ~/.buildozer/android/
- rm -rf ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-9
- ln -s ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-21 ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-9
- cp -f $GITHUB_WORKSPACE/scripts/build-target-python.sh ~/.buildozer/android/crystax-ndk-10.3.2/build/tools/build-target-python.sh
- cp -f $GITHUB_WORKSPACE/scripts/mangled-glibc-syscalls__arm64.h ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-21/arch-arm64/usr/include/crystax/bionic/libc/include/sys/mangled-glibc-syscalls.h
- cp -f $GITHUB_WORKSPACE/scripts/build-binary.mk ~/.buildozer/android/crystax-ndk-10.3.2/build/core/build-binary.mk
- rm -rf ~/.buildozer/android/crystax-ndk-10.3.2/sources/sqlite
- cp -Rf $GITHUB_WORKSPACE/scripts/crystax-sources/sqlite ~/.buildozer/android/crystax-ndk-10.3.2/sources/sqlite
- rm ~/.buildozer/android/crystax-ndk-10.3.2-linux-x86_64.tar.xz
+ wget -q 'https://dl.google.com/android/repository/android-ndk-r23c-linux.zip' -P ~/.buildozer/android/
+ unzip ~/.buildozer/android/android-ndk-r23c-linux.zip -d ~/.buildozer/android/
+
+# wget -q 'https://eu.crystax.net/download/crystax-ndk-10.3.2-linux-x86_64.tar.xz' -P ~/.buildozer/android/
+# tar -xf ~/.buildozer/android/crystax-ndk-10.3.2-linux-x86_64.tar.xz -C ~/.buildozer/android/
+# rm -rf ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-9
+# ln -s ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-21 ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-9
+# cp -f $GITHUB_WORKSPACE/scripts/build-target-python.sh ~/.buildozer/android/crystax-ndk-10.3.2/build/tools/build-target-python.sh
+# cp -f $GITHUB_WORKSPACE/scripts/mangled-glibc-syscalls__arm64.h ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-21/arch-arm64/usr/include/crystax/bionic/libc/include/sys/mangled-glibc-syscalls.h
+# cp -f $GITHUB_WORKSPACE/scripts/build-binary.mk ~/.buildozer/android/crystax-ndk-10.3.2/build/core/build-binary.mk
+# rm -rf ~/.buildozer/android/crystax-ndk-10.3.2/sources/sqlite
+# cp -Rf $GITHUB_WORKSPACE/scripts/crystax-sources/sqlite ~/.buildozer/android/crystax-ndk-10.3.2/sources/sqlite
+# rm ~/.buildozer/android/crystax-ndk-10.3.2-linux-x86_64.tar.xz
mv buildozer.spec.arm64.ci buildozer.spec
chmod u+x ./build-release.sh
- name: build release
@@ -77,6 +80,7 @@ jobs:
echo "NEXUS_SIGNING_KEYRING_FILE=$GITHUB_WORKSPACE/signing2.pgp" >> $GITHUB_ENV
export PATH=/usr/bin:$PATH
wget -q 'https://eu.crystax.net/download/crystax-ndk-10.3.2-linux-x86_64.tar.xz' -P ~/.buildozer/android/
+ unzip ~/
tar -xf ~/.buildozer/android/crystax-ndk-10.3.2-linux-x86_64.tar.xz -C ~/.buildozer/android/
rm -rf ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-9
ln -s ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-21 ~/.buildozer/android/crystax-ndk-10.3.2/platforms/android-9
diff --git a/MovedRecipes/__init__.py b/MovedRecipes/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/recipes/cryptography/__init__.py b/MovedRecipes/cryptography/__init__.py
similarity index 100%
rename from recipes/cryptography/__init__.py
rename to MovedRecipes/cryptography/__init__.py
diff --git a/recipes/cryptography/libpthread.patch b/MovedRecipes/cryptography/libpthread.patch
similarity index 100%
rename from recipes/cryptography/libpthread.patch
rename to MovedRecipes/cryptography/libpthread.patch
diff --git a/recipes/hostpython3crystax/__init__.py b/MovedRecipes/hostpython3crystax/__init__.py
similarity index 100%
rename from recipes/hostpython3crystax/__init__.py
rename to MovedRecipes/hostpython3crystax/__init__.py
diff --git a/recipes/libffi/Application.mk b/MovedRecipes/libffi/Application.mk
similarity index 100%
rename from recipes/libffi/Application.mk
rename to MovedRecipes/libffi/Application.mk
diff --git a/recipes/libffi/__init__.py b/MovedRecipes/libffi/__init__.py
similarity index 100%
rename from recipes/libffi/__init__.py
rename to MovedRecipes/libffi/__init__.py
diff --git a/recipes/libffi/disable-mips-check.patch b/MovedRecipes/libffi/disable-mips-check.patch
similarity index 100%
rename from recipes/libffi/disable-mips-check.patch
rename to MovedRecipes/libffi/disable-mips-check.patch
diff --git a/recipes/libffi/fix-includedir.patch b/MovedRecipes/libffi/fix-includedir.patch
similarity index 100%
rename from recipes/libffi/fix-includedir.patch
rename to MovedRecipes/libffi/fix-includedir.patch
diff --git a/recipes/libffi/remove-version-info.patch b/MovedRecipes/libffi/remove-version-info.patch
similarity index 100%
rename from recipes/libffi/remove-version-info.patch
rename to MovedRecipes/libffi/remove-version-info.patch
diff --git a/recipes/libsecp256k1/__init__.py b/MovedRecipes/libsecp256k1/__init__.py
similarity index 100%
rename from recipes/libsecp256k1/__init__.py
rename to MovedRecipes/libsecp256k1/__init__.py
diff --git a/recipes/netifaces/__init__.py b/MovedRecipes/netifaces/__init__.py
similarity index 100%
rename from recipes/netifaces/__init__.py
rename to MovedRecipes/netifaces/__init__.py
diff --git a/recipes/netifaces/socket-ioctls.patch b/MovedRecipes/netifaces/socket-ioctls.patch
similarity index 100%
rename from recipes/netifaces/socket-ioctls.patch
rename to MovedRecipes/netifaces/socket-ioctls.patch
diff --git a/recipes/openssl/__init__.py b/MovedRecipes/openssl/__init__.py
similarity index 100%
rename from recipes/openssl/__init__.py
rename to MovedRecipes/openssl/__init__.py
diff --git a/recipes/openssl/disable-sover.patch b/MovedRecipes/openssl/disable-sover.patch
similarity index 100%
rename from recipes/openssl/disable-sover.patch
rename to MovedRecipes/openssl/disable-sover.patch
diff --git a/recipes/openssl/rename-shared-lib.patch b/MovedRecipes/openssl/rename-shared-lib.patch
similarity index 100%
rename from recipes/openssl/rename-shared-lib.patch
rename to MovedRecipes/openssl/rename-shared-lib.patch
diff --git a/recipes/pyjnius/__init__.py b/MovedRecipes/pyjnius/__init__.py
similarity index 100%
rename from recipes/pyjnius/__init__.py
rename to MovedRecipes/pyjnius/__init__.py
diff --git a/recipes/pyjnius/genericndkbuild_jnienv_getter.patch b/MovedRecipes/pyjnius/genericndkbuild_jnienv_getter.patch
similarity index 100%
rename from recipes/pyjnius/genericndkbuild_jnienv_getter.patch
rename to MovedRecipes/pyjnius/genericndkbuild_jnienv_getter.patch
diff --git a/recipes/pyjnius/sdl2_jnienv_getter.patch b/MovedRecipes/pyjnius/sdl2_jnienv_getter.patch
similarity index 100%
rename from recipes/pyjnius/sdl2_jnienv_getter.patch
rename to MovedRecipes/pyjnius/sdl2_jnienv_getter.patch
diff --git a/recipes/python3crystax/__init__.py b/MovedRecipes/python3crystax/__init__.py
similarity index 100%
rename from recipes/python3crystax/__init__.py
rename to MovedRecipes/python3crystax/__init__.py
diff --git a/recipes/python3crystax/android.mk.3.9 b/MovedRecipes/python3crystax/android.mk.3.9
similarity index 100%
rename from recipes/python3crystax/android.mk.3.9
rename to MovedRecipes/python3crystax/android.mk.3.9
diff --git a/recipes/python3crystax/config.c.3.9 b/MovedRecipes/python3crystax/config.c.3.9
similarity index 100%
rename from recipes/python3crystax/config.c.3.9
rename to MovedRecipes/python3crystax/config.c.3.9
diff --git a/recipes/python3crystax/interpreter.c.3.9 b/MovedRecipes/python3crystax/interpreter.c.3.9
similarity index 100%
rename from recipes/python3crystax/interpreter.c.3.9
rename to MovedRecipes/python3crystax/interpreter.c.3.9
diff --git a/recipes/python3crystax/libffi/ChangeLog b/MovedRecipes/python3crystax/libffi/ChangeLog
similarity index 100%
rename from recipes/python3crystax/libffi/ChangeLog
rename to MovedRecipes/python3crystax/libffi/ChangeLog
diff --git a/recipes/python3crystax/libffi/ChangeLog.libffi b/MovedRecipes/python3crystax/libffi/ChangeLog.libffi
similarity index 100%
rename from recipes/python3crystax/libffi/ChangeLog.libffi
rename to MovedRecipes/python3crystax/libffi/ChangeLog.libffi
diff --git a/recipes/python3crystax/libffi/ChangeLog.libffi-3.1 b/MovedRecipes/python3crystax/libffi/ChangeLog.libffi-3.1
similarity index 100%
rename from recipes/python3crystax/libffi/ChangeLog.libffi-3.1
rename to MovedRecipes/python3crystax/libffi/ChangeLog.libffi-3.1
diff --git a/recipes/python3crystax/libffi/ChangeLog.libgcj b/MovedRecipes/python3crystax/libffi/ChangeLog.libgcj
similarity index 100%
rename from recipes/python3crystax/libffi/ChangeLog.libgcj
rename to MovedRecipes/python3crystax/libffi/ChangeLog.libgcj
diff --git a/recipes/python3crystax/libffi/ChangeLog.v1 b/MovedRecipes/python3crystax/libffi/ChangeLog.v1
similarity index 100%
rename from recipes/python3crystax/libffi/ChangeLog.v1
rename to MovedRecipes/python3crystax/libffi/ChangeLog.v1
diff --git a/recipes/python3crystax/libffi/LICENSE b/MovedRecipes/python3crystax/libffi/LICENSE
similarity index 100%
rename from recipes/python3crystax/libffi/LICENSE
rename to MovedRecipes/python3crystax/libffi/LICENSE
diff --git a/recipes/python3crystax/libffi/Makefile.am b/MovedRecipes/python3crystax/libffi/Makefile.am
similarity index 100%
rename from recipes/python3crystax/libffi/Makefile.am
rename to MovedRecipes/python3crystax/libffi/Makefile.am
diff --git a/recipes/python3crystax/libffi/Makefile.in b/MovedRecipes/python3crystax/libffi/Makefile.in
similarity index 100%
rename from recipes/python3crystax/libffi/Makefile.in
rename to MovedRecipes/python3crystax/libffi/Makefile.in
diff --git a/recipes/python3crystax/libffi/README b/MovedRecipes/python3crystax/libffi/README
similarity index 100%
rename from recipes/python3crystax/libffi/README
rename to MovedRecipes/python3crystax/libffi/README
diff --git a/MovedRecipes/python3crystax/libffi/__init__.py b/MovedRecipes/python3crystax/libffi/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/recipes/python3crystax/libffi/acinclude.m4 b/MovedRecipes/python3crystax/libffi/acinclude.m4
similarity index 100%
rename from recipes/python3crystax/libffi/acinclude.m4
rename to MovedRecipes/python3crystax/libffi/acinclude.m4
diff --git a/recipes/python3crystax/libffi/aclocal.m4 b/MovedRecipes/python3crystax/libffi/aclocal.m4
similarity index 100%
rename from recipes/python3crystax/libffi/aclocal.m4
rename to MovedRecipes/python3crystax/libffi/aclocal.m4
diff --git a/recipes/python3crystax/libffi/compile b/MovedRecipes/python3crystax/libffi/compile
similarity index 100%
rename from recipes/python3crystax/libffi/compile
rename to MovedRecipes/python3crystax/libffi/compile
diff --git a/recipes/python3crystax/libffi/config.guess b/MovedRecipes/python3crystax/libffi/config.guess
similarity index 100%
rename from recipes/python3crystax/libffi/config.guess
rename to MovedRecipes/python3crystax/libffi/config.guess
diff --git a/recipes/python3crystax/libffi/config.sub b/MovedRecipes/python3crystax/libffi/config.sub
similarity index 100%
rename from recipes/python3crystax/libffi/config.sub
rename to MovedRecipes/python3crystax/libffi/config.sub
diff --git a/recipes/python3crystax/libffi/configure b/MovedRecipes/python3crystax/libffi/configure
similarity index 100%
rename from recipes/python3crystax/libffi/configure
rename to MovedRecipes/python3crystax/libffi/configure
diff --git a/recipes/python3crystax/libffi/configure.ac b/MovedRecipes/python3crystax/libffi/configure.ac
similarity index 100%
rename from recipes/python3crystax/libffi/configure.ac
rename to MovedRecipes/python3crystax/libffi/configure.ac
diff --git a/recipes/python3crystax/libffi/depcomp b/MovedRecipes/python3crystax/libffi/depcomp
similarity index 100%
rename from recipes/python3crystax/libffi/depcomp
rename to MovedRecipes/python3crystax/libffi/depcomp
diff --git a/recipes/python3crystax/libffi/doc/libffi.info b/MovedRecipes/python3crystax/libffi/doc/libffi.info
similarity index 100%
rename from recipes/python3crystax/libffi/doc/libffi.info
rename to MovedRecipes/python3crystax/libffi/doc/libffi.info
diff --git a/recipes/python3crystax/libffi/doc/libffi.texi b/MovedRecipes/python3crystax/libffi/doc/libffi.texi
similarity index 100%
rename from recipes/python3crystax/libffi/doc/libffi.texi
rename to MovedRecipes/python3crystax/libffi/doc/libffi.texi
diff --git a/recipes/python3crystax/libffi/doc/stamp-vti b/MovedRecipes/python3crystax/libffi/doc/stamp-vti
similarity index 100%
rename from recipes/python3crystax/libffi/doc/stamp-vti
rename to MovedRecipes/python3crystax/libffi/doc/stamp-vti
diff --git a/recipes/python3crystax/libffi/doc/version.texi b/MovedRecipes/python3crystax/libffi/doc/version.texi
similarity index 100%
rename from recipes/python3crystax/libffi/doc/version.texi
rename to MovedRecipes/python3crystax/libffi/doc/version.texi
diff --git a/recipes/python3crystax/libffi/fficonfig.h.in b/MovedRecipes/python3crystax/libffi/fficonfig.h.in
similarity index 100%
rename from recipes/python3crystax/libffi/fficonfig.h.in
rename to MovedRecipes/python3crystax/libffi/fficonfig.h.in
diff --git a/recipes/python3crystax/libffi/fficonfig.py.in b/MovedRecipes/python3crystax/libffi/fficonfig.py.in
similarity index 100%
rename from recipes/python3crystax/libffi/fficonfig.py.in
rename to MovedRecipes/python3crystax/libffi/fficonfig.py.in
diff --git a/recipes/python3crystax/libffi/generate-darwin-source-and-headers.py b/MovedRecipes/python3crystax/libffi/generate-darwin-source-and-headers.py
similarity index 100%
rename from recipes/python3crystax/libffi/generate-darwin-source-and-headers.py
rename to MovedRecipes/python3crystax/libffi/generate-darwin-source-and-headers.py
diff --git a/recipes/python3crystax/libffi/include/Makefile.am b/MovedRecipes/python3crystax/libffi/include/Makefile.am
similarity index 100%
rename from recipes/python3crystax/libffi/include/Makefile.am
rename to MovedRecipes/python3crystax/libffi/include/Makefile.am
diff --git a/recipes/python3crystax/libffi/include/Makefile.in b/MovedRecipes/python3crystax/libffi/include/Makefile.in
similarity index 100%
rename from recipes/python3crystax/libffi/include/Makefile.in
rename to MovedRecipes/python3crystax/libffi/include/Makefile.in
diff --git a/recipes/python3crystax/libffi/include/ffi.h.in b/MovedRecipes/python3crystax/libffi/include/ffi.h.in
similarity index 100%
rename from recipes/python3crystax/libffi/include/ffi.h.in
rename to MovedRecipes/python3crystax/libffi/include/ffi.h.in
diff --git a/recipes/python3crystax/libffi/include/ffi_common.h b/MovedRecipes/python3crystax/libffi/include/ffi_common.h
similarity index 100%
rename from recipes/python3crystax/libffi/include/ffi_common.h
rename to MovedRecipes/python3crystax/libffi/include/ffi_common.h
diff --git a/recipes/python3crystax/libffi/install-sh b/MovedRecipes/python3crystax/libffi/install-sh
similarity index 100%
rename from recipes/python3crystax/libffi/install-sh
rename to MovedRecipes/python3crystax/libffi/install-sh
diff --git a/recipes/python3crystax/libffi/libffi.pc.in b/MovedRecipes/python3crystax/libffi/libffi.pc.in
similarity index 100%
rename from recipes/python3crystax/libffi/libffi.pc.in
rename to MovedRecipes/python3crystax/libffi/libffi.pc.in
diff --git a/recipes/python3crystax/libffi/libffi.xcodeproj/project.pbxproj b/MovedRecipes/python3crystax/libffi/libffi.xcodeproj/project.pbxproj
similarity index 100%
rename from recipes/python3crystax/libffi/libffi.xcodeproj/project.pbxproj
rename to MovedRecipes/python3crystax/libffi/libffi.xcodeproj/project.pbxproj
diff --git a/recipes/python3crystax/libffi/libtool-ldflags b/MovedRecipes/python3crystax/libffi/libtool-ldflags
similarity index 100%
rename from recipes/python3crystax/libffi/libtool-ldflags
rename to MovedRecipes/python3crystax/libffi/libtool-ldflags
diff --git a/recipes/python3crystax/libffi/libtool-version b/MovedRecipes/python3crystax/libffi/libtool-version
similarity index 100%
rename from recipes/python3crystax/libffi/libtool-version
rename to MovedRecipes/python3crystax/libffi/libtool-version
diff --git a/recipes/python3crystax/libffi/ltmain.sh b/MovedRecipes/python3crystax/libffi/ltmain.sh
similarity index 100%
rename from recipes/python3crystax/libffi/ltmain.sh
rename to MovedRecipes/python3crystax/libffi/ltmain.sh
diff --git a/recipes/python3crystax/libffi/m4/asmcfi.m4 b/MovedRecipes/python3crystax/libffi/m4/asmcfi.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/asmcfi.m4
rename to MovedRecipes/python3crystax/libffi/m4/asmcfi.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_append_flag.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_append_flag.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_append_flag.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_append_flag.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_cc_maxopt.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_cc_maxopt.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_cc_maxopt.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_cc_maxopt.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_cflags_warn_all.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_cflags_warn_all.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_cflags_warn_all.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_cflags_warn_all.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_check_compile_flag.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_check_compile_flag.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_check_compile_flag.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_check_compile_flag.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_compiler_vendor.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_compiler_vendor.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_compiler_vendor.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_compiler_vendor.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_configure_args.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_configure_args.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_configure_args.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_configure_args.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_enable_builddir.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_enable_builddir.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_enable_builddir.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_enable_builddir.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_gcc_archflag.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_gcc_archflag.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_gcc_archflag.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_gcc_archflag.m4
diff --git a/recipes/python3crystax/libffi/m4/ax_gcc_x86_cpuid.m4 b/MovedRecipes/python3crystax/libffi/m4/ax_gcc_x86_cpuid.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ax_gcc_x86_cpuid.m4
rename to MovedRecipes/python3crystax/libffi/m4/ax_gcc_x86_cpuid.m4
diff --git a/recipes/python3crystax/libffi/m4/libtool.m4 b/MovedRecipes/python3crystax/libffi/m4/libtool.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/libtool.m4
rename to MovedRecipes/python3crystax/libffi/m4/libtool.m4
diff --git a/recipes/python3crystax/libffi/m4/ltoptions.m4 b/MovedRecipes/python3crystax/libffi/m4/ltoptions.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ltoptions.m4
rename to MovedRecipes/python3crystax/libffi/m4/ltoptions.m4
diff --git a/recipes/python3crystax/libffi/m4/ltsugar.m4 b/MovedRecipes/python3crystax/libffi/m4/ltsugar.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ltsugar.m4
rename to MovedRecipes/python3crystax/libffi/m4/ltsugar.m4
diff --git a/recipes/python3crystax/libffi/m4/ltversion.m4 b/MovedRecipes/python3crystax/libffi/m4/ltversion.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/ltversion.m4
rename to MovedRecipes/python3crystax/libffi/m4/ltversion.m4
diff --git a/recipes/python3crystax/libffi/m4/lt~obsolete.m4 b/MovedRecipes/python3crystax/libffi/m4/lt~obsolete.m4
similarity index 100%
rename from recipes/python3crystax/libffi/m4/lt~obsolete.m4
rename to MovedRecipes/python3crystax/libffi/m4/lt~obsolete.m4
diff --git a/recipes/python3crystax/libffi/man/Makefile.am b/MovedRecipes/python3crystax/libffi/man/Makefile.am
similarity index 100%
rename from recipes/python3crystax/libffi/man/Makefile.am
rename to MovedRecipes/python3crystax/libffi/man/Makefile.am
diff --git a/recipes/python3crystax/libffi/man/Makefile.in b/MovedRecipes/python3crystax/libffi/man/Makefile.in
similarity index 100%
rename from recipes/python3crystax/libffi/man/Makefile.in
rename to MovedRecipes/python3crystax/libffi/man/Makefile.in
diff --git a/recipes/python3crystax/libffi/man/ffi.3 b/MovedRecipes/python3crystax/libffi/man/ffi.3
similarity index 100%
rename from recipes/python3crystax/libffi/man/ffi.3
rename to MovedRecipes/python3crystax/libffi/man/ffi.3
diff --git a/recipes/python3crystax/libffi/man/ffi_call.3 b/MovedRecipes/python3crystax/libffi/man/ffi_call.3
similarity index 100%
rename from recipes/python3crystax/libffi/man/ffi_call.3
rename to MovedRecipes/python3crystax/libffi/man/ffi_call.3
diff --git a/recipes/python3crystax/libffi/man/ffi_prep_cif.3 b/MovedRecipes/python3crystax/libffi/man/ffi_prep_cif.3
similarity index 100%
rename from recipes/python3crystax/libffi/man/ffi_prep_cif.3
rename to MovedRecipes/python3crystax/libffi/man/ffi_prep_cif.3
diff --git a/recipes/python3crystax/libffi/man/ffi_prep_cif_var.3 b/MovedRecipes/python3crystax/libffi/man/ffi_prep_cif_var.3
similarity index 100%
rename from recipes/python3crystax/libffi/man/ffi_prep_cif_var.3
rename to MovedRecipes/python3crystax/libffi/man/ffi_prep_cif_var.3
diff --git a/recipes/python3crystax/libffi/mdate-sh b/MovedRecipes/python3crystax/libffi/mdate-sh
similarity index 100%
rename from recipes/python3crystax/libffi/mdate-sh
rename to MovedRecipes/python3crystax/libffi/mdate-sh
diff --git a/recipes/python3crystax/libffi/missing b/MovedRecipes/python3crystax/libffi/missing
similarity index 100%
rename from recipes/python3crystax/libffi/missing
rename to MovedRecipes/python3crystax/libffi/missing
diff --git a/recipes/python3crystax/libffi/msvcc.sh b/MovedRecipes/python3crystax/libffi/msvcc.sh
similarity index 100%
rename from recipes/python3crystax/libffi/msvcc.sh
rename to MovedRecipes/python3crystax/libffi/msvcc.sh
diff --git a/recipes/python3crystax/libffi/src/aarch64/ffi.c b/MovedRecipes/python3crystax/libffi/src/aarch64/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/aarch64/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/aarch64/ffi.c
diff --git a/recipes/python3crystax/libffi/src/aarch64/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/aarch64/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/aarch64/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/aarch64/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/aarch64/sysv.S b/MovedRecipes/python3crystax/libffi/src/aarch64/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/aarch64/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/aarch64/sysv.S
diff --git a/recipes/python3crystax/libffi/src/alpha/ffi.c b/MovedRecipes/python3crystax/libffi/src/alpha/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/alpha/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/alpha/ffi.c
diff --git a/recipes/python3crystax/libffi/src/alpha/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/alpha/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/alpha/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/alpha/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/alpha/osf.S b/MovedRecipes/python3crystax/libffi/src/alpha/osf.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/alpha/osf.S
rename to MovedRecipes/python3crystax/libffi/src/alpha/osf.S
diff --git a/recipes/python3crystax/libffi/src/arc/arcompact.S b/MovedRecipes/python3crystax/libffi/src/arc/arcompact.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/arc/arcompact.S
rename to MovedRecipes/python3crystax/libffi/src/arc/arcompact.S
diff --git a/recipes/python3crystax/libffi/src/arc/ffi.c b/MovedRecipes/python3crystax/libffi/src/arc/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/arc/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/arc/ffi.c
diff --git a/recipes/python3crystax/libffi/src/arc/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/arc/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/arc/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/arc/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/arm/ffi.c b/MovedRecipes/python3crystax/libffi/src/arm/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/arm/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/arm/ffi.c
diff --git a/recipes/python3crystax/libffi/src/arm/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/arm/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/arm/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/arm/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/arm/gentramp.sh b/MovedRecipes/python3crystax/libffi/src/arm/gentramp.sh
similarity index 100%
rename from recipes/python3crystax/libffi/src/arm/gentramp.sh
rename to MovedRecipes/python3crystax/libffi/src/arm/gentramp.sh
diff --git a/recipes/python3crystax/libffi/src/arm/sysv.S b/MovedRecipes/python3crystax/libffi/src/arm/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/arm/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/arm/sysv.S
diff --git a/recipes/python3crystax/libffi/src/arm/trampoline.S b/MovedRecipes/python3crystax/libffi/src/arm/trampoline.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/arm/trampoline.S
rename to MovedRecipes/python3crystax/libffi/src/arm/trampoline.S
diff --git a/recipes/python3crystax/libffi/src/avr32/ffi.c b/MovedRecipes/python3crystax/libffi/src/avr32/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/avr32/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/avr32/ffi.c
diff --git a/recipes/python3crystax/libffi/src/avr32/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/avr32/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/avr32/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/avr32/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/avr32/sysv.S b/MovedRecipes/python3crystax/libffi/src/avr32/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/avr32/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/avr32/sysv.S
diff --git a/recipes/python3crystax/libffi/src/bfin/ffi.c b/MovedRecipes/python3crystax/libffi/src/bfin/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/bfin/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/bfin/ffi.c
diff --git a/recipes/python3crystax/libffi/src/bfin/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/bfin/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/bfin/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/bfin/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/bfin/sysv.S b/MovedRecipes/python3crystax/libffi/src/bfin/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/bfin/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/bfin/sysv.S
diff --git a/recipes/python3crystax/libffi/src/closures.c b/MovedRecipes/python3crystax/libffi/src/closures.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/closures.c
rename to MovedRecipes/python3crystax/libffi/src/closures.c
diff --git a/recipes/python3crystax/libffi/src/cris/ffi.c b/MovedRecipes/python3crystax/libffi/src/cris/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/cris/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/cris/ffi.c
diff --git a/recipes/python3crystax/libffi/src/cris/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/cris/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/cris/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/cris/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/cris/sysv.S b/MovedRecipes/python3crystax/libffi/src/cris/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/cris/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/cris/sysv.S
diff --git a/recipes/python3crystax/libffi/src/debug.c b/MovedRecipes/python3crystax/libffi/src/debug.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/debug.c
rename to MovedRecipes/python3crystax/libffi/src/debug.c
diff --git a/recipes/python3crystax/libffi/src/dlmalloc.c b/MovedRecipes/python3crystax/libffi/src/dlmalloc.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/dlmalloc.c
rename to MovedRecipes/python3crystax/libffi/src/dlmalloc.c
diff --git a/recipes/python3crystax/libffi/src/frv/eabi.S b/MovedRecipes/python3crystax/libffi/src/frv/eabi.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/frv/eabi.S
rename to MovedRecipes/python3crystax/libffi/src/frv/eabi.S
diff --git a/recipes/python3crystax/libffi/src/frv/ffi.c b/MovedRecipes/python3crystax/libffi/src/frv/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/frv/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/frv/ffi.c
diff --git a/recipes/python3crystax/libffi/src/frv/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/frv/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/frv/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/frv/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/ia64/ffi.c b/MovedRecipes/python3crystax/libffi/src/ia64/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/ia64/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/ia64/ffi.c
diff --git a/recipes/python3crystax/libffi/src/ia64/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/ia64/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/ia64/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/ia64/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/ia64/ia64_flags.h b/MovedRecipes/python3crystax/libffi/src/ia64/ia64_flags.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/ia64/ia64_flags.h
rename to MovedRecipes/python3crystax/libffi/src/ia64/ia64_flags.h
diff --git a/recipes/python3crystax/libffi/src/ia64/unix.S b/MovedRecipes/python3crystax/libffi/src/ia64/unix.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/ia64/unix.S
rename to MovedRecipes/python3crystax/libffi/src/ia64/unix.S
diff --git a/recipes/python3crystax/libffi/src/java_raw_api.c b/MovedRecipes/python3crystax/libffi/src/java_raw_api.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/java_raw_api.c
rename to MovedRecipes/python3crystax/libffi/src/java_raw_api.c
diff --git a/recipes/python3crystax/libffi/src/m32r/ffi.c b/MovedRecipes/python3crystax/libffi/src/m32r/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/m32r/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/m32r/ffi.c
diff --git a/recipes/python3crystax/libffi/src/m32r/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/m32r/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/m32r/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/m32r/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/m32r/sysv.S b/MovedRecipes/python3crystax/libffi/src/m32r/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/m32r/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/m32r/sysv.S
diff --git a/recipes/python3crystax/libffi/src/m68k/ffi.c b/MovedRecipes/python3crystax/libffi/src/m68k/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/m68k/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/m68k/ffi.c
diff --git a/recipes/python3crystax/libffi/src/m68k/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/m68k/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/m68k/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/m68k/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/m68k/sysv.S b/MovedRecipes/python3crystax/libffi/src/m68k/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/m68k/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/m68k/sysv.S
diff --git a/recipes/python3crystax/libffi/src/m88k/ffi.c b/MovedRecipes/python3crystax/libffi/src/m88k/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/m88k/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/m88k/ffi.c
diff --git a/recipes/python3crystax/libffi/src/m88k/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/m88k/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/m88k/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/m88k/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/m88k/obsd.S b/MovedRecipes/python3crystax/libffi/src/m88k/obsd.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/m88k/obsd.S
rename to MovedRecipes/python3crystax/libffi/src/m88k/obsd.S
diff --git a/recipes/python3crystax/libffi/src/metag/ffi.c b/MovedRecipes/python3crystax/libffi/src/metag/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/metag/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/metag/ffi.c
diff --git a/recipes/python3crystax/libffi/src/metag/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/metag/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/metag/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/metag/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/metag/sysv.S b/MovedRecipes/python3crystax/libffi/src/metag/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/metag/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/metag/sysv.S
diff --git a/recipes/python3crystax/libffi/src/microblaze/ffi.c b/MovedRecipes/python3crystax/libffi/src/microblaze/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/microblaze/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/microblaze/ffi.c
diff --git a/recipes/python3crystax/libffi/src/microblaze/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/microblaze/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/microblaze/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/microblaze/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/microblaze/sysv.S b/MovedRecipes/python3crystax/libffi/src/microblaze/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/microblaze/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/microblaze/sysv.S
diff --git a/recipes/python3crystax/libffi/src/mips/ffi.c b/MovedRecipes/python3crystax/libffi/src/mips/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/mips/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/mips/ffi.c
diff --git a/recipes/python3crystax/libffi/src/mips/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/mips/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/mips/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/mips/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/mips/n32.S b/MovedRecipes/python3crystax/libffi/src/mips/n32.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/mips/n32.S
rename to MovedRecipes/python3crystax/libffi/src/mips/n32.S
diff --git a/recipes/python3crystax/libffi/src/mips/o32.S b/MovedRecipes/python3crystax/libffi/src/mips/o32.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/mips/o32.S
rename to MovedRecipes/python3crystax/libffi/src/mips/o32.S
diff --git a/recipes/python3crystax/libffi/src/moxie/eabi.S b/MovedRecipes/python3crystax/libffi/src/moxie/eabi.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/moxie/eabi.S
rename to MovedRecipes/python3crystax/libffi/src/moxie/eabi.S
diff --git a/recipes/python3crystax/libffi/src/moxie/ffi.c b/MovedRecipes/python3crystax/libffi/src/moxie/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/moxie/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/moxie/ffi.c
diff --git a/recipes/python3crystax/libffi/src/moxie/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/moxie/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/moxie/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/moxie/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/nios2/ffi.c b/MovedRecipes/python3crystax/libffi/src/nios2/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/nios2/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/nios2/ffi.c
diff --git a/recipes/python3crystax/libffi/src/nios2/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/nios2/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/nios2/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/nios2/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/nios2/sysv.S b/MovedRecipes/python3crystax/libffi/src/nios2/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/nios2/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/nios2/sysv.S
diff --git a/recipes/python3crystax/libffi/src/pa/ffi.c b/MovedRecipes/python3crystax/libffi/src/pa/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/pa/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/pa/ffi.c
diff --git a/recipes/python3crystax/libffi/src/pa/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/pa/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/pa/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/pa/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/pa/hpux32.S b/MovedRecipes/python3crystax/libffi/src/pa/hpux32.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/pa/hpux32.S
rename to MovedRecipes/python3crystax/libffi/src/pa/hpux32.S
diff --git a/recipes/python3crystax/libffi/src/pa/linux.S b/MovedRecipes/python3crystax/libffi/src/pa/linux.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/pa/linux.S
rename to MovedRecipes/python3crystax/libffi/src/pa/linux.S
diff --git a/recipes/python3crystax/libffi/src/powerpc/aix.S b/MovedRecipes/python3crystax/libffi/src/powerpc/aix.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/aix.S
rename to MovedRecipes/python3crystax/libffi/src/powerpc/aix.S
diff --git a/recipes/python3crystax/libffi/src/powerpc/aix_closure.S b/MovedRecipes/python3crystax/libffi/src/powerpc/aix_closure.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/aix_closure.S
rename to MovedRecipes/python3crystax/libffi/src/powerpc/aix_closure.S
diff --git a/recipes/python3crystax/libffi/src/powerpc/asm.h b/MovedRecipes/python3crystax/libffi/src/powerpc/asm.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/asm.h
rename to MovedRecipes/python3crystax/libffi/src/powerpc/asm.h
diff --git a/recipes/python3crystax/libffi/src/powerpc/darwin.S b/MovedRecipes/python3crystax/libffi/src/powerpc/darwin.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/darwin.S
rename to MovedRecipes/python3crystax/libffi/src/powerpc/darwin.S
diff --git a/recipes/python3crystax/libffi/src/powerpc/darwin_closure.S b/MovedRecipes/python3crystax/libffi/src/powerpc/darwin_closure.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/darwin_closure.S
rename to MovedRecipes/python3crystax/libffi/src/powerpc/darwin_closure.S
diff --git a/recipes/python3crystax/libffi/src/powerpc/ffi.c b/MovedRecipes/python3crystax/libffi/src/powerpc/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/powerpc/ffi.c
diff --git a/recipes/python3crystax/libffi/src/powerpc/ffi_darwin.c b/MovedRecipes/python3crystax/libffi/src/powerpc/ffi_darwin.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/ffi_darwin.c
rename to MovedRecipes/python3crystax/libffi/src/powerpc/ffi_darwin.c
diff --git a/recipes/python3crystax/libffi/src/powerpc/ffi_linux64.c b/MovedRecipes/python3crystax/libffi/src/powerpc/ffi_linux64.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/ffi_linux64.c
rename to MovedRecipes/python3crystax/libffi/src/powerpc/ffi_linux64.c
diff --git a/recipes/python3crystax/libffi/src/powerpc/ffi_powerpc.h b/MovedRecipes/python3crystax/libffi/src/powerpc/ffi_powerpc.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/ffi_powerpc.h
rename to MovedRecipes/python3crystax/libffi/src/powerpc/ffi_powerpc.h
diff --git a/recipes/python3crystax/libffi/src/powerpc/ffi_sysv.c b/MovedRecipes/python3crystax/libffi/src/powerpc/ffi_sysv.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/ffi_sysv.c
rename to MovedRecipes/python3crystax/libffi/src/powerpc/ffi_sysv.c
diff --git a/recipes/python3crystax/libffi/src/powerpc/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/powerpc/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/powerpc/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/powerpc/linux64.S b/MovedRecipes/python3crystax/libffi/src/powerpc/linux64.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/linux64.S
rename to MovedRecipes/python3crystax/libffi/src/powerpc/linux64.S
diff --git a/recipes/python3crystax/libffi/src/powerpc/linux64_closure.S b/MovedRecipes/python3crystax/libffi/src/powerpc/linux64_closure.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/linux64_closure.S
rename to MovedRecipes/python3crystax/libffi/src/powerpc/linux64_closure.S
diff --git a/recipes/python3crystax/libffi/src/powerpc/ppc_closure.S b/MovedRecipes/python3crystax/libffi/src/powerpc/ppc_closure.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/ppc_closure.S
rename to MovedRecipes/python3crystax/libffi/src/powerpc/ppc_closure.S
diff --git a/recipes/python3crystax/libffi/src/powerpc/sysv.S b/MovedRecipes/python3crystax/libffi/src/powerpc/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/powerpc/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/powerpc/sysv.S
diff --git a/recipes/python3crystax/libffi/src/prep_cif.c b/MovedRecipes/python3crystax/libffi/src/prep_cif.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/prep_cif.c
rename to MovedRecipes/python3crystax/libffi/src/prep_cif.c
diff --git a/recipes/python3crystax/libffi/src/raw_api.c b/MovedRecipes/python3crystax/libffi/src/raw_api.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/raw_api.c
rename to MovedRecipes/python3crystax/libffi/src/raw_api.c
diff --git a/recipes/python3crystax/libffi/src/s390/ffi.c b/MovedRecipes/python3crystax/libffi/src/s390/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/s390/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/s390/ffi.c
diff --git a/recipes/python3crystax/libffi/src/s390/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/s390/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/s390/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/s390/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/s390/sysv.S b/MovedRecipes/python3crystax/libffi/src/s390/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/s390/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/s390/sysv.S
diff --git a/recipes/python3crystax/libffi/src/sh/ffi.c b/MovedRecipes/python3crystax/libffi/src/sh/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/sh/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/sh/ffi.c
diff --git a/recipes/python3crystax/libffi/src/sh/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/sh/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/sh/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/sh/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/sh/sysv.S b/MovedRecipes/python3crystax/libffi/src/sh/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/sh/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/sh/sysv.S
diff --git a/recipes/python3crystax/libffi/src/sh64/ffi.c b/MovedRecipes/python3crystax/libffi/src/sh64/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/sh64/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/sh64/ffi.c
diff --git a/recipes/python3crystax/libffi/src/sh64/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/sh64/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/sh64/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/sh64/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/sh64/sysv.S b/MovedRecipes/python3crystax/libffi/src/sh64/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/sh64/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/sh64/sysv.S
diff --git a/recipes/python3crystax/libffi/src/sparc/ffi.c b/MovedRecipes/python3crystax/libffi/src/sparc/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/sparc/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/sparc/ffi.c
diff --git a/recipes/python3crystax/libffi/src/sparc/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/sparc/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/sparc/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/sparc/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/sparc/v8.S b/MovedRecipes/python3crystax/libffi/src/sparc/v8.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/sparc/v8.S
rename to MovedRecipes/python3crystax/libffi/src/sparc/v8.S
diff --git a/recipes/python3crystax/libffi/src/sparc/v9.S b/MovedRecipes/python3crystax/libffi/src/sparc/v9.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/sparc/v9.S
rename to MovedRecipes/python3crystax/libffi/src/sparc/v9.S
diff --git a/recipes/python3crystax/libffi/src/tile/ffi.c b/MovedRecipes/python3crystax/libffi/src/tile/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/tile/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/tile/ffi.c
diff --git a/recipes/python3crystax/libffi/src/tile/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/tile/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/tile/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/tile/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/tile/tile.S b/MovedRecipes/python3crystax/libffi/src/tile/tile.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/tile/tile.S
rename to MovedRecipes/python3crystax/libffi/src/tile/tile.S
diff --git a/recipes/python3crystax/libffi/src/types.c b/MovedRecipes/python3crystax/libffi/src/types.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/types.c
rename to MovedRecipes/python3crystax/libffi/src/types.c
diff --git a/recipes/python3crystax/libffi/src/vax/elfbsd.S b/MovedRecipes/python3crystax/libffi/src/vax/elfbsd.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/vax/elfbsd.S
rename to MovedRecipes/python3crystax/libffi/src/vax/elfbsd.S
diff --git a/recipes/python3crystax/libffi/src/vax/ffi.c b/MovedRecipes/python3crystax/libffi/src/vax/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/vax/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/vax/ffi.c
diff --git a/recipes/python3crystax/libffi/src/vax/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/vax/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/vax/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/vax/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/x86/darwin.S b/MovedRecipes/python3crystax/libffi/src/x86/darwin.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/darwin.S
rename to MovedRecipes/python3crystax/libffi/src/x86/darwin.S
diff --git a/recipes/python3crystax/libffi/src/x86/darwin64.S b/MovedRecipes/python3crystax/libffi/src/x86/darwin64.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/darwin64.S
rename to MovedRecipes/python3crystax/libffi/src/x86/darwin64.S
diff --git a/recipes/python3crystax/libffi/src/x86/ffi.c b/MovedRecipes/python3crystax/libffi/src/x86/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/x86/ffi.c
diff --git a/recipes/python3crystax/libffi/src/x86/ffi64.c b/MovedRecipes/python3crystax/libffi/src/x86/ffi64.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/ffi64.c
rename to MovedRecipes/python3crystax/libffi/src/x86/ffi64.c
diff --git a/recipes/python3crystax/libffi/src/x86/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/x86/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/x86/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/x86/freebsd.S b/MovedRecipes/python3crystax/libffi/src/x86/freebsd.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/freebsd.S
rename to MovedRecipes/python3crystax/libffi/src/x86/freebsd.S
diff --git a/recipes/python3crystax/libffi/src/x86/sysv.S b/MovedRecipes/python3crystax/libffi/src/x86/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/x86/sysv.S
diff --git a/recipes/python3crystax/libffi/src/x86/unix64.S b/MovedRecipes/python3crystax/libffi/src/x86/unix64.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/unix64.S
rename to MovedRecipes/python3crystax/libffi/src/x86/unix64.S
diff --git a/recipes/python3crystax/libffi/src/x86/win32.S b/MovedRecipes/python3crystax/libffi/src/x86/win32.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/win32.S
rename to MovedRecipes/python3crystax/libffi/src/x86/win32.S
diff --git a/recipes/python3crystax/libffi/src/x86/win64.S b/MovedRecipes/python3crystax/libffi/src/x86/win64.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/x86/win64.S
rename to MovedRecipes/python3crystax/libffi/src/x86/win64.S
diff --git a/recipes/python3crystax/libffi/src/xtensa/ffi.c b/MovedRecipes/python3crystax/libffi/src/xtensa/ffi.c
similarity index 100%
rename from recipes/python3crystax/libffi/src/xtensa/ffi.c
rename to MovedRecipes/python3crystax/libffi/src/xtensa/ffi.c
diff --git a/recipes/python3crystax/libffi/src/xtensa/ffitarget.h b/MovedRecipes/python3crystax/libffi/src/xtensa/ffitarget.h
similarity index 100%
rename from recipes/python3crystax/libffi/src/xtensa/ffitarget.h
rename to MovedRecipes/python3crystax/libffi/src/xtensa/ffitarget.h
diff --git a/recipes/python3crystax/libffi/src/xtensa/sysv.S b/MovedRecipes/python3crystax/libffi/src/xtensa/sysv.S
similarity index 100%
rename from recipes/python3crystax/libffi/src/xtensa/sysv.S
rename to MovedRecipes/python3crystax/libffi/src/xtensa/sysv.S
diff --git a/recipes/python3crystax/libffi/testsuite/Makefile.am b/MovedRecipes/python3crystax/libffi/testsuite/Makefile.am
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/Makefile.am
rename to MovedRecipes/python3crystax/libffi/testsuite/Makefile.am
diff --git a/recipes/python3crystax/libffi/testsuite/Makefile.in b/MovedRecipes/python3crystax/libffi/testsuite/Makefile.in
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/Makefile.in
rename to MovedRecipes/python3crystax/libffi/testsuite/Makefile.in
diff --git a/recipes/python3crystax/libffi/testsuite/config/default.exp b/MovedRecipes/python3crystax/libffi/testsuite/config/default.exp
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/config/default.exp
rename to MovedRecipes/python3crystax/libffi/testsuite/config/default.exp
diff --git a/recipes/python3crystax/libffi/testsuite/lib/libffi.exp b/MovedRecipes/python3crystax/libffi/testsuite/lib/libffi.exp
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/lib/libffi.exp
rename to MovedRecipes/python3crystax/libffi/testsuite/lib/libffi.exp
diff --git a/recipes/python3crystax/libffi/testsuite/lib/target-libpath.exp b/MovedRecipes/python3crystax/libffi/testsuite/lib/target-libpath.exp
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/lib/target-libpath.exp
rename to MovedRecipes/python3crystax/libffi/testsuite/lib/target-libpath.exp
diff --git a/recipes/python3crystax/libffi/testsuite/lib/wrapper.exp b/MovedRecipes/python3crystax/libffi/testsuite/lib/wrapper.exp
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/lib/wrapper.exp
rename to MovedRecipes/python3crystax/libffi/testsuite/lib/wrapper.exp
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/call.exp b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/call.exp
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/call.exp
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/call.exp
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn0.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn0.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn0.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn0.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn3.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn3.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn3.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn3.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn4.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn4.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn4.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn4.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn5.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn5.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn5.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn5.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn6.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn6.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_fn6.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_fn6.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_loc_fn0.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_loc_fn0.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_loc_fn0.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_loc_fn0.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/closure_simple.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_simple.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/closure_simple.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/closure_simple.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_12byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_12byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_12byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_12byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_16byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_16byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_16byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_16byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_18byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_18byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_18byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_18byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_19byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_19byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_19byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_19byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_1_1byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_1_1byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_1_1byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_1_1byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_20byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_20byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_20byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_20byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_20byte1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_20byte1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_20byte1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_20byte1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_24byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_24byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_24byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_24byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_2byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_2byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_2byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_2byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_3_1byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_3_1byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_3_1byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_3_1byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_3byte1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_3byte1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_3byte1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_3byte1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_3byte2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_3byte2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_3byte2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_3byte2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_4_1byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_4_1byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_4_1byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_4_1byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_4byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_4byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_4byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_4byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_5_1_byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_5_1_byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_5_1_byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_5_1_byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_5byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_5byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_5byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_5byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_64byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_64byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_64byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_64byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_6_1_byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_6_1_byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_6_1_byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_6_1_byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_6byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_6byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_6byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_6byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_7_1_byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_7_1_byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_7_1_byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_7_1_byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_7byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_7byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_7byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_7byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_8byte.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_8byte.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_8byte.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_8byte.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_9byte1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_9byte1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_9byte1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_9byte1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_9byte2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_9byte2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_9byte2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_9byte2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_double.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_double.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_double.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_double.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_float.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_float.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_float.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_float.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble_split.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble_split.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_pointer.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_pointer.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_pointer.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_pointer.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint16.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint16.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint16.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint16.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint32.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint32.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint32.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint32.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint64.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint64.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint64.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_sint64.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint16.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint16.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint16.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint16.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint32.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint32.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint32.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint32.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint64.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint64.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint64.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_align_uint64.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_dbls_struct.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_dbls_struct.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_dbls_struct.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_dbls_struct.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_double.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_double.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_double.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_double.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_double_va.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_double_va.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_double_va.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_double_va.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_float.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_float.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_float.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_float.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_longdouble.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_longdouble.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_longdouble.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_longdouble.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_longdouble_va.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_longdouble_va.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_longdouble_va.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_longdouble_va.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_schar.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_schar.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_schar.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_schar.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_sshort.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_sshort.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_sshort.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_sshort.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_sshortchar.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_sshortchar.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_uchar.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_uchar.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_uchar.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_uchar.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_ushort.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_ushort.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_ushort.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_ushort.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_ushortchar.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_multi_ushortchar.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_pointer.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_pointer.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_pointer.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_pointer.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_pointer_stack.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_pointer_stack.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_pointer_stack.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_pointer_stack.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_schar.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_schar.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_schar.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_schar.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_sint.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_sint.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_sint.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_sint.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_sshort.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_sshort.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_sshort.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_sshort.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_struct_va1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_struct_va1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_struct_va1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_struct_va1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_uchar.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_uchar.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_uchar.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_uchar.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_uchar_va.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_uchar_va.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_uchar_va.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_uchar_va.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_uint.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_uint.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_uint.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_uint.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_uint_va.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_uint_va.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_uint_va.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_uint_va.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_ulong_va.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_ulong_va.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_ulong_va.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_ulong_va.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_ulonglong.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_ulonglong.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_ulonglong.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_ulonglong.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_ushort.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_ushort.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_ushort.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_ushort.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/cls_ushort_va.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_ushort_va.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/cls_ushort_va.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/cls_ushort_va.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/err_bad_abi.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/err_bad_abi.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/err_bad_abi.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/err_bad_abi.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/err_bad_typedef.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/err_bad_typedef.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/err_bad_typedef.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/err_bad_typedef.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/ffitest.h b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/ffitest.h
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/ffitest.h
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/ffitest.h
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/float.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/float.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/float1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/float1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/float2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/float2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/float3.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float3.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/float3.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float3.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/float4.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float4.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/float4.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float4.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/float_va.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float_va.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/float_va.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/float_va.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/huge_struct.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/huge_struct.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/huge_struct.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/huge_struct.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/many.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/many.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/many.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/many.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/many2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/many2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/many2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/many2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/negint.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/negint.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/negint.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/negint.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct10.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct10.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct10.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct10.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct11.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct11.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct11.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct11.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct3.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct3.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct3.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct3.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct4.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct4.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct4.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct4.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct5.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct5.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct5.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct5.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct6.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct6.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct6.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct6.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct7.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct7.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct7.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct7.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct8.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct8.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct8.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct8.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct9.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct9.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/nested_struct9.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/nested_struct9.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/problem1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/problem1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/problem1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/problem1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/promotion.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/promotion.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/promotion.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/promotion.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/pyobjc-tc.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/pyobjc-tc.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/pyobjc-tc.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/pyobjc-tc.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_dbl.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_dbl.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_dbl.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_dbl.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_dbl1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_dbl1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_dbl1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_dbl1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_dbl2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_dbl2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_dbl2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_dbl2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_fl.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_fl.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_fl.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_fl.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_fl1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_fl1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_fl1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_fl1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_fl2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_fl2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_fl2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_fl2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_fl3.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_fl3.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_fl3.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_fl3.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_ldl.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_ldl.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_ldl.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_ldl.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_ll.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_ll.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_ll.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_ll.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_ll1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_ll1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_ll1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_ll1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_sc.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_sc.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_sc.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_sc.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_sl.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_sl.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_sl.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_sl.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_uc.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_uc.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_uc.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_uc.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/return_ul.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_ul.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/return_ul.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/return_ul.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/stret_large.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/stret_large.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/stret_large.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/stret_large.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/stret_large2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/stret_large2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/stret_large2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/stret_large2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/stret_medium.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/stret_medium.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/stret_medium.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/stret_medium.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/stret_medium2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/stret_medium2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/stret_medium2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/stret_medium2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/strlen.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/strlen.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/strlen.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/strlen.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/strlen2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/strlen2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/strlen2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/strlen2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/strlen3.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/strlen3.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/strlen3.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/strlen3.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/strlen4.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/strlen4.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/strlen4.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/strlen4.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct3.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct3.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct3.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct3.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct4.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct4.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct4.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct4.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct5.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct5.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct5.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct5.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct6.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct6.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct6.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct6.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct7.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct7.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct7.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct7.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct8.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct8.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct8.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct8.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/struct9.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct9.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/struct9.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/struct9.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/testclosure.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/testclosure.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/testclosure.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/testclosure.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/uninitialized.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/uninitialized.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/uninitialized.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/uninitialized.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/unwindtest.cc b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/unwindtest.cc
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/unwindtest.cc
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/unwindtest.cc
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/va_1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/va_1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/va_1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/va_1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/va_struct1.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/va_struct1.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/va_struct1.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/va_struct1.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/va_struct2.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/va_struct2.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/va_struct2.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/va_struct2.c
diff --git a/recipes/python3crystax/libffi/testsuite/libffi.call/va_struct3.c b/MovedRecipes/python3crystax/libffi/testsuite/libffi.call/va_struct3.c
similarity index 100%
rename from recipes/python3crystax/libffi/testsuite/libffi.call/va_struct3.c
rename to MovedRecipes/python3crystax/libffi/testsuite/libffi.call/va_struct3.c
diff --git a/recipes/python3crystax/libffi/texinfo.tex b/MovedRecipes/python3crystax/libffi/texinfo.tex
similarity index 100%
rename from recipes/python3crystax/libffi/texinfo.tex
rename to MovedRecipes/python3crystax/libffi/texinfo.tex
diff --git a/recipes/python3crystax/patch/patch_python3.6.patch b/MovedRecipes/python3crystax/patch/patch_python3.6.patch
similarity index 100%
rename from recipes/python3crystax/patch/patch_python3.6.patch
rename to MovedRecipes/python3crystax/patch/patch_python3.6.patch
diff --git a/recipes/python3crystax/patch/patch_python3.9.patch b/MovedRecipes/python3crystax/patch/patch_python3.9.patch
similarity index 100%
rename from recipes/python3crystax/patch/patch_python3.9.patch
rename to MovedRecipes/python3crystax/patch/patch_python3.9.patch
diff --git a/recipes/python3crystax/patch/platlibdir.patch b/MovedRecipes/python3crystax/patch/platlibdir.patch
similarity index 100%
rename from recipes/python3crystax/patch/platlibdir.patch
rename to MovedRecipes/python3crystax/patch/platlibdir.patch
diff --git a/recipes/python3crystax/patch/py3.8.1.patch b/MovedRecipes/python3crystax/patch/py3.8.1.patch
similarity index 100%
rename from recipes/python3crystax/patch/py3.8.1.patch
rename to MovedRecipes/python3crystax/patch/py3.8.1.patch
diff --git a/recipes/python3crystax/patch/py3.8.1_fix_cortex_a8.patch b/MovedRecipes/python3crystax/patch/py3.8.1_fix_cortex_a8.patch
similarity index 100%
rename from recipes/python3crystax/patch/py3.8.1_fix_cortex_a8.patch
rename to MovedRecipes/python3crystax/patch/py3.8.1_fix_cortex_a8.patch
diff --git a/recipes/python3crystax/patch/pyconfig_detection.patch b/MovedRecipes/python3crystax/patch/pyconfig_detection.patch
similarity index 100%
rename from recipes/python3crystax/patch/pyconfig_detection.patch
rename to MovedRecipes/python3crystax/patch/pyconfig_detection.patch
diff --git a/recipes/python3crystax/patch/remove_android_api_check.patch b/MovedRecipes/python3crystax/patch/remove_android_api_check.patch
similarity index 100%
rename from recipes/python3crystax/patch/remove_android_api_check.patch
rename to MovedRecipes/python3crystax/patch/remove_android_api_check.patch
diff --git a/recipes/python3crystax/patch/reproducible-buildinfo.diff b/MovedRecipes/python3crystax/patch/reproducible-buildinfo.diff
similarity index 100%
rename from recipes/python3crystax/patch/reproducible-buildinfo.diff
rename to MovedRecipes/python3crystax/patch/reproducible-buildinfo.diff
diff --git a/recipes/python3crystax/patch/selectors.patch b/MovedRecipes/python3crystax/patch/selectors.patch
similarity index 100%
rename from recipes/python3crystax/patch/selectors.patch
rename to MovedRecipes/python3crystax/patch/selectors.patch
diff --git a/recipes/python3crystax/patch/strdup.patch b/MovedRecipes/python3crystax/patch/strdup.patch
similarity index 100%
rename from recipes/python3crystax/patch/strdup.patch
rename to MovedRecipes/python3crystax/patch/strdup.patch
diff --git a/recipes/setuptools/__init__.py b/MovedRecipes/setuptools/__init__.py
similarity index 100%
rename from recipes/setuptools/__init__.py
rename to MovedRecipes/setuptools/__init__.py
diff --git a/recipes/sqlite3/Android.mk b/MovedRecipes/sqlite3/Android.mk
similarity index 100%
rename from recipes/sqlite3/Android.mk
rename to MovedRecipes/sqlite3/Android.mk
diff --git a/recipes/sqlite3/__init__.py b/MovedRecipes/sqlite3/__init__.py
similarity index 100%
rename from recipes/sqlite3/__init__.py
rename to MovedRecipes/sqlite3/__init__.py
diff --git a/buildozer.spec.arm64.ci b/buildozer.spec.arm64.ci
index 94797f8..b28f314 100644
--- a/buildozer.spec.arm64.ci
+++ b/buildozer.spec.arm64.ci
@@ -107,7 +107,9 @@ android.sdk = 23
#android.private_storage = True
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
-android.ndk_path = ~/.buildozer/android/crystax-ndk-10.3.2
+# android.ndk_path = ~/.buildozer/android/crystax-ndk-10.3.2
+android.ndk_path = ~/.buildozer/android/android-ndk-r23c
+
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
#android.sdk_path = ~/.buildozer/android
diff --git a/docker/Dockerfile.python39.platform-28 b/docker/Dockerfile.python39.platform-28
index 6607f07..4ad2688 100644
--- a/docker/Dockerfile.python39.platform-28
+++ b/docker/Dockerfile.python39.platform-28
@@ -24,6 +24,7 @@ RUN wget 'https://dl.google.com/android/android-sdk_r23-linux.tgz' -P ~/.buildoz
RUN tar -xvf ~/.buildozer/android/platform/android-sdk_r23-linux.tgz -C ~/.buildozer/android/platform/ && \
mv ~/.buildozer/android/platform/android-sdk-linux ~/.buildozer/android/platform/android-sdk && \
unzip ~/.buildozer/android/platform/platform-28_r06.zip -d ~/.buildozer/android/platform/android-sdk/platforms && \
+ # android 9 (pie) comes with api level 28.
mv ~/.buildozer/android/platform/android-sdk/platforms/android-9 ~/.buildozer/android/platform/android-sdk/platforms/android-28 && \
mkdir -p ~/.buildozer/android/platform/android-sdk/build-tools && \
unzip ~/.buildozer/android/platform/build-tools_r28.0.3-linux.zip -d ~/.buildozer/android/platform/android-sdk/build-tools && \
@@ -45,3 +46,10 @@ RUN git clone https://github.com/lbryio/buildozer.git
RUN cd buildozer && python setup.py install && cd ..
CMD ["/bin/bash"]
+
+# result is
+# ./root/.buildozer/android/platform/android-sdk/[build-tools,cmdline-tools,licenses,platforms,tools]
+# ...build-tools/28.0.3/
+# ...cmdline-tools/5.0/[bin,lib,source.properties]
+# ...platforms/android-28/[]
+# ...tools/[]
diff --git a/p4a/pythonforandroid/bootstraps/lbry/__init__.py b/p4a/pythonforandroid/bootstraps/lbry/__init__.py
new file mode 100644
index 0000000..f3fbeed
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/__init__.py
@@ -0,0 +1,133 @@
+from pythonforandroid.toolchain import (
+ Bootstrap, shprint, current_directory, info, info_main)
+from pythonforandroid.util import ensure_dir
+from os.path import join, exists, curdir, abspath
+from os import walk
+import glob
+import sh
+
+EXCLUDE_EXTS = (".py", ".pyc", ".so.o", ".so.a", ".so.libs", ".pyx")
+
+
+class LbryBootstrap(Bootstrap):
+ name = 'lbry'
+
+ recipe_depends = ['genericndkbuild', ('python2', 'python3')]
+
+ def run_distribute(self):
+ info_main("# Creating Android project ({})".format(self.name))
+
+ arch = self.ctx.archs[0]
+ python_install_dir = self.ctx.get_python_install_dir()
+ #from_crystax = self.ctx.python_recipe.from_crystax
+ #crystax_python_dir = join("crystax_python", "crystax_python")
+
+ if len(self.ctx.archs) > 1:
+ raise ValueError("LBRY/gradle support only one arch")
+
+ info("Copying LBRY/gradle build for {}".format(arch))
+ shprint(sh.rm, "-rf", self.dist_dir)
+ shprint(sh.cp, "-r", self.build_dir, self.dist_dir)
+
+ # either the build use environemnt variable (ANDROID_HOME)
+ # or the local.properties if exists
+ with current_directory(self.dist_dir):
+ with open('local.properties', 'w') as fileh:
+ fileh.write('sdk.dir={}'.format(self.ctx.sdk_dir))
+
+ with current_directory(self.dist_dir):
+ info("Copying Python distribution")
+
+ if not exists("private"):
+ ensure_dir("private")
+
+ hostpython = sh.Command(self.ctx.hostpython)
+ # if not from_crystax:
+ try:
+ shprint(hostpython, '-OO', '-m', 'compileall',
+ python_install_dir,
+ _tail=10, _filterout="^Listing")
+ except sh.ErrorReturnCode:
+ pass
+ if not exists('python-install'):
+ shprint(
+ sh.cp, '-a', python_install_dir, './python-install')
+
+ self.distribute_libs(arch, [self.ctx.get_libs_dir(arch.arch)])
+ self.distribute_javaclasses(self.ctx.javaclass_dir,
+ dest_dir=join("src", "main", "java"))
+
+ # if not from_crystax:
+ info("Filling private directory")
+ if not exists(join("private", "lib")):
+ info("private/lib does not exist, making")
+ shprint(sh.cp, "-a",
+ join("python-install", "lib"), "private")
+ shprint(sh.mkdir, "-p",
+ join("private", "include", "python2.7"))
+
+ libpymodules_fn = join("libs", arch.arch, "libpymodules.so")
+ if exists(libpymodules_fn):
+ shprint(sh.mv, libpymodules_fn, 'private/')
+ shprint(sh.cp,
+ join('python-install', 'include',
+ 'python2.7', 'pyconfig.h'),
+ join('private', 'include', 'python2.7/'))
+
+ info('Removing some unwanted files')
+ shprint(sh.rm, '-f', join('private', 'lib', 'libpython2.7.so'))
+ shprint(sh.rm, '-rf', join('private', 'lib', 'pkgconfig'))
+
+ libdir = join(self.dist_dir, 'private', 'lib', 'python2.7')
+ site_packages_dir = join(libdir, 'site-packages')
+ with current_directory(libdir):
+ removes = []
+ for dirname, root, filenames in walk("."):
+ for filename in filenames:
+ for suffix in EXCLUDE_EXTS:
+ if filename.endswith(suffix):
+ removes.append(filename)
+ shprint(sh.rm, '-f', *removes)
+
+ info('Deleting some other stuff not used on android')
+ # To quote the original distribute.sh, 'well...'
+ shprint(sh.rm, '-rf', 'lib2to3')
+ shprint(sh.rm, '-rf', 'idlelib')
+ for filename in glob.glob('config/libpython*.a'):
+ shprint(sh.rm, '-f', filename)
+ shprint(sh.rm, '-rf', 'config/python.o')
+
+ # else: # Python *is* loaded from crystax
+ # ndk_dir = self.ctx.ndk_dir
+ # py_recipe = self.ctx.python_recipe
+ # python_dir = join(ndk_dir, 'sources', 'python',
+ # py_recipe.version, 'libs', arch.arch)
+ # shprint(sh.cp, '-r', join(python_dir,
+ # 'stdlib.zip'), crystax_python_dir)
+ # shprint(sh.cp, '-r', join(python_dir,
+ # 'modules'), crystax_python_dir)
+ # shprint(sh.cp, '-r', self.ctx.get_python_install_dir(),
+ # join(crystax_python_dir, 'site-packages'))
+ #
+ # info('Renaming .so files to reflect cross-compile')
+ # site_packages_dir = join(crystax_python_dir, "site-packages")
+ # find_ret = shprint(
+ # sh.find, site_packages_dir, '-iname', '*.so')
+ # filenames = find_ret.stdout.decode('utf-8').split('\n')[:-1]
+ # for filename in filenames:
+ # parts = filename.split('.')
+ # if len(parts) <= 2:
+ # continue
+ # shprint(sh.mv, filename, filename.split('.')[0] + '.so')
+ # site_packages_dir = join(abspath(curdir),
+ # site_packages_dir)
+ if 'sqlite3' not in self.ctx.recipe_build_order:
+ with open('blacklist.txt', 'a') as fileh:
+ fileh.write('\nsqlite3/*\nlib-dynload/_sqlite3.so\n')
+
+ self.strip_libraries(arch)
+ self.fry_eggs(site_packages_dir)
+ super(LbryBootstrap, self).run_distribute()
+
+
+bootstrap = LbryBootstrap()
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/.gitignore b/p4a/pythonforandroid/bootstraps/lbry/build/.gitignore
new file mode 100644
index 0000000..a1fc39c
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/.gitignore
@@ -0,0 +1,14 @@
+.gradle
+/build/
+
+# Ignore Gradle GUI config
+gradle-app.setting
+
+# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
+!gradle-wrapper.jar
+
+# Cache of project
+.gradletasknamecache
+
+# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
+# gradle/wrapper/gradle-wrapper.properties
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/ant.properties b/p4a/pythonforandroid/bootstraps/lbry/build/ant.properties
new file mode 100644
index 0000000..0dee5c8
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/ant.properties
@@ -0,0 +1,22 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked into Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
+source.absolute.dir = tmp-src
+
+resource.absolute.dir = src/main/res
+
+asset.absolute.dir = src/main/assets
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/blacklist.txt b/p4a/pythonforandroid/bootstraps/lbry/build/blacklist.txt
new file mode 100644
index 0000000..72ebeaf
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/blacklist.txt
@@ -0,0 +1,83 @@
+# prevent user to include invalid extensions
+*.apk
+*.pxd
+
+# eggs
+*.egg-info
+
+# unit test
+#unittest/*
+
+# python config
+config/makesetup
+
+# unused kivy files (platform specific)
+kivy/input/providers/wm_*
+kivy/input/providers/mactouch*
+kivy/input/providers/probesysfs*
+kivy/input/providers/mtdev*
+kivy/input/providers/hidinput*
+kivy/core/camera/camera_videocapture*
+kivy/core/spelling/*osx*
+kivy/core/video/video_pyglet*
+kivy/tools
+kivy/tests/*
+kivy/*/*.h
+kivy/*/*.pxi
+
+# unused encodings
+lib-dynload/*codec*
+encodings/cp*.pyo
+encodings/tis*
+encodings/shift*
+encodings/bz2*
+encodings/iso*
+encodings/undefined*
+encodings/johab*
+encodings/p*
+encodings/m*
+encodings/euc*
+encodings/k*
+encodings/unicode_internal*
+encodings/quo*
+encodings/gb*
+encodings/big5*
+encodings/hp*
+encodings/hz*
+
+# unused python modules
+bsddb/*
+wsgiref/*
+hotshot/*
+pydoc_data/*
+tty.pyo
+anydbm.pyo
+nturl2path.pyo
+LICENCE.txt
+macurl2path.pyo
+dummy_threading.pyo
+audiodev.pyo
+antigravity.pyo
+dumbdbm.pyo
+sndhdr.pyo
+__phello__.foo.pyo
+sunaudio.pyo
+os2emxpath.pyo
+multiprocessing/dummy*
+
+# unused binaries python modules
+lib-dynload/termios.so
+lib-dynload/_lsprof.so
+lib-dynload/*audioop.so
+lib-dynload/mmap.so
+lib-dynload/_hotshot.so
+lib-dynload/_heapq.so
+lib-dynload/_json.so
+lib-dynload/grp.so
+lib-dynload/resource.so
+lib-dynload/pyexpat.so
+lib-dynload/_ctypes_test.so
+lib-dynload/_testcapi.so
+
+# odd files
+plat-linux3/regen
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/build.py b/p4a/pythonforandroid/bootstraps/lbry/build/build.py
new file mode 100755
index 0000000..59857a9
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/build.py
@@ -0,0 +1,607 @@
+#!/usr/bin/env python2.7
+# coding: utf-8
+
+from __future__ import print_function
+from os.path import (
+ dirname, join, isfile, realpath, relpath, split, exists, basename)
+from os import makedirs, remove, listdir
+import os
+import tarfile
+import time
+import subprocess
+import shutil
+from zipfile import ZipFile
+import sys
+from distutils.version import LooseVersion
+
+from fnmatch import fnmatch
+
+import jinja2
+
+curdir = dirname(__file__)
+
+# Try to find a host version of Python that matches our ARM version.
+PYTHON = join(curdir, 'python-install', 'bin', 'python.host')
+if not exists(PYTHON):
+ print('Could not find hostpython, will not compile to .pyo (this is normal with python3)')
+ PYTHON = None
+
+BLACKLIST_PATTERNS = [
+ # code versionning
+ '^*.hg/*',
+ '^*.git/*',
+ '^*.bzr/*',
+ '^*.svn/*',
+
+ # pyc/py
+ '*.pyc',
+
+ # temp files
+ '~',
+ '*.bak',
+ '*.swp',
+]
+if PYTHON is not None:
+ BLACKLIST_PATTERNS.append('*.py')
+
+WHITELIST_PATTERNS = ['pyconfig.h', ]
+
+python_files = []
+
+
+environment = jinja2.Environment(loader=jinja2.FileSystemLoader(
+ join(curdir, 'templates')))
+
+
+def try_unlink(fn):
+ if exists(fn):
+ os.unlink(fn)
+
+
+def ensure_dir(path):
+ if not exists(path):
+ makedirs(path)
+
+
+def render(template, dest, **kwargs):
+ '''Using jinja2, render `template` to the filename `dest`, supplying the
+
+ keyword arguments as template parameters.
+ '''
+
+ dest_dir = dirname(dest)
+ if dest_dir and not exists(dest_dir):
+ makedirs(dest_dir)
+
+ template = environment.get_template(template)
+ text = template.render(**kwargs)
+
+ f = open(dest, 'wb')
+ f.write(text.encode('utf-8'))
+ f.close()
+
+
+def is_whitelist(name):
+ return match_filename(WHITELIST_PATTERNS, name)
+
+
+def is_blacklist(name):
+ if is_whitelist(name):
+ return False
+ return match_filename(BLACKLIST_PATTERNS, name)
+
+
+def match_filename(pattern_list, name):
+ for pattern in pattern_list:
+ if pattern.startswith('^'):
+ pattern = pattern[1:]
+ else:
+ pattern = '*/' + pattern
+ if fnmatch(name, pattern):
+ return True
+
+
+def listfiles(d):
+ basedir = d
+ subdirlist = []
+ for item in os.listdir(d):
+ fn = join(d, item)
+ if isfile(fn):
+ yield fn
+ else:
+ subdirlist.append(join(basedir, item))
+ for subdir in subdirlist:
+ for fn in listfiles(subdir):
+ yield fn
+
+
+def make_python_zip():
+ '''
+ Search for all the python related files, and construct the pythonXX.zip
+ According to
+ # http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html
+ site-packages, config and lib-dynload will be not included.
+ '''
+
+ if not exists('private'):
+ print('No compiled python is present to zip, skipping.')
+ print('this should only be the case if you are using the CrystaX python')
+ return
+
+ global python_files
+ d = realpath(join('private', 'lib', 'python2.7'))
+
+ def select(fn):
+ if is_blacklist(fn):
+ return False
+ fn = realpath(fn)
+ assert(fn.startswith(d))
+ fn = fn[len(d):]
+ if (fn.startswith('/site-packages/') or
+ fn.startswith('/config/') or
+ fn.startswith('/lib-dynload/') or
+ fn.startswith('/libpymodules.so')):
+ return False
+ return fn
+
+ # get a list of all python file
+ python_files = [x for x in listfiles(d) if select(x)]
+
+ # create the final zipfile
+ zfn = join('private', 'lib', 'python27.zip')
+ zf = ZipFile(zfn, 'w')
+
+ # put all the python files in it
+ for fn in python_files:
+ afn = fn[len(d):]
+ zf.write(fn, afn)
+ zf.close()
+
+
+def make_tar(tfn, source_dirs, ignore_path=[]):
+ '''
+ Make a zip file `fn` from the contents of source_dis.
+ '''
+
+ # selector function
+ def select(fn):
+ rfn = realpath(fn)
+ for p in ignore_path:
+ if p.endswith('/'):
+ p = p[:-1]
+ if rfn.startswith(p):
+ return False
+ if rfn in python_files:
+ return False
+ return not is_blacklist(fn)
+
+ # get the files and relpath file of all the directory we asked for
+ files = []
+ for sd in source_dirs:
+ sd = realpath(sd)
+ compile_dir(sd)
+ files += [(x, relpath(realpath(x), sd)) for x in listfiles(sd)
+ if select(x)]
+
+ # create tar.gz of thoses files
+ tf = tarfile.open(tfn, 'w:gz', format=tarfile.USTAR_FORMAT)
+ dirs = []
+ for fn, afn in files:
+# print('%s: %s' % (tfn, fn))
+ dn = dirname(afn)
+ if dn not in dirs:
+ # create every dirs first if not exist yet
+ d = ''
+ for component in split(dn):
+ d = join(d, component)
+ if d.startswith('/'):
+ d = d[1:]
+ if d == '' or d in dirs:
+ continue
+ dirs.append(d)
+ tinfo = tarfile.TarInfo(d)
+ tinfo.type = tarfile.DIRTYPE
+ tf.addfile(tinfo)
+
+ # put the file
+ tf.add(fn, afn)
+ tf.close()
+
+
+def compile_dir(dfn):
+ '''
+ Compile *.py in directory `dfn` to *.pyo
+ '''
+ # -OO = strip docstrings
+ if PYTHON is None:
+ return
+ subprocess.call([PYTHON, '-OO', '-m', 'compileall', '-f', dfn])
+
+
+def make_package(args):
+ # Ignore warning if the launcher is in args
+ if not args.launcher:
+ if not (exists(join(realpath(args.private), 'main.py')) or
+ exists(join(realpath(args.private), 'main.pyo'))):
+ print('''BUILD FAILURE: No main.py(o) found in your app directory. This
+file must exist to act as the entry point for you app. If your app is
+started by a file with a different name, rename it to main.py or add a
+main.py that loads it.''')
+ exit(1)
+
+ # Delete the old assets.
+ try_unlink('src/main/assets/public.mp3')
+ try_unlink('src/main/assets/private.mp3')
+
+ # In order to speedup import and initial depack,
+ # construct a python27.zip
+ make_python_zip()
+
+ # Package up the private data (public not supported).
+ tar_dirs = [args.private]
+ if exists('private'):
+ tar_dirs.append('private')
+ if exists('crystax_python'):
+ tar_dirs.append('crystax_python')
+
+ if args.private:
+ make_tar('src/main/assets/private.mp3', tar_dirs, args.ignore_path)
+ elif args.launcher:
+ # clean 'None's as a result of main.py path absence
+ tar_dirs = [tdir for tdir in tar_dirs if tdir]
+ make_tar('src/main/assets/private.mp3', tar_dirs, args.ignore_path)
+
+ # folder name for launcher
+ url_scheme = 'kivy'
+
+ # Prepare some variables for templating process
+ default_icon = 'templates/lbry-icon.png'
+ default_presplash = 'templates/kivy-presplash.jpg'
+ shutil.copy(args.icon or default_icon, 'src/main/res/drawable/icon.png')
+ shutil.copy(args.presplash or default_presplash,
+ 'src/main/res/drawable/presplash.jpg')
+
+ # If extra Java jars were requested, copy them into the libs directory
+ if args.add_jar:
+ for jarname in args.add_jar:
+ if not exists(jarname):
+ print('Requested jar does not exist: {}'.format(jarname))
+ sys.exit(-1)
+ shutil.copy(jarname, 'src/main/libs')
+
+ # if extra aar were requested, copy them into the libs directory
+ aars = []
+ if args.add_aar:
+ ensure_dir("libs")
+ for aarname in args.add_aar:
+ if not exists(aarname):
+ print('Requested aar does not exists: {}'.format(aarname))
+ sys.exit(-1)
+ shutil.copy(aarname, 'libs')
+ aars.append(basename(aarname).rsplit('.', 1)[0])
+
+ versioned_name = (args.name.replace(' ', '').replace('\'', '') +
+ '-' + args.version)
+
+ version_code = 0
+ if not args.numeric_version:
+ for i in args.version.split('.'):
+ version_code *= 100
+ version_code += int(i)
+ args.numeric_version = str(version_code)
+
+ if args.intent_filters:
+ with open(args.intent_filters) as fd:
+ args.intent_filters = fd.read()
+
+ if args.extra_source_dirs:
+ esd = []
+ for spec in args.extra_source_dirs:
+ if ':' in spec:
+ specdir, specincludes = spec.split(':')
+ else:
+ specdir = spec
+ specincludes = '**'
+ esd.append((realpath(specdir), specincludes))
+ args.extra_source_dirs = esd
+ else:
+ args.extra_source_dirs = []
+
+ service = False
+ if args.private:
+ service_main = join(realpath(args.private), 'service', 'main.py')
+ if exists(service_main) or exists(service_main + 'o'):
+ service = True
+
+ service_names = []
+ for sid, spec in enumerate(args.services):
+ spec = spec.split(':')
+ name = spec[0]
+ entrypoint = spec[1]
+ options = spec[2:]
+
+ foreground = 'foreground' in options
+ sticky = 'sticky' in options
+
+ service_names.append(name)
+ render(
+ 'Service.tmpl.java',
+ 'src/main/java/{}/Service{}.java'.format(args.package.replace(".", "/"), name.capitalize()),
+ name=name,
+ entrypoint=entrypoint,
+ args=args,
+ foreground=foreground,
+ sticky=sticky,
+ service_id=sid + 1)
+
+ # Find the SDK directory and target API
+ with open('project.properties', 'r') as fileh:
+ target = fileh.read().strip()
+ android_api = target.split('-')[1]
+ with open('local.properties', 'r') as fileh:
+ sdk_dir = fileh.read().strip()
+ sdk_dir = sdk_dir[8:]
+
+ # Try to build with the newest available build tools
+ build_tools_versions = listdir(join(sdk_dir, 'build-tools'))
+ build_tools_versions.sort(key=LooseVersion)
+ build_tools_version = build_tools_versions[-1]
+
+
+ render(
+ 'AndroidManifest.tmpl.xml',
+ 'src/main/AndroidManifest.xml',
+ args=args,
+ service=service,
+ service_names=service_names,
+ android_api=android_api,
+ url_scheme=url_scheme)
+
+ # Copy the AndroidManifest.xml to the dist root dir so that ant
+ # can also use it
+ if exists('AndroidManifest.xml'):
+ remove('AndroidManifest.xml')
+ shutil.copy(join('src', 'main', 'AndroidManifest.xml'),
+ 'AndroidManifest.xml')
+
+ render(
+ 'strings.tmpl.xml',
+ 'src/main/res/values/strings.xml',
+ args=args,
+ url_scheme=url_scheme,
+ private_version=str(time.time()))
+
+ # add colors.xml
+ render(
+ 'colors.tmpl.xml',
+ 'src/main/res/values/colors.xml',
+ args=args,
+ url_scheme=url_scheme,
+ )
+
+ # add themes.xml
+ render(
+ 'themes.tmpl.xml',
+ 'src/main/res/values/themes.xml',
+ args=args,
+ url_scheme=url_scheme,
+ )
+
+ # add activity_service_control
+ render(
+ 'activity_service_control.xml',
+ 'src/main/res/layout/activity_service_control.xml',
+ args=args,
+ url_scheme=url_scheme,
+ )
+
+ ## gradle build templates
+ render(
+ 'build.tmpl.gradle',
+ 'build.gradle',
+ args=args,
+ aars=aars,
+ android_api=android_api,
+ build_tools_version=build_tools_version)
+
+ render(
+ 'gradle.properties',
+ 'gradle.properties',
+ env=os.environ)
+
+ # copy icon drawables
+ for folder in ('drawable-hdpi', 'drawable-mdpi', 'drawable-xhdpi', 'drawable-xxhdpi', 'drawable-xxxhdpi'):
+ shutil.copy(
+ 'templates/res/{}/ic_file_download_black_24dp.png'.format(folder),
+ 'src/main/res/{}/ic_file_download_black_24dp.png'.format(folder)
+ );
+
+ ## ant build templates
+ render(
+ 'build.tmpl.xml',
+ 'build.xml',
+ args=args,
+ versioned_name=versioned_name)
+
+ render(
+ 'custom_rules.tmpl.xml',
+ 'custom_rules.xml',
+ args=args)
+
+
+ if args.sign:
+ render('build.properties', 'build.properties')
+ else:
+ if exists('build.properties'):
+ os.remove('build.properties')
+
+def parse_args(args=None):
+ global BLACKLIST_PATTERNS, WHITELIST_PATTERNS, PYTHON
+ default_android_api = 12
+ import argparse
+ ap = argparse.ArgumentParser(description='''\
+Package a Python application for Android.
+
+For this to work, Java and Ant need to be in your path, as does the
+tools directory of the Android SDK.
+''')
+
+ ap.add_argument('--private', dest='private',
+ help='the dir of user files')
+ # , required=True) for launcher, crashes in make_package
+ # if not mentioned (and the check is there anyway)
+ ap.add_argument('--package', dest='package',
+ help=('The name of the java package the project will be'
+ ' packaged under.'),
+ required=True)
+ ap.add_argument('--name', dest='name',
+ help=('The human-readable name of the project.'),
+ required=True)
+ ap.add_argument('--numeric-version', dest='numeric_version',
+ help=('The numeric version number of the project. If not '
+ 'given, this is automatically computed from the '
+ 'version.'))
+ ap.add_argument('--version', dest='version',
+ help=('The version number of the project. This should '
+ 'consist of numbers and dots, and should have the '
+ 'same number of groups of numbers as previous '
+ 'versions.'),
+ required=True)
+ ap.add_argument('--orientation', dest='orientation', default='portrait',
+ help=('The orientation that the game will display in. '
+ 'Usually one of "landscape", "portrait", '
+ '"sensor", or "user" (the same as "sensor" but '
+ 'obeying the user\'s Android rotation setting). '
+ 'The full list of options is given under '
+ 'android_screenOrientation at '
+ 'https://developer.android.com/guide/topics/manifest/'
+ 'activity-element.html'))
+ ap.add_argument('--launcher', dest='launcher', action='store_true',
+ help=('Provide this argument to build a multi-app '
+ 'launcher, rather than a single app.'))
+ ap.add_argument('--icon', dest='icon',
+ help='A png file to use as the icon for the application.')
+ ap.add_argument('--permission', dest='permissions', action='append',
+ help='The permissions to give this app.', nargs='+')
+ ap.add_argument('--meta-data', dest='meta_data', action='append',
+ help='Custom key=value to add in application metadata')
+ ap.add_argument('--presplash', dest='presplash',
+ help=('A jpeg file to use as a screen while the '
+ 'application is loading.'))
+ ap.add_argument('--presplash-color', dest='presplash_color', default='#000000',
+ help=('A string to set the loading screen background color. '
+ 'Supported formats are: #RRGGBB #AARRGGBB or color names '
+ 'like red, green, blue, etc.'))
+ ap.add_argument('--wakelock', dest='wakelock', action='store_true',
+ help=('Indicate if the application needs the device '
+ 'to stay on'))
+ ap.add_argument('--window', dest='window', action='store_true',
+ help='Indicate if the application will be windowed')
+ ap.add_argument('--blacklist', dest='blacklist',
+ default=join(curdir, 'blacklist.txt'),
+ help=('Use a blacklist file to match unwanted file in '
+ 'the final APK'))
+ ap.add_argument('--whitelist', dest='whitelist',
+ default=join(curdir, 'whitelist.txt'),
+ help=('Use a whitelist file to prevent blacklisting of '
+ 'file in the final APK'))
+ ap.add_argument('--add-jar', dest='add_jar', action='append',
+ help=('Add a Java .jar to the libs, so you can access its '
+ 'classes with pyjnius. You can specify this '
+ 'argument more than once to include multiple jars'))
+ ap.add_argument('--add-aar', dest='add_aar', action='append',
+ help=('Add an aar dependency manually'))
+ ap.add_argument('--depend', dest='depends', action='append',
+ help=('Add a external dependency '
+ '(eg: com.android.support:appcompat-v7:19.0.1)'))
+ ## The --sdk option has been removed, it is ignored in favour of
+ ## --android-api handled by toolchain.py
+ ap.add_argument('--sdk', dest='sdk_version', default=-1,
+ type=int, help=('Deprecated argument, does nothing'))
+ ap.add_argument('--minsdk', dest='min_sdk_version',
+ default=default_android_api, type=int,
+ help=('Minimum Android SDK version to use. Default to '
+ 'the value of ANDROIDAPI, or {} if not set'
+ .format(default_android_api)))
+ ap.add_argument('--intent-filters', dest='intent_filters',
+ help=('Add intent-filters xml rules to the '
+ 'AndroidManifest.xml file. The argument is a '
+ 'filename containing xml. The filename should be '
+ 'located relative to the python-for-android '
+ 'directory'))
+ ap.add_argument('--service', dest='services', action='append',
+ help='Declare a new service entrypoint: '
+ 'NAME:PATH_TO_PY[:foreground]')
+ ap.add_argument('--add-source', dest='extra_source_dirs', action='append',
+ help='Include additional source dirs in Java build')
+ ap.add_argument('--try-system-python-compile', dest='try_system_python_compile',
+ action='store_true',
+ help='Use the system python during compileall if possible.')
+ ap.add_argument('--no-compile-pyo', dest='no_compile_pyo', action='store_true',
+ help='Do not optimise .py files to .pyo.')
+ ap.add_argument('--sign', action='store_true',
+ help=('Try to sign the APK with your credentials. You must set '
+ 'the appropriate environment variables.'))
+
+ if args is None:
+ args = sys.argv[1:]
+ args = ap.parse_args(args)
+ args.ignore_path = []
+
+ if args.name and args.name[0] == '"' and args.name[-1] == '"':
+ args.name = args.name[1:-1]
+
+ # if args.sdk_version == -1:
+ # args.sdk_version = args.min_sdk_version
+
+ if args.sdk_version != -1:
+ print('WARNING: Received a --sdk argument, but this argument is '
+ 'deprecated and does nothing.')
+
+ if args.permissions is None:
+ args.permissions = []
+ elif args.permissions:
+ if isinstance(args.permissions[0], list):
+ args.permissions = [p for perm in args.permissions for p in perm]
+
+ if args.meta_data is None:
+ args.meta_data = []
+
+ if args.services is None:
+ args.services = []
+
+ if args.try_system_python_compile:
+ # Hardcoding python2.7 is okay for now, as python3 skips the
+ # compilation anyway
+ if not exists('crystax_python'):
+ python_executable = 'python2.7'
+ try:
+ subprocess.call([python_executable, '--version'])
+ except (OSError, subprocess.CalledProcessError):
+ pass
+ else:
+ PYTHON = python_executable
+
+ if args.no_compile_pyo:
+ PYTHON = None
+ BLACKLIST_PATTERNS.remove('*.py')
+
+ if args.blacklist:
+ with open(args.blacklist) as fd:
+ patterns = [x.strip() for x in fd.read().splitlines()
+ if x.strip() and not x.strip().startswith('#')]
+ BLACKLIST_PATTERNS += patterns
+
+ if args.whitelist:
+ with open(args.whitelist) as fd:
+ patterns = [x.strip() for x in fd.read().splitlines()
+ if x.strip() and not x.strip().startswith('#')]
+ WHITELIST_PATTERNS += patterns
+
+ make_package(args)
+
+ return args
+
+
+if __name__ == "__main__":
+ parse_args()
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/build.xml b/p4a/pythonforandroid/bootstraps/lbry/build/build.xml
new file mode 100644
index 0000000..9f19a07
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/build.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/gradle/wrapper/gradle-wrapper.jar b/p4a/pythonforandroid/bootstraps/lbry/build/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..3d0dee6
Binary files /dev/null and b/p4a/pythonforandroid/bootstraps/lbry/build/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/gradle/wrapper/gradle-wrapper.properties b/p4a/pythonforandroid/bootstraps/lbry/build/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..7f81b24
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Mar 09 17:19:02 CET 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/gradlew b/p4a/pythonforandroid/bootstraps/lbry/build/gradlew
new file mode 100755
index 0000000..91a7e26
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/gradlew
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+ [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/gradlew.bat b/p4a/pythonforandroid/bootstraps/lbry/build/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/jni/Android.mk b/p4a/pythonforandroid/bootstraps/lbry/build/jni/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/jni/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/jni/Application.mk b/p4a/pythonforandroid/bootstraps/lbry/build/jni/Application.mk
new file mode 100644
index 0000000..e79e378
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/jni/Application.mk
@@ -0,0 +1,7 @@
+
+# Uncomment this if you're using STL in your project
+# See CPLUSPLUS-SUPPORT.html in the NDK documentation for more information
+# APP_STL := stlport_static
+
+# APP_ABI := armeabi armeabi-v7a x86
+APP_ABI := $(ARCH)
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/Android.mk b/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/Android.mk
new file mode 100644
index 0000000..0bc42bf
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/Android.mk
@@ -0,0 +1,22 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := main
+
+# Add your application source files here...
+LOCAL_SRC_FILES := start.c pyjniusjni.c
+
+LOCAL_CFLAGS += -I$(PYTHON_INCLUDE_ROOT) $(EXTRA_CFLAGS)
+
+LOCAL_SHARED_LIBRARIES := python_shared
+
+LOCAL_LDLIBS := -llog $(EXTRA_LDLIBS)
+
+LOCAL_LDFLAGS += -L$(PYTHON_LINK_ROOT) $(APPLICATION_ADDITIONAL_LDFLAGS)
+
+include $(BUILD_SHARED_LIBRARY)
+
+ifdef CRYSTAX_PYTHON_VERSION
+ $(call import-module,python/$(CRYSTAX_PYTHON_VERSION))
+endif
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/Android_static.mk b/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/Android_static.mk
new file mode 100644
index 0000000..2de278e
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/Android_static.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := main
+
+LOCAL_SRC_FILES := YourSourceHere.c
+
+include $(BUILD_SHARED_LIBRARY)
+$(call import-module,SDL)LOCAL_PATH := $(call my-dir)
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/bootstrap_name.h b/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/bootstrap_name.h
new file mode 100644
index 0000000..b93a4ae
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/bootstrap_name.h
@@ -0,0 +1,6 @@
+
+#define BOOTSTRAP_NAME_SERVICEONLY
+#define BOOTSTRAP_USES_NO_SDL_HEADERS
+
+const char bootstrap_name[] = "service_only";
+
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/pyjniusjni.c b/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/pyjniusjni.c
new file mode 100644
index 0000000..d67972a
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/jni/application/src/pyjniusjni.c
@@ -0,0 +1,103 @@
+
+#include
+#include
+
+#define LOGI(...) do {} while (0)
+#define LOGE(...) do {} while (0)
+
+#include "android/log.h"
+
+/* These JNI management functions are taken from SDL2, but modified to refer to pyjnius */
+
+/* #define LOG(n, x) __android_log_write(ANDROID_LOG_INFO, (n), (x)) */
+/* #define LOGP(x) LOG("python", (x)) */
+#define LOG_TAG "Python_android"
+#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+
+
+/* Function headers */
+JNIEnv* Android_JNI_GetEnv(void);
+static void Android_JNI_ThreadDestroyed(void*);
+
+static pthread_key_t mThreadKey;
+static JavaVM* mJavaVM;
+
+int Android_JNI_SetupThread(void)
+{
+ Android_JNI_GetEnv();
+ return 1;
+}
+
+/* Library init */
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+ JNIEnv *env;
+ mJavaVM = vm;
+ LOGI("JNI_OnLoad called");
+ if ((*mJavaVM)->GetEnv(mJavaVM, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
+ LOGE("Failed to get the environment using GetEnv()");
+ return -1;
+ }
+ /*
+ * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread
+ * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this
+ */
+ if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed) != 0) {
+
+ __android_log_print(ANDROID_LOG_ERROR, "pyjniusjni", "Error initializing pthread key");
+ }
+ Android_JNI_SetupThread();
+
+ return JNI_VERSION_1_4;
+}
+
+JNIEnv* Android_JNI_GetEnv(void)
+{
+ /* From http://developer.android.com/guide/practices/jni.html
+ * All threads are Linux threads, scheduled by the kernel.
+ * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then
+ * attached to the JavaVM. For example, a thread started with pthread_create can be attached with the
+ * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv,
+ * and cannot make JNI calls.
+ * Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main"
+ * ThreadGroup, making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread
+ * is a no-op.
+ * Note: You can call this function any number of times for the same thread, there's no harm in it
+ */
+
+ JNIEnv *env;
+ int status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env, NULL);
+ if(status < 0) {
+ LOGE("failed to attach current thread");
+ return 0;
+ }
+
+ /* From http://developer.android.com/guide/practices/jni.html
+ * Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward,
+ * in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be
+ * called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific
+ * to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.)
+ * Note: The destructor is not called unless the stored value is != NULL
+ * Note: You can call this function any number of times for the same thread, there's no harm in it
+ * (except for some lost CPU cycles)
+ */
+ pthread_setspecific(mThreadKey, (void*) env);
+
+ return env;
+}
+
+static void Android_JNI_ThreadDestroyed(void* value)
+{
+ /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
+ JNIEnv *env = (JNIEnv*) value;
+ if (env != NULL) {
+ (*mJavaVM)->DetachCurrentThread(mJavaVM);
+ pthread_setspecific(mThreadKey, NULL);
+ }
+}
+
+void *WebView_AndroidGetJNIEnv()
+{
+ return Android_JNI_GetEnv();
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/proguard-project.txt b/p4a/pythonforandroid/bootstraps/lbry/build/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-hdpi/ic_launcher.png b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..6c7126b
Binary files /dev/null and b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-hdpi/ic_launcher.png differ
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-mdpi/ic_launcher.png b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..542c83b
Binary files /dev/null and b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-mdpi/ic_launcher.png differ
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xhdpi/ic_launcher.png b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..df80b81
Binary files /dev/null and b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xxhdpi/ic_launcher.png b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d5c9438
Binary files /dev/null and b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xxxhdpi/lbry-icon.png b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xxxhdpi/lbry-icon.png
new file mode 100644
index 0000000..fb78a16
Binary files /dev/null and b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable-xxxhdpi/lbry-icon.png differ
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable/.gitkeep b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable/icon.png b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable/icon.png
new file mode 100644
index 0000000..fb78a16
Binary files /dev/null and b/p4a/pythonforandroid/bootstraps/lbry/build/res/drawable/icon.png differ
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/chooser_item.xml b/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/chooser_item.xml
new file mode 100644
index 0000000..1823b13
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/chooser_item.xml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/main.xml b/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/main.xml
new file mode 100644
index 0000000..123c4b6
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/main.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/project_chooser.xml b/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/project_chooser.xml
new file mode 100644
index 0000000..23828e6
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/project_chooser.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/project_empty.xml b/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/project_empty.xml
new file mode 100644
index 0000000..ee54814
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/res/layout/project_empty.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/res/values/strings.xml b/p4a/pythonforandroid/bootstraps/lbry/build/res/values/strings.xml
new file mode 100644
index 0000000..daebceb
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+
+ SDL App
+ 0.1
+
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/assets/.gitkeep b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/assets/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/.gitkeep b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/Octal.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/Octal.java
new file mode 100755
index 0000000..dd10624
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/Octal.java
@@ -0,0 +1,141 @@
+/**
+ * Copyright 2012 Kamran Zafar
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.kamranzafar.jtar;
+
+/**
+ * @author Kamran Zafar
+ *
+ */
+public class Octal {
+
+ /**
+ * Parse an octal string from a header buffer. This is used for the file
+ * permission mode value.
+ *
+ * @param header
+ * The header buffer from which to parse.
+ * @param offset
+ * The offset into the buffer from which to parse.
+ * @param length
+ * The number of header bytes to parse.
+ *
+ * @return The long value of the octal string.
+ */
+ public static long parseOctal(byte[] header, int offset, int length) {
+ long result = 0;
+ boolean stillPadding = true;
+
+ int end = offset + length;
+ for (int i = offset; i < end; ++i) {
+ if (header[i] == 0)
+ break;
+
+ if (header[i] == (byte) ' ' || header[i] == '0') {
+ if (stillPadding)
+ continue;
+
+ if (header[i] == (byte) ' ')
+ break;
+ }
+
+ stillPadding = false;
+
+ result = ( result << 3 ) + ( header[i] - '0' );
+ }
+
+ return result;
+ }
+
+ /**
+ * Parse an octal integer from a header buffer.
+ *
+ * @param value
+ * @param buf
+ * The header buffer from which to parse.
+ * @param offset
+ * The offset into the buffer from which to parse.
+ * @param length
+ * The number of header bytes to parse.
+ *
+ * @return The integer value of the octal bytes.
+ */
+ public static int getOctalBytes(long value, byte[] buf, int offset, int length) {
+ int idx = length - 1;
+
+ buf[offset + idx] = 0;
+ --idx;
+ buf[offset + idx] = (byte) ' ';
+ --idx;
+
+ if (value == 0) {
+ buf[offset + idx] = (byte) '0';
+ --idx;
+ } else {
+ for (long val = value; idx >= 0 && val > 0; --idx) {
+ buf[offset + idx] = (byte) ( (byte) '0' + (byte) ( val & 7 ) );
+ val = val >> 3;
+ }
+ }
+
+ for (; idx >= 0; --idx) {
+ buf[offset + idx] = (byte) ' ';
+ }
+
+ return offset + length;
+ }
+
+ /**
+ * Parse the checksum octal integer from a header buffer.
+ *
+ * @param value
+ * @param buf
+ * The header buffer from which to parse.
+ * @param offset
+ * The offset into the buffer from which to parse.
+ * @param length
+ * The number of header bytes to parse.
+ * @return The integer value of the entry's checksum.
+ */
+ public static int getCheckSumOctalBytes(long value, byte[] buf, int offset, int length) {
+ getOctalBytes( value, buf, offset, length );
+ buf[offset + length - 1] = (byte) ' ';
+ buf[offset + length - 2] = 0;
+ return offset + length;
+ }
+
+ /**
+ * Parse an octal long integer from a header buffer.
+ *
+ * @param value
+ * @param buf
+ * The header buffer from which to parse.
+ * @param offset
+ * The offset into the buffer from which to parse.
+ * @param length
+ * The number of header bytes to parse.
+ *
+ * @return The long value of the octal bytes.
+ */
+ public static int getLongOctalBytes(long value, byte[] buf, int offset, int length) {
+ byte[] temp = new byte[length + 1];
+ getOctalBytes( value, temp, 0, length + 1 );
+ System.arraycopy( temp, 0, buf, offset, length );
+ return offset + length;
+ }
+
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarConstants.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarConstants.java
new file mode 100755
index 0000000..4611e20
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarConstants.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright 2012 Kamran Zafar
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.kamranzafar.jtar;
+
+/**
+ * @author Kamran Zafar
+ *
+ */
+public class TarConstants {
+ public static final int EOF_BLOCK = 1024;
+ public static final int DATA_BLOCK = 512;
+ public static final int HEADER_BLOCK = 512;
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarEntry.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarEntry.java
new file mode 100755
index 0000000..fe01db4
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarEntry.java
@@ -0,0 +1,284 @@
+/**
+ * Copyright 2012 Kamran Zafar
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.kamranzafar.jtar;
+
+import java.io.File;
+import java.util.Date;
+
+/**
+ * @author Kamran Zafar
+ *
+ */
+public class TarEntry {
+ protected File file;
+ protected TarHeader header;
+
+ private TarEntry() {
+ this.file = null;
+ header = new TarHeader();
+ }
+
+ public TarEntry(File file, String entryName) {
+ this();
+ this.file = file;
+ this.extractTarHeader(entryName);
+ }
+
+ public TarEntry(byte[] headerBuf) {
+ this();
+ this.parseTarHeader(headerBuf);
+ }
+
+ /**
+ * Constructor to create an entry from an existing TarHeader object.
+ *
+ * This method is useful to add new entries programmatically (e.g. for
+ * adding files or directories that do not exist in the file system).
+ *
+ * @param header
+ *
+ */
+ public TarEntry(TarHeader header) {
+ this.file = null;
+ this.header = header;
+ }
+
+ public boolean equals(TarEntry it) {
+ return header.name.toString().equals(it.header.name.toString());
+ }
+
+ public boolean isDescendent(TarEntry desc) {
+ return desc.header.name.toString().startsWith(header.name.toString());
+ }
+
+ public TarHeader getHeader() {
+ return header;
+ }
+
+ public String getName() {
+ String name = header.name.toString();
+ if (header.namePrefix != null && !header.namePrefix.toString().equals("")) {
+ name = header.namePrefix.toString() + "/" + name;
+ }
+
+ return name;
+ }
+
+ public void setName(String name) {
+ header.name = new StringBuffer(name);
+ }
+
+ public int getUserId() {
+ return header.userId;
+ }
+
+ public void setUserId(int userId) {
+ header.userId = userId;
+ }
+
+ public int getGroupId() {
+ return header.groupId;
+ }
+
+ public void setGroupId(int groupId) {
+ header.groupId = groupId;
+ }
+
+ public String getUserName() {
+ return header.userName.toString();
+ }
+
+ public void setUserName(String userName) {
+ header.userName = new StringBuffer(userName);
+ }
+
+ public String getGroupName() {
+ return header.groupName.toString();
+ }
+
+ public void setGroupName(String groupName) {
+ header.groupName = new StringBuffer(groupName);
+ }
+
+ public void setIds(int userId, int groupId) {
+ this.setUserId(userId);
+ this.setGroupId(groupId);
+ }
+
+ public void setModTime(long time) {
+ header.modTime = time / 1000;
+ }
+
+ public void setModTime(Date time) {
+ header.modTime = time.getTime() / 1000;
+ }
+
+ public Date getModTime() {
+ return new Date(header.modTime * 1000);
+ }
+
+ public File getFile() {
+ return this.file;
+ }
+
+ public long getSize() {
+ return header.size;
+ }
+
+ public void setSize(long size) {
+ header.size = size;
+ }
+
+ /**
+ * Checks if the org.kamrazafar.jtar entry is a directory
+ *
+ * @return
+ */
+ public boolean isDirectory() {
+ if (this.file != null)
+ return this.file.isDirectory();
+
+ if (header != null) {
+ if (header.linkFlag == TarHeader.LF_DIR)
+ return true;
+
+ if (header.name.toString().endsWith("/"))
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Extract header from File
+ *
+ * @param entryName
+ */
+ public void extractTarHeader(String entryName) {
+ header = TarHeader.createHeader(entryName, file.length(), file.lastModified() / 1000, file.isDirectory());
+ }
+
+ /**
+ * Calculate checksum
+ *
+ * @param buf
+ * @return
+ */
+ public long computeCheckSum(byte[] buf) {
+ long sum = 0;
+
+ for (int i = 0; i < buf.length; ++i) {
+ sum += 255 & buf[i];
+ }
+
+ return sum;
+ }
+
+ /**
+ * Writes the header to the byte buffer
+ *
+ * @param outbuf
+ */
+ public void writeEntryHeader(byte[] outbuf) {
+ int offset = 0;
+
+ offset = TarHeader.getNameBytes(header.name, outbuf, offset, TarHeader.NAMELEN);
+ offset = Octal.getOctalBytes(header.mode, outbuf, offset, TarHeader.MODELEN);
+ offset = Octal.getOctalBytes(header.userId, outbuf, offset, TarHeader.UIDLEN);
+ offset = Octal.getOctalBytes(header.groupId, outbuf, offset, TarHeader.GIDLEN);
+
+ long size = header.size;
+
+ offset = Octal.getLongOctalBytes(size, outbuf, offset, TarHeader.SIZELEN);
+ offset = Octal.getLongOctalBytes(header.modTime, outbuf, offset, TarHeader.MODTIMELEN);
+
+ int csOffset = offset;
+ for (int c = 0; c < TarHeader.CHKSUMLEN; ++c)
+ outbuf[offset++] = (byte) ' ';
+
+ outbuf[offset++] = header.linkFlag;
+
+ offset = TarHeader.getNameBytes(header.linkName, outbuf, offset, TarHeader.NAMELEN);
+ offset = TarHeader.getNameBytes(header.magic, outbuf, offset, TarHeader.USTAR_MAGICLEN);
+ offset = TarHeader.getNameBytes(header.userName, outbuf, offset, TarHeader.USTAR_USER_NAMELEN);
+ offset = TarHeader.getNameBytes(header.groupName, outbuf, offset, TarHeader.USTAR_GROUP_NAMELEN);
+ offset = Octal.getOctalBytes(header.devMajor, outbuf, offset, TarHeader.USTAR_DEVLEN);
+ offset = Octal.getOctalBytes(header.devMinor, outbuf, offset, TarHeader.USTAR_DEVLEN);
+ offset = TarHeader.getNameBytes(header.namePrefix, outbuf, offset, TarHeader.USTAR_FILENAME_PREFIX);
+
+ for (; offset < outbuf.length;)
+ outbuf[offset++] = 0;
+
+ long checkSum = this.computeCheckSum(outbuf);
+
+ Octal.getCheckSumOctalBytes(checkSum, outbuf, csOffset, TarHeader.CHKSUMLEN);
+ }
+
+ /**
+ * Parses the tar header to the byte buffer
+ *
+ * @param header
+ * @param bh
+ */
+ public void parseTarHeader(byte[] bh) {
+ int offset = 0;
+
+ header.name = TarHeader.parseName(bh, offset, TarHeader.NAMELEN);
+ offset += TarHeader.NAMELEN;
+
+ header.mode = (int) Octal.parseOctal(bh, offset, TarHeader.MODELEN);
+ offset += TarHeader.MODELEN;
+
+ header.userId = (int) Octal.parseOctal(bh, offset, TarHeader.UIDLEN);
+ offset += TarHeader.UIDLEN;
+
+ header.groupId = (int) Octal.parseOctal(bh, offset, TarHeader.GIDLEN);
+ offset += TarHeader.GIDLEN;
+
+ header.size = Octal.parseOctal(bh, offset, TarHeader.SIZELEN);
+ offset += TarHeader.SIZELEN;
+
+ header.modTime = Octal.parseOctal(bh, offset, TarHeader.MODTIMELEN);
+ offset += TarHeader.MODTIMELEN;
+
+ header.checkSum = (int) Octal.parseOctal(bh, offset, TarHeader.CHKSUMLEN);
+ offset += TarHeader.CHKSUMLEN;
+
+ header.linkFlag = bh[offset++];
+
+ header.linkName = TarHeader.parseName(bh, offset, TarHeader.NAMELEN);
+ offset += TarHeader.NAMELEN;
+
+ header.magic = TarHeader.parseName(bh, offset, TarHeader.USTAR_MAGICLEN);
+ offset += TarHeader.USTAR_MAGICLEN;
+
+ header.userName = TarHeader.parseName(bh, offset, TarHeader.USTAR_USER_NAMELEN);
+ offset += TarHeader.USTAR_USER_NAMELEN;
+
+ header.groupName = TarHeader.parseName(bh, offset, TarHeader.USTAR_GROUP_NAMELEN);
+ offset += TarHeader.USTAR_GROUP_NAMELEN;
+
+ header.devMajor = (int) Octal.parseOctal(bh, offset, TarHeader.USTAR_DEVLEN);
+ offset += TarHeader.USTAR_DEVLEN;
+
+ header.devMinor = (int) Octal.parseOctal(bh, offset, TarHeader.USTAR_DEVLEN);
+ offset += TarHeader.USTAR_DEVLEN;
+
+ header.namePrefix = TarHeader.parseName(bh, offset, TarHeader.USTAR_FILENAME_PREFIX);
+ }
+}
\ No newline at end of file
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarHeader.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarHeader.java
new file mode 100755
index 0000000..b9d3a86
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarHeader.java
@@ -0,0 +1,243 @@
+/**
+ * Copyright 2012 Kamran Zafar
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.kamranzafar.jtar;
+
+import java.io.File;
+
+/**
+ * Header
+ *
+ *
+ * Offset Size Field
+ * 0 100 File name
+ * 100 8 File mode
+ * 108 8 Owner's numeric user ID
+ * 116 8 Group's numeric user ID
+ * 124 12 File size in bytes
+ * 136 12 Last modification time in numeric Unix time format
+ * 148 8 Checksum for header block
+ * 156 1 Link indicator (file type)
+ * 157 100 Name of linked file
+ *
+ *
+ *
+ * File Types
+ *
+ *
+ * Value Meaning
+ * '0' Normal file
+ * (ASCII NUL) Normal file (now obsolete)
+ * '1' Hard link
+ * '2' Symbolic link
+ * '3' Character special
+ * '4' Block special
+ * '5' Directory
+ * '6' FIFO
+ * '7' Contigous
+ *
+ *
+ *
+ *
+ * Ustar header
+ *
+ *
+ * Offset Size Field
+ * 257 6 UStar indicator "ustar"
+ * 263 2 UStar version "00"
+ * 265 32 Owner user name
+ * 297 32 Owner group name
+ * 329 8 Device major number
+ * 337 8 Device minor number
+ * 345 155 Filename prefix
+ *
+ */
+
+public class TarHeader {
+
+ /*
+ * Header
+ */
+ public static final int NAMELEN = 100;
+ public static final int MODELEN = 8;
+ public static final int UIDLEN = 8;
+ public static final int GIDLEN = 8;
+ public static final int SIZELEN = 12;
+ public static final int MODTIMELEN = 12;
+ public static final int CHKSUMLEN = 8;
+ public static final byte LF_OLDNORM = 0;
+
+ /*
+ * File Types
+ */
+ public static final byte LF_NORMAL = (byte) '0';
+ public static final byte LF_LINK = (byte) '1';
+ public static final byte LF_SYMLINK = (byte) '2';
+ public static final byte LF_CHR = (byte) '3';
+ public static final byte LF_BLK = (byte) '4';
+ public static final byte LF_DIR = (byte) '5';
+ public static final byte LF_FIFO = (byte) '6';
+ public static final byte LF_CONTIG = (byte) '7';
+
+ /*
+ * Ustar header
+ */
+
+ public static final String USTAR_MAGIC = "ustar"; // POSIX
+
+ public static final int USTAR_MAGICLEN = 8;
+ public static final int USTAR_USER_NAMELEN = 32;
+ public static final int USTAR_GROUP_NAMELEN = 32;
+ public static final int USTAR_DEVLEN = 8;
+ public static final int USTAR_FILENAME_PREFIX = 155;
+
+ // Header values
+ public StringBuffer name;
+ public int mode;
+ public int userId;
+ public int groupId;
+ public long size;
+ public long modTime;
+ public int checkSum;
+ public byte linkFlag;
+ public StringBuffer linkName;
+ public StringBuffer magic; // ustar indicator and version
+ public StringBuffer userName;
+ public StringBuffer groupName;
+ public int devMajor;
+ public int devMinor;
+ public StringBuffer namePrefix;
+
+ public TarHeader() {
+ this.magic = new StringBuffer(TarHeader.USTAR_MAGIC);
+
+ this.name = new StringBuffer();
+ this.linkName = new StringBuffer();
+
+ String user = System.getProperty("user.name", "");
+
+ if (user.length() > 31)
+ user = user.substring(0, 31);
+
+ this.userId = 0;
+ this.groupId = 0;
+ this.userName = new StringBuffer(user);
+ this.groupName = new StringBuffer("");
+ this.namePrefix = new StringBuffer();
+ }
+
+ /**
+ * Parse an entry name from a header buffer.
+ *
+ * @param name
+ * @param header
+ * The header buffer from which to parse.
+ * @param offset
+ * The offset into the buffer from which to parse.
+ * @param length
+ * The number of header bytes to parse.
+ * @return The header's entry name.
+ */
+ public static StringBuffer parseName(byte[] header, int offset, int length) {
+ StringBuffer result = new StringBuffer(length);
+
+ int end = offset + length;
+ for (int i = offset; i < end; ++i) {
+ if (header[i] == 0)
+ break;
+ result.append((char) header[i]);
+ }
+
+ return result;
+ }
+
+ /**
+ * Determine the number of bytes in an entry name.
+ *
+ * @param name
+ * @param header
+ * The header buffer from which to parse.
+ * @param offset
+ * The offset into the buffer from which to parse.
+ * @param length
+ * The number of header bytes to parse.
+ * @return The number of bytes in a header's entry name.
+ */
+ public static int getNameBytes(StringBuffer name, byte[] buf, int offset, int length) {
+ int i;
+
+ for (i = 0; i < length && i < name.length(); ++i) {
+ buf[offset + i] = (byte) name.charAt(i);
+ }
+
+ for (; i < length; ++i) {
+ buf[offset + i] = 0;
+ }
+
+ return offset + length;
+ }
+
+ /**
+ * Creates a new header for a file/directory entry.
+ *
+ *
+ * @param name
+ * File name
+ * @param size
+ * File size in bytes
+ * @param modTime
+ * Last modification time in numeric Unix time format
+ * @param dir
+ * Is directory
+ *
+ * @return
+ */
+ public static TarHeader createHeader(String entryName, long size, long modTime, boolean dir) {
+ String name = entryName;
+ name = TarUtils.trim(name.replace(File.separatorChar, '/'), '/');
+
+ TarHeader header = new TarHeader();
+ header.linkName = new StringBuffer("");
+
+ if (name.length() > 100) {
+ header.namePrefix = new StringBuffer(name.substring(0, name.lastIndexOf('/')));
+ header.name = new StringBuffer(name.substring(name.lastIndexOf('/') + 1));
+ } else {
+ header.name = new StringBuffer(name);
+ }
+
+ if (dir) {
+ header.mode = 040755;
+ header.linkFlag = TarHeader.LF_DIR;
+ if (header.name.charAt(header.name.length() - 1) != '/') {
+ header.name.append("/");
+ }
+ header.size = 0;
+ } else {
+ header.mode = 0100644;
+ header.linkFlag = TarHeader.LF_NORMAL;
+ header.size = size;
+ }
+
+ header.modTime = modTime;
+ header.checkSum = 0;
+ header.devMajor = 0;
+ header.devMinor = 0;
+
+ return header;
+ }
+}
\ No newline at end of file
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarInputStream.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarInputStream.java
new file mode 100755
index 0000000..ec50a1b
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarInputStream.java
@@ -0,0 +1,249 @@
+/**
+ * Copyright 2012 Kamran Zafar
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.kamranzafar.jtar;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author Kamran Zafar
+ *
+ */
+public class TarInputStream extends FilterInputStream {
+
+ private static final int SKIP_BUFFER_SIZE = 2048;
+ private TarEntry currentEntry;
+ private long currentFileSize;
+ private long bytesRead;
+ private boolean defaultSkip = false;
+
+ public TarInputStream(InputStream in) {
+ super(in);
+ currentFileSize = 0;
+ bytesRead = 0;
+ }
+
+ @Override
+ public boolean markSupported() {
+ return false;
+ }
+
+ /**
+ * Not supported
+ *
+ */
+ @Override
+ public synchronized void mark(int readlimit) {
+ }
+
+ /**
+ * Not supported
+ *
+ */
+ @Override
+ public synchronized void reset() throws IOException {
+ throw new IOException("mark/reset not supported");
+ }
+
+ /**
+ * Read a byte
+ *
+ * @see java.io.FilterInputStream#read()
+ */
+ @Override
+ public int read() throws IOException {
+ byte[] buf = new byte[1];
+
+ int res = this.read(buf, 0, 1);
+
+ if (res != -1) {
+ return 0xFF & buf[0];
+ }
+
+ return res;
+ }
+
+ /**
+ * Checks if the bytes being read exceed the entry size and adjusts the byte
+ * array length. Updates the byte counters
+ *
+ *
+ * @see java.io.FilterInputStream#read(byte[], int, int)
+ */
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (currentEntry != null) {
+ if (currentFileSize == currentEntry.getSize()) {
+ return -1;
+ } else if ((currentEntry.getSize() - currentFileSize) < len) {
+ len = (int) (currentEntry.getSize() - currentFileSize);
+ }
+ }
+
+ int br = super.read(b, off, len);
+
+ if (br != -1) {
+ if (currentEntry != null) {
+ currentFileSize += br;
+ }
+
+ bytesRead += br;
+ }
+
+ return br;
+ }
+
+ /**
+ * Returns the next entry in the tar file
+ *
+ * @return TarEntry
+ * @throws IOException
+ */
+ public TarEntry getNextEntry() throws IOException {
+ closeCurrentEntry();
+
+ byte[] header = new byte[TarConstants.HEADER_BLOCK];
+ byte[] theader = new byte[TarConstants.HEADER_BLOCK];
+ int tr = 0;
+
+ // Read full header
+ while (tr < TarConstants.HEADER_BLOCK) {
+ int res = read(theader, 0, TarConstants.HEADER_BLOCK - tr);
+
+ if (res < 0) {
+ break;
+ }
+
+ System.arraycopy(theader, 0, header, tr, res);
+ tr += res;
+ }
+
+ // Check if record is null
+ boolean eof = true;
+ for (byte b : header) {
+ if (b != 0) {
+ eof = false;
+ break;
+ }
+ }
+
+ if (!eof) {
+ currentEntry = new TarEntry(header);
+ }
+
+ return currentEntry;
+ }
+
+ /**
+ * Returns the current offset (in bytes) from the beginning of the stream.
+ * This can be used to find out at which point in a tar file an entry's content begins, for instance.
+ */
+ public long getCurrentOffset() {
+ return bytesRead;
+ }
+
+ /**
+ * Closes the current tar entry
+ *
+ * @throws IOException
+ */
+ protected void closeCurrentEntry() throws IOException {
+ if (currentEntry != null) {
+ if (currentEntry.getSize() > currentFileSize) {
+ // Not fully read, skip rest of the bytes
+ long bs = 0;
+ while (bs < currentEntry.getSize() - currentFileSize) {
+ long res = skip(currentEntry.getSize() - currentFileSize - bs);
+
+ if (res == 0 && currentEntry.getSize() - currentFileSize > 0) {
+ // I suspect file corruption
+ throw new IOException("Possible tar file corruption");
+ }
+
+ bs += res;
+ }
+ }
+
+ currentEntry = null;
+ currentFileSize = 0L;
+ skipPad();
+ }
+ }
+
+ /**
+ * Skips the pad at the end of each tar entry file content
+ *
+ * @throws IOException
+ */
+ protected void skipPad() throws IOException {
+ if (bytesRead > 0) {
+ int extra = (int) (bytesRead % TarConstants.DATA_BLOCK);
+
+ if (extra > 0) {
+ long bs = 0;
+ while (bs < TarConstants.DATA_BLOCK - extra) {
+ long res = skip(TarConstants.DATA_BLOCK - extra - bs);
+ bs += res;
+ }
+ }
+ }
+ }
+
+ /**
+ * Skips 'n' bytes on the InputStream
+ * Overrides default implementation of skip
+ *
+ */
+ @Override
+ public long skip(long n) throws IOException {
+ if (defaultSkip) {
+ // use skip method of parent stream
+ // may not work if skip not implemented by parent
+ long bs = super.skip(n);
+ bytesRead += bs;
+
+ return bs;
+ }
+
+ if (n <= 0) {
+ return 0;
+ }
+
+ long left = n;
+ byte[] sBuff = new byte[SKIP_BUFFER_SIZE];
+
+ while (left > 0) {
+ int res = read(sBuff, 0, (int) (left < SKIP_BUFFER_SIZE ? left : SKIP_BUFFER_SIZE));
+ if (res < 0) {
+ break;
+ }
+ left -= res;
+ }
+
+ return n - left;
+ }
+
+ public boolean isDefaultSkip() {
+ return defaultSkip;
+ }
+
+ public void setDefaultSkip(boolean defaultSkip) {
+ this.defaultSkip = defaultSkip;
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarOutputStream.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarOutputStream.java
new file mode 100755
index 0000000..ffdfe87
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarOutputStream.java
@@ -0,0 +1,163 @@
+/**
+ * Copyright 2012 Kamran Zafar
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.kamranzafar.jtar;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+
+/**
+ * @author Kamran Zafar
+ *
+ */
+public class TarOutputStream extends OutputStream {
+ private final OutputStream out;
+ private long bytesWritten;
+ private long currentFileSize;
+ private TarEntry currentEntry;
+
+ public TarOutputStream(OutputStream out) {
+ this.out = out;
+ bytesWritten = 0;
+ currentFileSize = 0;
+ }
+
+ public TarOutputStream(final File fout) throws FileNotFoundException {
+ this.out = new BufferedOutputStream(new FileOutputStream(fout));
+ bytesWritten = 0;
+ currentFileSize = 0;
+ }
+
+ /**
+ * Opens a file for writing.
+ */
+ public TarOutputStream(final File fout, final boolean append) throws IOException {
+ @SuppressWarnings("resource")
+ RandomAccessFile raf = new RandomAccessFile(fout, "rw");
+ final long fileSize = fout.length();
+ if (append && fileSize > TarConstants.EOF_BLOCK) {
+ raf.seek(fileSize - TarConstants.EOF_BLOCK);
+ }
+ out = new BufferedOutputStream(new FileOutputStream(raf.getFD()));
+ }
+
+ /**
+ * Appends the EOF record and closes the stream
+ *
+ * @see java.io.FilterOutputStream#close()
+ */
+ @Override
+ public void close() throws IOException {
+ closeCurrentEntry();
+ write( new byte[TarConstants.EOF_BLOCK] );
+ out.close();
+ }
+ /**
+ * Writes a byte to the stream and updates byte counters
+ *
+ * @see java.io.FilterOutputStream#write(int)
+ */
+ @Override
+ public void write(int b) throws IOException {
+ out.write( b );
+ bytesWritten += 1;
+
+ if (currentEntry != null) {
+ currentFileSize += 1;
+ }
+ }
+
+ /**
+ * Checks if the bytes being written exceed the current entry size.
+ *
+ * @see java.io.FilterOutputStream#write(byte[], int, int)
+ */
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (currentEntry != null && !currentEntry.isDirectory()) {
+ if (currentEntry.getSize() < currentFileSize + len) {
+ throw new IOException( "The current entry[" + currentEntry.getName() + "] size["
+ + currentEntry.getSize() + "] is smaller than the bytes[" + ( currentFileSize + len )
+ + "] being written." );
+ }
+ }
+
+ out.write( b, off, len );
+
+ bytesWritten += len;
+
+ if (currentEntry != null) {
+ currentFileSize += len;
+ }
+ }
+
+ /**
+ * Writes the next tar entry header on the stream
+ *
+ * @param entry
+ * @throws IOException
+ */
+ public void putNextEntry(TarEntry entry) throws IOException {
+ closeCurrentEntry();
+
+ byte[] header = new byte[TarConstants.HEADER_BLOCK];
+ entry.writeEntryHeader( header );
+
+ write( header );
+
+ currentEntry = entry;
+ }
+
+ /**
+ * Closes the current tar entry
+ *
+ * @throws IOException
+ */
+ protected void closeCurrentEntry() throws IOException {
+ if (currentEntry != null) {
+ if (currentEntry.getSize() > currentFileSize) {
+ throw new IOException( "The current entry[" + currentEntry.getName() + "] of size["
+ + currentEntry.getSize() + "] has not been fully written." );
+ }
+
+ currentEntry = null;
+ currentFileSize = 0;
+
+ pad();
+ }
+ }
+
+ /**
+ * Pads the last content block
+ *
+ * @throws IOException
+ */
+ protected void pad() throws IOException {
+ if (bytesWritten > 0) {
+ int extra = (int) ( bytesWritten % TarConstants.DATA_BLOCK );
+
+ if (extra > 0) {
+ write( new byte[TarConstants.DATA_BLOCK - extra] );
+ }
+ }
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarUtils.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarUtils.java
new file mode 100755
index 0000000..5016576
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kamranzafar/jtar/TarUtils.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright 2012 Kamran Zafar
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.kamranzafar.jtar;
+
+import java.io.File;
+
+/**
+ * @author Kamran
+ *
+ */
+public class TarUtils {
+ /**
+ * Determines the tar file size of the given folder/file path
+ *
+ * @param path
+ * @return
+ */
+ public static long calculateTarSize(File path) {
+ return tarSize(path) + TarConstants.EOF_BLOCK;
+ }
+
+ private static long tarSize(File dir) {
+ long size = 0;
+
+ if (dir.isFile()) {
+ return entrySize(dir.length());
+ } else {
+ File[] subFiles = dir.listFiles();
+
+ if (subFiles != null && subFiles.length > 0) {
+ for (File file : subFiles) {
+ if (file.isFile()) {
+ size += entrySize(file.length());
+ } else {
+ size += tarSize(file);
+ }
+ }
+ } else {
+ // Empty folder header
+ return TarConstants.HEADER_BLOCK;
+ }
+ }
+
+ return size;
+ }
+
+ private static long entrySize(long fileSize) {
+ long size = 0;
+ size += TarConstants.HEADER_BLOCK; // Header
+ size += fileSize; // File size
+
+ long extra = size % TarConstants.DATA_BLOCK;
+
+ if (extra > 0) {
+ size += (TarConstants.DATA_BLOCK - extra); // pad
+ }
+
+ return size;
+ }
+
+ public static String trim(String s, char c) {
+ StringBuffer tmp = new StringBuffer(s);
+ for (int i = 0; i < tmp.length(); i++) {
+ if (tmp.charAt(i) != c) {
+ break;
+ } else {
+ tmp.deleteCharAt(i);
+ }
+ }
+
+ for (int i = tmp.length() - 1; i >= 0; i--) {
+ if (tmp.charAt(i) != c) {
+ break;
+ } else {
+ tmp.deleteCharAt(i);
+ }
+ }
+
+ return tmp.toString();
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/GenericBroadcastReceiver.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/GenericBroadcastReceiver.java
new file mode 100644
index 0000000..58a1c5e
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/GenericBroadcastReceiver.java
@@ -0,0 +1,19 @@
+package org.kivy.android;
+
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.Context;
+
+public class GenericBroadcastReceiver extends BroadcastReceiver {
+
+ GenericBroadcastReceiverCallback listener;
+
+ public GenericBroadcastReceiver(GenericBroadcastReceiverCallback listener) {
+ super();
+ this.listener = listener;
+ }
+
+ public void onReceive(Context context, Intent intent) {
+ this.listener.onReceive(context, intent);
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/GenericBroadcastReceiverCallback.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/GenericBroadcastReceiverCallback.java
new file mode 100644
index 0000000..1a87c98
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/GenericBroadcastReceiverCallback.java
@@ -0,0 +1,8 @@
+package org.kivy.android;
+
+import android.content.Intent;
+import android.content.Context;
+
+public interface GenericBroadcastReceiverCallback {
+ void onReceive(Context context, Intent intent);
+};
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonActivity.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonActivity.java
new file mode 100644
index 0000000..b2f4a45
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonActivity.java
@@ -0,0 +1,479 @@
+
+package org.kivy.android;
+
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+
+import android.view.ViewGroup;
+import android.view.SurfaceView;
+import android.app.Activity;
+import android.content.Intent;
+import android.util.Log;
+import android.widget.Toast;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.graphics.PixelFormat;
+import android.view.SurfaceHolder;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ApplicationInfo;
+import android.content.Intent;
+import android.widget.ImageView;
+import java.io.InputStream;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+
+import org.libsdl.app.SDLActivity;
+
+import org.kivy.android.PythonUtil;
+import org.kivy.android.launcher.Project;
+
+import org.renpy.android.ResourceManager;
+import org.renpy.android.AssetExtract;
+
+
+public class PythonActivity extends SDLActivity {
+ private static final String TAG = "PythonActivity";
+
+ public static PythonActivity mActivity = null;
+
+ private ResourceManager resourceManager = null;
+ private Bundle mMetaData = null;
+ private PowerManager.WakeLock mWakeLock = null;
+
+ public String getAppRoot() {
+ String app_root = getFilesDir().getAbsolutePath() + "/app";
+ return app_root;
+ }
+
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ Log.v(TAG, "My oncreate running");
+ resourceManager = new ResourceManager(this);
+
+ Log.v(TAG, "About to do super onCreate");
+ super.onCreate(savedInstanceState);
+ Log.v(TAG, "Did super onCreate");
+
+ this.mActivity = this;
+ this.showLoadingScreen();
+
+ new UnpackFilesTask().execute(getAppRoot());
+ }
+
+ public void loadLibraries() {
+ String app_root = new String(getAppRoot());
+ File app_root_file = new File(app_root);
+ PythonUtil.loadLibraries(app_root_file, new File(getApplicationInfo().nativeLibraryDir));
+ }
+
+ public void recursiveDelete(File f) {
+ if (f.isDirectory()) {
+ for (File r : f.listFiles()) {
+ recursiveDelete(r);
+ }
+ }
+ f.delete();
+ }
+
+ /**
+ * Show an error using a toast. (Only makes sense from non-UI
+ * threads.)
+ */
+ public void toastError(final String msg) {
+
+ final Activity thisActivity = this;
+
+ runOnUiThread(new Runnable () {
+ public void run() {
+ Toast.makeText(thisActivity, msg, Toast.LENGTH_LONG).show();
+ }
+ });
+
+ // Wait to show the error.
+ synchronized (this) {
+ try {
+ this.wait(1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ private class UnpackFilesTask extends AsyncTask {
+ @Override
+ protected String doInBackground(String... params) {
+ File app_root_file = new File(params[0]);
+ Log.v(TAG, "Ready to unpack");
+ unpackData("private", app_root_file);
+ return null;
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ // Figure out the directory where the game is. If the game was
+ // given to us via an intent, then we use the scheme-specific
+ // part of that intent to determine the file to launch. We
+ // also use the android.txt file to determine the orientation.
+ //
+ // Otherwise, we use the public data, if we have it, or the
+ // private data if we do not.
+ mActivity.finishLoad();
+
+ // finishLoad called setContentView with the SDL view, which
+ // removed the loading screen. However, we still need it to
+ // show until the app is ready to render, so pop it back up
+ // on top of the SDL view.
+ mActivity.showLoadingScreen();
+
+ String app_root_dir = getAppRoot();
+ if (getIntent() != null && getIntent().getAction() != null &&
+ getIntent().getAction().equals("org.kivy.LAUNCH")) {
+ File path = new File(getIntent().getData().getSchemeSpecificPart());
+
+ Project p = Project.scanDirectory(path);
+ SDLActivity.nativeSetEnv("ANDROID_ENTRYPOINT", p.dir + "/main.py");
+ SDLActivity.nativeSetEnv("ANDROID_ARGUMENT", p.dir);
+ SDLActivity.nativeSetEnv("ANDROID_APP_PATH", p.dir);
+
+ if (p != null) {
+ if (p.landscape) {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ } else {
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ }
+ }
+
+ // Let old apps know they started.
+ try {
+ FileWriter f = new FileWriter(new File(path, ".launch"));
+ f.write("started");
+ f.close();
+ } catch (IOException e) {
+ // pass
+ }
+ } else {
+ SDLActivity.nativeSetEnv("ANDROID_ENTRYPOINT", "main.pyo");
+ SDLActivity.nativeSetEnv("ANDROID_ARGUMENT", app_root_dir);
+ SDLActivity.nativeSetEnv("ANDROID_APP_PATH", app_root_dir);
+ }
+
+ String mFilesDirectory = mActivity.getFilesDir().getAbsolutePath();
+ Log.v(TAG, "Setting env vars for start.c and Python to use");
+ SDLActivity.nativeSetEnv("ANDROID_PRIVATE", mFilesDirectory);
+ SDLActivity.nativeSetEnv("PYTHONHOME", app_root_dir);
+ SDLActivity.nativeSetEnv("PYTHONPATH", app_root_dir + ":" + app_root_dir + "/lib");
+ SDLActivity.nativeSetEnv("PYTHONOPTIMIZE", "2");
+
+ try {
+ Log.v(TAG, "Access to our meta-data...");
+ mActivity.mMetaData = mActivity.getPackageManager().getApplicationInfo(
+ mActivity.getPackageName(), PackageManager.GET_META_DATA).metaData;
+
+ PowerManager pm = (PowerManager) mActivity.getSystemService(Context.POWER_SERVICE);
+ if ( mActivity.mMetaData.getInt("wakelock") == 1 ) {
+ mActivity.mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "Screen On");
+ mActivity.mWakeLock.acquire();
+ }
+ if ( mActivity.mMetaData.getInt("surface.transparent") != 0 ) {
+ Log.v(TAG, "Surface will be transparent.");
+ getSurface().setZOrderOnTop(true);
+ getSurface().getHolder().setFormat(PixelFormat.TRANSPARENT);
+ } else {
+ Log.i(TAG, "Surface will NOT be transparent");
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ }
+
+ @Override
+ protected void onPreExecute() {
+ }
+
+ @Override
+ protected void onProgressUpdate(Void... values) {
+ }
+ }
+
+ public void unpackData(final String resource, File target) {
+
+ Log.v(TAG, "UNPACKING!!! " + resource + " " + target.getName());
+
+ // The version of data in memory and on disk.
+ String data_version = resourceManager.getString(resource + "_version");
+ String disk_version = null;
+
+ Log.v(TAG, "Data version is " + data_version);
+
+ // If no version, no unpacking is necessary.
+ if (data_version == null) {
+ return;
+ }
+
+ // Check the current disk version, if any.
+ String filesDir = target.getAbsolutePath();
+ String disk_version_fn = filesDir + "/" + resource + ".version";
+
+ try {
+ byte buf[] = new byte[64];
+ InputStream is = new FileInputStream(disk_version_fn);
+ int len = is.read(buf);
+ disk_version = new String(buf, 0, len);
+ is.close();
+ } catch (Exception e) {
+ disk_version = "";
+ }
+
+ // If the disk data is out of date, extract it and write the
+ // version file.
+ // if (! data_version.equals(disk_version)) {
+ if (! data_version.equals(disk_version)) {
+ Log.v(TAG, "Extracting " + resource + " assets.");
+
+ recursiveDelete(target);
+ target.mkdirs();
+
+ AssetExtract ae = new AssetExtract(this);
+ if (!ae.extractTar(resource + ".mp3", target.getAbsolutePath())) {
+ toastError("Could not extract " + resource + " data.");
+ }
+
+ try {
+ // Write .nomedia.
+ new File(target, ".nomedia").createNewFile();
+
+ // Write version file.
+ FileOutputStream os = new FileOutputStream(disk_version_fn);
+ os.write(data_version.getBytes());
+ os.close();
+ } catch (Exception e) {
+ Log.w("python", e);
+ }
+ }
+ }
+
+ public static ViewGroup getLayout() {
+ return mLayout;
+ }
+
+ public static SurfaceView getSurface() {
+ return mSurface;
+ }
+
+ //----------------------------------------------------------------------------
+ // Listener interface for onNewIntent
+ //
+
+ public interface NewIntentListener {
+ void onNewIntent(Intent intent);
+ }
+
+ private List newIntentListeners = null;
+
+ public void registerNewIntentListener(NewIntentListener listener) {
+ if ( this.newIntentListeners == null )
+ this.newIntentListeners = Collections.synchronizedList(new ArrayList());
+ this.newIntentListeners.add(listener);
+ }
+
+ public void unregisterNewIntentListener(NewIntentListener listener) {
+ if ( this.newIntentListeners == null )
+ return;
+ this.newIntentListeners.remove(listener);
+ }
+
+ @Override
+ protected void onNewIntent(Intent intent) {
+ if ( this.newIntentListeners == null )
+ return;
+ this.onResume();
+ synchronized ( this.newIntentListeners ) {
+ Iterator iterator = this.newIntentListeners.iterator();
+ while ( iterator.hasNext() ) {
+ (iterator.next()).onNewIntent(intent);
+ }
+ }
+ }
+
+ //----------------------------------------------------------------------------
+ // Listener interface for onActivityResult
+ //
+
+ public interface ActivityResultListener {
+ void onActivityResult(int requestCode, int resultCode, Intent data);
+ }
+
+ private List activityResultListeners = null;
+
+ public void registerActivityResultListener(ActivityResultListener listener) {
+ if ( this.activityResultListeners == null )
+ this.activityResultListeners = Collections.synchronizedList(new ArrayList());
+ this.activityResultListeners.add(listener);
+ }
+
+ public void unregisterActivityResultListener(ActivityResultListener listener) {
+ if ( this.activityResultListeners == null )
+ return;
+ this.activityResultListeners.remove(listener);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
+ if ( this.activityResultListeners == null )
+ return;
+ this.onResume();
+ synchronized ( this.activityResultListeners ) {
+ Iterator iterator = this.activityResultListeners.iterator();
+ while ( iterator.hasNext() )
+ (iterator.next()).onActivityResult(requestCode, resultCode, intent);
+ }
+ }
+
+ public static void start_service(String serviceTitle, String serviceDescription,
+ String pythonServiceArgument) {
+ Intent serviceIntent = new Intent(PythonActivity.mActivity, PythonService.class);
+ String argument = PythonActivity.mActivity.getFilesDir().getAbsolutePath();
+ String filesDirectory = argument;
+ String app_root_dir = PythonActivity.mActivity.getAppRoot();
+ serviceIntent.putExtra("androidPrivate", argument);
+ serviceIntent.putExtra("androidArgument", app_root_dir);
+ serviceIntent.putExtra("serviceEntrypoint", "service/main.pyo");
+ serviceIntent.putExtra("pythonHome", app_root_dir);
+ serviceIntent.putExtra("pythonPath", app_root_dir + ":" + app_root_dir + "/lib");
+ serviceIntent.putExtra("serviceTitle", serviceTitle);
+ serviceIntent.putExtra("serviceDescription", serviceDescription);
+ serviceIntent.putExtra("pythonServiceArgument", pythonServiceArgument);
+ PythonActivity.mActivity.startService(serviceIntent);
+ }
+
+ public static void stop_service() {
+ Intent serviceIntent = new Intent(PythonActivity.mActivity, PythonService.class);
+ PythonActivity.mActivity.stopService(serviceIntent);
+ }
+
+ /** Loading screen implementation
+ * keepActive() is a method plugged in pollInputDevices in SDLActivity.
+ * Once it's called twice, the loading screen will be removed.
+ * The first call happen as soon as the window is created, but no image has been
+ * displayed first. My tests showed that we can wait one more. This might delay
+ * the real available of few hundred milliseconds.
+ * The real deal is to know if a rendering has already happen. The previous
+ * python-for-android and kivy was having something for that, but this new version
+ * is not compatible, and would require a new kivy version.
+ * In case of, the method PythonActivty.mActivity.removeLoadingScreen() can be called.
+ */
+ public static ImageView mImageView = null;
+ int mLoadingCount = 2;
+
+ @Override
+ public void keepActive() {
+ if (this.mLoadingCount > 0) {
+ this.mLoadingCount -= 1;
+ if (this.mLoadingCount == 0) {
+ this.removeLoadingScreen();
+ }
+ }
+ }
+
+ public void removeLoadingScreen() {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ if (PythonActivity.mImageView != null &&
+ PythonActivity.mImageView.getParent() != null) {
+ ((ViewGroup)PythonActivity.mImageView.getParent()).removeView(
+ PythonActivity.mImageView);
+ PythonActivity.mImageView = null;
+ }
+ }
+ });
+ }
+
+
+ protected void showLoadingScreen() {
+ // load the bitmap
+ // 1. if the image is valid and we don't have layout yet, assign this bitmap
+ // as main view.
+ // 2. if we have a layout, just set it in the layout.
+ // 3. If we have an mImageView already, then do nothing because it will have
+ // already been made the content view or added to the layout.
+
+ if (mImageView == null) {
+ int presplashId = this.resourceManager.getIdentifier("presplash", "drawable");
+ InputStream is = this.getResources().openRawResource(presplashId);
+ Bitmap bitmap = null;
+ try {
+ bitmap = BitmapFactory.decodeStream(is);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {};
+ }
+
+ mImageView = new ImageView(this);
+ mImageView.setImageBitmap(bitmap);
+
+ /*
+ * Set the presplash loading screen background color
+ * https://developer.android.com/reference/android/graphics/Color.html
+ * Parse the color string, and return the corresponding color-int.
+ * If the string cannot be parsed, throws an IllegalArgumentException exception.
+ * Supported formats are: #RRGGBB #AARRGGBB or one of the following names:
+ * 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', 'yellow',
+ * 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey', 'aqua', 'fuchsia',
+ * 'lime', 'maroon', 'navy', 'olive', 'purple', 'silver', 'teal'.
+ */
+ String backgroundColor = resourceManager.getString("presplash_color");
+ if (backgroundColor != null) {
+ try {
+ mImageView.setBackgroundColor(Color.parseColor(backgroundColor));
+ } catch (IllegalArgumentException e) {}
+ }
+ mImageView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ mImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
+
+ }
+
+ if (mLayout == null) {
+ setContentView(mImageView);
+ } else if (PythonActivity.mImageView.getParent() == null){
+ mLayout.addView(mImageView);
+ }
+
+ }
+
+ @Override
+ protected void onPause() {
+ // fooabc
+ if ( this.mWakeLock != null && mWakeLock.isHeld()){
+ this.mWakeLock.release();
+ }
+
+ Log.v(TAG, "onPause()");
+ super.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ if ( this.mWakeLock != null){
+ this.mWakeLock.acquire();
+ }
+ Log.v(TAG, "onResume()");
+ super.onResume();
+ }
+
+
+
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonService.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonService.java
new file mode 100644
index 0000000..db4884c
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonService.java
@@ -0,0 +1,138 @@
+package org.kivy.android;
+
+import android.app.Service;
+import android.os.IBinder;
+import android.os.Build;
+import android.os.Bundle;
+import android.content.Intent;
+import android.content.Context;
+import android.util.Log;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.os.Process;
+import java.io.File;
+
+import org.kivy.android.PythonUtil;
+
+import org.renpy.android.Hardware;
+
+
+public class PythonService extends Service implements Runnable {
+
+ // Thread for Python code
+ private Thread pythonThread = null;
+
+ // Python environment variables
+ private String androidPrivate;
+ private String androidArgument;
+ private String pythonName;
+ private String pythonHome;
+ private String pythonPath;
+ private String serviceEntrypoint;
+ // Argument to pass to Python code,
+ private String pythonServiceArgument;
+ public static PythonService mService = null;
+ private Intent startIntent = null;
+
+ private boolean autoRestartService = false;
+
+ public void setAutoRestartService(boolean restart) {
+ autoRestartService = restart;
+ }
+
+ public boolean canDisplayNotification() {
+ return true;
+ }
+
+ public int startType() {
+ return START_NOT_STICKY;
+ }
+
+ @Override
+ public IBinder onBind(Intent arg0) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (pythonThread != null) {
+ Log.v("python service", "service exists, do not start again");
+ return START_NOT_STICKY;
+ }
+
+ startIntent = intent;
+ Bundle extras = intent.getExtras();
+ androidPrivate = extras.getString("androidPrivate");
+ androidArgument = extras.getString("androidArgument");
+ serviceEntrypoint = extras.getString("serviceEntrypoint");
+ pythonName = extras.getString("pythonName");
+ pythonHome = extras.getString("pythonHome");
+ pythonPath = extras.getString("pythonPath");
+ pythonServiceArgument = extras.getString("pythonServiceArgument");
+
+ pythonThread = new Thread(this);
+ pythonThread.start();
+
+ if (canDisplayNotification()) {
+ doStartForeground(extras);
+ }
+
+ return startType();
+ }
+
+ protected void doStartForeground(Bundle extras) {
+ String serviceTitle = extras.getString("serviceTitle");
+ String serviceDescription = extras.getString("serviceDescription");
+
+ Context context = getApplicationContext();
+ Intent contextIntent = new Intent(context, PythonActivity.class);
+ PendingIntent pIntent = PendingIntent.getActivity(context, 0, contextIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ Notification notification = new Notification.Builder(context)
+ .setContentTitle(serviceTitle)
+ .setContentText(serviceDescription)
+ .setContentIntent(pIntent)
+ .setWhen(System.currentTimeMillis())
+ .setSmallIcon(android.R.drawable.ic_dialog_info)
+ .setOngoing(true)
+ .build();
+ startForeground(1, notification);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ pythonThread = null;
+ if (autoRestartService && startIntent != null) {
+ Log.v("python service", "service restart requested");
+ startService(startIntent);
+ }
+ Process.killProcess(Process.myPid());
+ }
+
+ @Override
+ public void run(){
+ String app_root = getFilesDir().getAbsolutePath() + "/app";
+ File app_root_file = new File(app_root);
+ PythonUtil.loadLibraries(app_root_file, new File(getApplicationInfo().nativeLibraryDir));
+ this.mService = this;
+ nativeStart(
+ androidPrivate, androidArgument,
+ serviceEntrypoint, pythonName,
+ pythonHome, pythonPath,
+ pythonServiceArgument);
+ stopSelf();
+ }
+
+ // Native part
+ public static native void nativeStart(
+ String androidPrivate, String androidArgument,
+ String serviceEntrypoint, String pythonName,
+ String pythonHome, String pythonPath,
+ String pythonServiceArgument);
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonUtil.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonUtil.java
new file mode 100644
index 0000000..2dc888d
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/PythonUtil.java
@@ -0,0 +1,68 @@
+package org.kivy.android;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.regex.Pattern;
+
+import android.util.Log;
+
+public class PythonUtil {
+ private static final String TAG = "pythonutil";
+
+ protected static void addLibraryIfExists(ArrayList libsList, String pattern, File libsDir) {
+ // pattern should be the name of the lib file, without the
+ // preceding "lib" or suffix ".so", for instance "ssl.*" will
+ // match files of the form "libssl.*.so".
+ File [] files = libsDir.listFiles();
+
+ pattern = "lib" + pattern + "\\.so";
+ Pattern p = Pattern.compile(pattern);
+ for (int i = 0; i < files.length; ++i) {
+ File file = files[i];
+ String name = file.getName();
+ Log.v(TAG, "Checking pattern " + pattern + " against " + name);
+ if (p.matcher(name).matches()) {
+ Log.v(TAG, "Pattern " + pattern + " matched file " + name);
+ libsList.add(name.substring(3, name.length() - 3));
+ }
+ }
+ }
+
+ protected static ArrayList getLibraries(File libsDir) {
+ ArrayList libsList = new ArrayList();
+ libsList.add("python3.7m");
+ libsList.add("python3.8");
+ libsList.add("python3.9");
+ libsList.add("main");
+ return libsList;
+ }
+
+ public static void loadLibraries(File filesDir, File libsDir) {
+ boolean foundPython = false;
+
+ for (String lib : getLibraries(libsDir)) {
+ Log.v(TAG, "Loading library: " + lib);
+ try {
+ System.loadLibrary(lib);
+ if (lib.startsWith("python")) {
+ foundPython = true;
+ }
+ } catch(UnsatisfiedLinkError e) {
+ // If this is the last possible libpython
+ // load, and it has failed, give a more
+ // general error
+ Log.v(TAG, "Library loading error: " + e.getMessage());
+ if (lib.startsWith("python3.9") && !foundPython) {
+ throw new RuntimeException("Could not load any libpythonXXX.so");
+ } else if (lib.startsWith("python")) {
+ continue;
+ } else {
+ Log.v(TAG, "An UnsatisfiedLinkError occurred loading " + lib);
+ throw e;
+ }
+ }
+ }
+
+ Log.v(TAG, "Loaded everything!");
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/concurrency/PythonEvent.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/concurrency/PythonEvent.java
new file mode 100644
index 0000000..9911356
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/concurrency/PythonEvent.java
@@ -0,0 +1,45 @@
+package org.kivy.android.concurrency;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Created by ryan on 3/28/14.
+ */
+public class PythonEvent {
+ private final Lock lock = new ReentrantLock();
+ private final Condition cond = lock.newCondition();
+ private boolean flag = false;
+
+ public void set() {
+ lock.lock();
+ try {
+ flag = true;
+ cond.signalAll();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void wait_() throws InterruptedException {
+ lock.lock();
+ try {
+ while (!flag) {
+ cond.await();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public void clear() {
+ lock.lock();
+ try {
+ flag = false;
+ cond.signalAll();
+ } finally {
+ lock.unlock();
+ }
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/concurrency/PythonLock.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/concurrency/PythonLock.java
new file mode 100644
index 0000000..22f9d90
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/concurrency/PythonLock.java
@@ -0,0 +1,19 @@
+package org.kivy.android.concurrency;
+
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Created by ryan on 3/28/14.
+ */
+public class PythonLock {
+ private final Lock lock = new ReentrantLock();
+
+ public void acquire() {
+ lock.lock();
+ }
+
+ public void release() {
+ lock.unlock();
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/Project.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/Project.java
new file mode 100644
index 0000000..9177b43
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/Project.java
@@ -0,0 +1,99 @@
+package org.kivy.android.launcher;
+
+import java.io.UnsupportedEncodingException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Properties;
+
+import android.util.Log;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+
+/**
+ * This represents a project we've scanned for.
+ */
+public class Project {
+
+ public String dir = null;
+ String title = null;
+ String author = null;
+ Bitmap icon = null;
+ public boolean landscape = false;
+
+ static String decode(String s) {
+ try {
+ return new String(s.getBytes("ISO-8859-1"), "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ return s;
+ }
+ }
+
+ /**
+ * Scans directory for a android.txt file. If it finds one,
+ * and it looks valid enough, then it creates a new Project,
+ * and returns that. Otherwise, returns null.
+ */
+ public static Project scanDirectory(File dir) {
+
+ // We might have a link file.
+ if (dir.getAbsolutePath().endsWith(".link")) {
+ try {
+
+ // Scan the android.txt file.
+ File propfile = new File(dir, "android.txt");
+ FileInputStream in = new FileInputStream(propfile);
+ Properties p = new Properties();
+ p.load(in);
+ in.close();
+
+ String directory = p.getProperty("directory", null);
+
+ if (directory == null) {
+ return null;
+ }
+
+ dir = new File(directory);
+
+ } catch (Exception e) {
+ Log.i("Project", "Couldn't open link file " + dir, e);
+ }
+ }
+
+ // Make sure we're dealing with a directory.
+ if (! dir.isDirectory()) {
+ return null;
+ }
+
+ try {
+
+ // Scan the android.txt file.
+ File propfile = new File(dir, "android.txt");
+ FileInputStream in = new FileInputStream(propfile);
+ Properties p = new Properties();
+ p.load(in);
+ in.close();
+
+ // Get the various properties.
+ String title = decode(p.getProperty("title", "Untitled"));
+ String author = decode(p.getProperty("author", ""));
+ boolean landscape = p.getProperty("orientation", "portrait").equals("landscape");
+
+ // Create the project object.
+ Project rv = new Project();
+ rv.title = title;
+ rv.author = author;
+ rv.icon = BitmapFactory.decodeFile(new File(dir, "icon.png").getAbsolutePath());
+ rv.landscape = landscape;
+ rv.dir = dir.getAbsolutePath();
+
+ return rv;
+
+ } catch (Exception e) {
+ Log.i("Project", "Couldn't open android.txt", e);
+ }
+
+ return null;
+
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/ProjectAdapter.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/ProjectAdapter.java
new file mode 100644
index 0000000..f66debf
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/ProjectAdapter.java
@@ -0,0 +1,44 @@
+package org.kivy.android.launcher;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Gravity;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+import android.widget.LinearLayout;
+import android.widget.ImageView;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.util.Log;
+
+import org.renpy.android.ResourceManager;
+
+public class ProjectAdapter extends ArrayAdapter {
+
+ private Activity mContext;
+ private ResourceManager resourceManager;
+
+ public ProjectAdapter(Activity context) {
+ super(context, 0);
+
+ mContext = context;
+ resourceManager = new ResourceManager(context);
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ Project p = getItem(position);
+
+ View v = resourceManager.inflateView("chooser_item");
+ TextView title = (TextView) resourceManager.getViewById(v, "title");
+ TextView author = (TextView) resourceManager.getViewById(v, "author");
+ ImageView icon = (ImageView) resourceManager.getViewById(v, "icon");
+
+ title.setText(p.title);
+ author.setText(p.author);
+ icon.setImageBitmap(p.icon);
+
+ return v;
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/ProjectChooser.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/ProjectChooser.java
new file mode 100644
index 0000000..17eec32
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/kivy/android/launcher/ProjectChooser.java
@@ -0,0 +1,94 @@
+package org.kivy.android.launcher;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import android.content.Intent;
+import android.content.res.Resources;
+import android.util.Log;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.AdapterView;
+import android.os.Environment;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import android.net.Uri;
+
+import org.renpy.android.ResourceManager;
+
+public class ProjectChooser extends Activity implements AdapterView.OnItemClickListener {
+
+ ResourceManager resourceManager;
+
+ String urlScheme;
+
+ @Override
+ public void onStart()
+ {
+ super.onStart();
+
+ resourceManager = new ResourceManager(this);
+
+ urlScheme = resourceManager.getString("urlScheme");
+
+ // Set the window title.
+ setTitle(resourceManager.getString("appName"));
+
+ // Scan the sdcard for files, and sort them.
+ File dir = new File(Environment.getExternalStorageDirectory(), urlScheme);
+
+ File entries[] = dir.listFiles();
+
+ if (entries == null) {
+ entries = new File[0];
+ }
+
+ Arrays.sort(entries);
+
+ // Create a ProjectAdapter and fill it with projects.
+ ProjectAdapter projectAdapter = new ProjectAdapter(this);
+
+ // Populate it with the properties files.
+ for (File d : entries) {
+ Project p = Project.scanDirectory(d);
+ if (p != null) {
+ projectAdapter.add(p);
+ }
+ }
+
+ if (projectAdapter.getCount() != 0) {
+
+ View v = resourceManager.inflateView("project_chooser");
+ ListView l = (ListView) resourceManager.getViewById(v, "projectList");
+
+ l.setAdapter(projectAdapter);
+ l.setOnItemClickListener(this);
+
+ setContentView(v);
+
+ } else {
+
+ View v = resourceManager.inflateView("project_empty");
+ TextView emptyText = (TextView) resourceManager.getViewById(v, "emptyText");
+
+ emptyText.setText("No projects are available to launch. Please place a project into " + dir + " and restart this application. Press the back button to exit.");
+
+ setContentView(v);
+ }
+ }
+
+ public void onItemClick(AdapterView parent, View view, int position, long id) {
+ Project p = (Project) parent.getItemAtPosition(position);
+
+ Intent intent = new Intent(
+ "org.kivy.LAUNCH",
+ Uri.fromParts(urlScheme, p.dir, ""));
+
+ intent.setClassName(getPackageName(), "org.kivy.android.PythonActivity");
+ this.startActivity(intent);
+ this.finish();
+ }
+}
diff --git a/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/libsdl/app/SDLActivity.java b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/libsdl/app/SDLActivity.java
new file mode 100644
index 0000000..e1dc084
--- /dev/null
+++ b/p4a/pythonforandroid/bootstraps/lbry/build/src/main/java/org/libsdl/app/SDLActivity.java
@@ -0,0 +1,1579 @@
+package org.libsdl.app;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.lang.reflect.Method;
+
+import android.app.*;
+import android.content.*;
+import android.view.*;
+import android.view.inputmethod.BaseInputConnection;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AbsoluteLayout;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.os.*;
+import android.util.Log;
+import android.util.SparseArray;
+import android.graphics.*;
+import android.graphics.drawable.Drawable;
+import android.media.*;
+import android.hardware.*;
+
+/**
+ SDL Activity
+*/
+public class SDLActivity extends Activity {
+ private static final String TAG = "SDL";
+
+ // Keep track of the paused state
+ public static boolean mIsPaused, mIsSurfaceReady, mHasFocus;
+ public static boolean mExitCalledFromJava;
+
+ /** If shared libraries (e.g. SDL or the native application) could not be loaded. */
+ public static boolean mBrokenLibraries;
+
+ // If we want to separate mouse and touch events.
+ // This is only toggled in native code when a hint is set!
+ public static boolean mSeparateMouseAndTouch;
+
+ // Main components
+ protected static SDLActivity mSingleton;
+ protected static SDLSurface mSurface;
+ protected static View mTextEdit;
+ protected static ViewGroup mLayout;
+ protected static SDLJoystickHandler mJoystickHandler;
+
+ // This is what SDL runs in. It invokes SDL_main(), eventually
+ protected static Thread mSDLThread;
+
+ // Audio
+ protected static AudioTrack mAudioTrack;
+
+ /**
+ * This method is called by SDL before loading the native shared libraries.
+ * It can be overridden to provide names of shared libraries to be loaded.
+ * The default implementation returns the defaults. It never returns null.
+ * An array returned by a new implementation must at least contain "SDL2".
+ * Also keep in mind that the order the libraries are loaded may matter.
+ * @return names of shared libraries to be loaded (e.g. "SDL2", "main").
+ */
+ protected String[] getLibraries() {
+ return new String[] {
+ "SDL2",
+ // "SDL2_image",
+ // "SDL2_mixer",
+ // "SDL2_net",
+ // "SDL2_ttf",
+ "main"
+ };
+ }
+
+ // Load the .so
+ public void loadLibraries() {
+ for (String lib : getLibraries()) {
+ System.loadLibrary(lib);
+ }
+ }
+
+ /**
+ * This method is called by SDL before starting the native application thread.
+ * It can be overridden to provide the arguments after the application name.
+ * The default implementation returns an empty array. It never returns null.
+ * @return arguments for the native application.
+ */
+ protected String[] getArguments() {
+ return new String[0];
+ }
+
+ public static void initialize() {
+ // The static nature of the singleton and Android quirkyness force us to initialize everything here
+ // Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values
+ mSingleton = null;
+ mSurface = null;
+ mTextEdit = null;
+ mLayout = null;
+ mJoystickHandler = null;
+ mSDLThread = null;
+ mAudioTrack = null;
+ mExitCalledFromJava = false;
+ mBrokenLibraries = false;
+ mIsPaused = false;
+ mIsSurfaceReady = false;
+ mHasFocus = true;
+ }
+
+ // Setup
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ Log.v("SDL", "Device: " + android.os.Build.DEVICE);
+ Log.v("SDL", "Model: " + android.os.Build.MODEL);
+ Log.v("SDL", "onCreate():" + mSingleton);
+ super.onCreate(savedInstanceState);
+
+ SDLActivity.initialize();
+ // So we can call stuff from static callbacks
+ mSingleton = this;
+ }
+
+ // We don't do this in onCreate because we unpack and load the app data on a thread
+ // and we can't run setup tasks until that thread completes.
+ protected void finishLoad() {
+ // Load shared libraries
+ String errorMsgBrokenLib = "";
+ try {
+ loadLibraries();
+ } catch(UnsatisfiedLinkError e) {
+ System.err.println(e.getMessage());
+ mBrokenLibraries = true;
+ errorMsgBrokenLib = e.getMessage();
+ } catch(Exception e) {
+ System.err.println(e.getMessage());
+ mBrokenLibraries = true;
+ errorMsgBrokenLib = e.getMessage();
+ }
+
+ if (mBrokenLibraries)
+ {
+ AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
+ dlgAlert.setMessage("An error occurred while trying to start the application. Please try again and/or reinstall."
+ + System.getProperty("line.separator")
+ + System.getProperty("line.separator")
+ + "Error: " + errorMsgBrokenLib);
+ dlgAlert.setTitle("SDL Error");
+ dlgAlert.setPositiveButton("Exit",
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog,int id) {
+ // if this button is clicked, close current activity
+ SDLActivity.mSingleton.finish();
+ }
+ });
+ dlgAlert.setCancelable(false);
+ dlgAlert.create().show();
+
+ return;
+ }
+
+ // Set up the surface
+ mSurface = new SDLSurface(getApplication());
+
+ if(Build.VERSION.SDK_INT >= 12) {
+ mJoystickHandler = new SDLJoystickHandler_API12();
+ }
+ else {
+ mJoystickHandler = new SDLJoystickHandler();
+ }
+
+ mLayout = new AbsoluteLayout(this);
+ mLayout.addView(mSurface);
+
+ setContentView(mLayout);
+ }
+
+ // Events
+ @Override
+ protected void onPause() {
+ Log.v("SDL", "onPause()");
+ super.onPause();
+
+ if (SDLActivity.mBrokenLibraries) {
+ return;
+ }
+
+ SDLActivity.handlePause();
+ }
+
+ @Override
+ protected void onResume() {
+ Log.v("SDL", "onResume()");
+ super.onResume();
+
+ if (SDLActivity.mBrokenLibraries) {
+ return;
+ }
+
+ SDLActivity.handleResume();
+ }
+
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ Log.v("SDL", "onWindowFocusChanged(): " + hasFocus);
+
+ if (SDLActivity.mBrokenLibraries) {
+ return;
+ }
+
+ SDLActivity.mHasFocus = hasFocus;
+ if (hasFocus) {
+ SDLActivity.handleResume();
+ }
+ }
+
+ @Override
+ public void onLowMemory() {
+ Log.v("SDL", "onLowMemory()");
+ super.onLowMemory();
+
+ if (SDLActivity.mBrokenLibraries) {
+ return;
+ }
+
+ SDLActivity.nativeLowMemory();
+ }
+
+ @Override
+ protected void onDestroy() {
+ Log.v("SDL", "onDestroy()");
+
+ if (SDLActivity.mBrokenLibraries) {
+ super.onDestroy();
+ // Reset everything in case the user re opens the app
+ SDLActivity.initialize();
+ return;
+ }
+
+ // Send a quit message to the application
+ SDLActivity.mExitCalledFromJava = true;
+ SDLActivity.nativeQuit();
+
+ // Now wait for the SDL thread to quit
+ if (SDLActivity.mSDLThread != null) {
+ try {
+ SDLActivity.mSDLThread.join();
+ } catch(Exception e) {
+ Log.v("SDL", "Problem stopping thread: " + e);
+ }
+ SDLActivity.mSDLThread = null;
+
+ //Log.v("SDL", "Finished waiting for SDL thread");
+ }
+
+ super.onDestroy();
+ // Reset everything in case the user re opens the app
+ SDLActivity.initialize();
+
+ // Completely closes application.
+ System.exit(0);
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+
+ if (SDLActivity.mBrokenLibraries) {
+ return false;
+ }
+
+ int keyCode = event.getKeyCode();
+ // Ignore certain special keys so they're handled by Android
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
+ keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+ keyCode == KeyEvent.KEYCODE_CAMERA ||
+ keyCode == 168 || /* API 11: KeyEvent.KEYCODE_ZOOM_IN */
+ keyCode == 169 /* API 11: KeyEvent.KEYCODE_ZOOM_OUT */
+ ) {
+ return false;
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ /** Called by onPause or surfaceDestroyed. Even if surfaceDestroyed
+ * is the first to be called, mIsSurfaceReady should still be set
+ * to 'true' during the call to onPause (in a usual scenario).
+ */
+ public static void handlePause() {
+ if (!SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady) {
+ SDLActivity.mIsPaused = true;
+ SDLActivity.nativePause();
+ mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false);
+ }
+ }
+
+ /** Called by onResume or surfaceCreated. An actual resume should be done only when the surface is ready.
+ * Note: Some Android variants may send multiple surfaceChanged events, so we don't need to resume
+ * every time we get one of those events, only if it comes after surfaceDestroyed
+ */
+ public static void handleResume() {
+ if (SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady && SDLActivity.mHasFocus) {
+ SDLActivity.mIsPaused = false;
+ SDLActivity.nativeResume();
+ mSurface.handleResume();
+ }
+ }
+
+ /* The native thread has finished */
+ public static void handleNativeExit() {
+ SDLActivity.mSDLThread = null;
+ mSingleton.finish();
+ }
+
+
+ // Messages from the SDLMain thread
+ static final int COMMAND_CHANGE_TITLE = 1;
+ static final int COMMAND_UNUSED = 2;
+ static final int COMMAND_TEXTEDIT_HIDE = 3;
+ static final int COMMAND_SET_KEEP_SCREEN_ON = 5;
+
+ protected static final int COMMAND_USER = 0x8000;
+
+ /**
+ * This method is called by SDL if SDL did not handle a message itself.
+ * This happens if a received message contains an unsupported command.
+ * Method can be overwritten to handle Messages in a different class.
+ * @param command the command of the message.
+ * @param param the parameter of the message. May be null.
+ * @return if the message was handled in overridden method.
+ */
+ protected boolean onUnhandledMessage(int command, Object param) {
+ return false;
+ }
+
+ /**
+ * A Handler class for Messages from native SDL applications.
+ * It uses current Activities as target (e.g. for the title).
+ * static to prevent implicit references to enclosing object.
+ */
+ protected static class SDLCommandHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+ Context context = getContext();
+ if (context == null) {
+ Log.e(TAG, "error handling message, getContext() returned null");
+ return;
+ }
+ switch (msg.arg1) {
+ case COMMAND_CHANGE_TITLE:
+ if (context instanceof Activity) {
+ ((Activity) context).setTitle((String)msg.obj);
+ } else {
+ Log.e(TAG, "error handling message, getContext() returned no Activity");
+ }
+ break;
+ case COMMAND_TEXTEDIT_HIDE:
+ if (mTextEdit != null) {
+ mTextEdit.setVisibility(View.GONE);
+
+ InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
+ }
+ break;
+ case COMMAND_SET_KEEP_SCREEN_ON:
+ {
+ Window window = ((Activity) context).getWindow();
+ if (window != null) {
+ if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) {
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ } else {
+ window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+ }
+ }
+ break;
+ }
+ default:
+ if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
+ Log.e(TAG, "error handling message, command is " + msg.arg1);
+ }
+ }
+ }
+ }
+
+ // Handler for the messages
+ Handler commandHandler = new SDLCommandHandler();
+
+ // Send a message from the SDLMain thread
+ boolean sendCommand(int command, Object data) {
+ Message msg = commandHandler.obtainMessage();
+ msg.arg1 = command;
+ msg.obj = data;
+ return commandHandler.sendMessage(msg);
+ }
+
+ // C functions we call
+ public static native int nativeInit(Object arguments);
+ public static native void nativeLowMemory();
+ public static native void nativeQuit();
+ public static native void nativePause();
+ public static native void nativeResume();
+ public static native void onNativeResize(int x, int y, int format, float rate);
+ public static native int onNativePadDown(int device_id, int keycode);
+ public static native int onNativePadUp(int device_id, int keycode);
+ public static native void onNativeJoy(int device_id, int axis,
+ float value);
+ public static native void onNativeHat(int device_id, int hat_id,
+ int x, int y);
+ public static native void nativeSetEnv(String j_name, String j_value);
+ public static native void onNativeKeyDown(int keycode);
+ public static native void onNativeKeyUp(int keycode);
+ public static native void onNativeKeyboardFocusLost();
+ public static native void onNativeMouse(int button, int action, float x, float y);
+ public static native void onNativeTouch(int touchDevId, int pointerFingerId,
+ int action, float x,
+ float y, float p);
+ public static native void onNativeAccel(float x, float y, float z);
+ public static native void onNativeSurfaceChanged();
+ public static native void onNativeSurfaceDestroyed();
+ public static native void nativeFlipBuffers();
+ public static native int nativeAddJoystick(int device_id, String name,
+ int is_accelerometer, int nbuttons,
+ int naxes, int nhats, int nballs);
+ public static native int nativeRemoveJoystick(int device_id);
+ public static native String nativeGetHint(String name);
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static void flipBuffers() {
+ SDLActivity.nativeFlipBuffers();
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static boolean setActivityTitle(String title) {
+ // Called from SDLMain() thread and can't directly affect the view
+ return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static boolean sendMessage(int command, int param) {
+ return mSingleton.sendCommand(command, Integer.valueOf(param));
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static Context getContext() {
+ return mSingleton;
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ * @return result of getSystemService(name) but executed on UI thread.
+ */
+ public Object getSystemServiceFromUiThread(final String name) {
+ final Object lock = new Object();
+ final Object[] results = new Object[2]; // array for writable variables
+ synchronized (lock) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ synchronized (lock) {
+ results[0] = getSystemService(name);
+ results[1] = Boolean.TRUE;
+ lock.notify();
+ }
+ }
+ });
+ if (results[1] == null) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ return results[0];
+ }
+
+ static class ShowTextInputTask implements Runnable {
+ /*
+ * This is used to regulate the pan&scan method to have some offset from
+ * the bottom edge of the input region and the top edge of an input
+ * method (soft keyboard)
+ */
+ static final int HEIGHT_PADDING = 15;
+
+ public int x, y, w, h;
+
+ public ShowTextInputTask(int x, int y, int w, int h) {
+ this.x = x;
+ this.y = y;
+ this.w = w;
+ this.h = h;
+ }
+
+ @Override
+ public void run() {
+ AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
+ w, h + HEIGHT_PADDING, x, y);
+
+ if (mTextEdit == null) {
+ mTextEdit = new DummyEdit(getContext());
+
+ mLayout.addView(mTextEdit, params);
+ } else {
+ mTextEdit.setLayoutParams(params);
+ }
+
+ mTextEdit.setVisibility(View.VISIBLE);
+ mTextEdit.requestFocus();
+
+ InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.showSoftInput(mTextEdit, 0);
+ }
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static boolean showTextInput(int x, int y, int w, int h) {
+ // Transfer the task to the main thread as a Runnable
+ return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h));
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static Surface getNativeSurface() {
+ return SDLActivity.mSurface.getNativeSurface();
+ }
+
+ // Audio
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
+ int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
+ int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
+ int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
+
+ Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
+
+ // Let the user pick a larger buffer if they really want -- but ye
+ // gods they probably shouldn't, the minimums are horrifyingly high
+ // latency already
+ desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
+
+ if (mAudioTrack == null) {
+ mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
+ channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
+
+ // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
+ // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
+ // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
+
+ if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
+ Log.e("SDL", "Failed during initialization of Audio Track");
+ mAudioTrack = null;
+ return -1;
+ }
+
+ mAudioTrack.play();
+ }
+
+ Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
+
+ return 0;
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static void audioWriteShortBuffer(short[] buffer) {
+ for (int i = 0; i < buffer.length; ) {
+ int result = mAudioTrack.write(buffer, i, buffer.length - i);
+ if (result > 0) {
+ i += result;
+ } else if (result == 0) {
+ try {
+ Thread.sleep(1);
+ } catch(InterruptedException e) {
+ // Nom nom
+ }
+ } else {
+ Log.w("SDL", "SDL audio: error return from write(short)");
+ return;
+ }
+ }
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static void audioWriteByteBuffer(byte[] buffer) {
+ for (int i = 0; i < buffer.length; ) {
+ int result = mAudioTrack.write(buffer, i, buffer.length - i);
+ if (result > 0) {
+ i += result;
+ } else if (result == 0) {
+ try {
+ Thread.sleep(1);
+ } catch(InterruptedException e) {
+ // Nom nom
+ }
+ } else {
+ Log.w("SDL", "SDL audio: error return from write(byte)");
+ return;
+ }
+ }
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static void audioQuit() {
+ if (mAudioTrack != null) {
+ mAudioTrack.stop();
+ mAudioTrack = null;
+ }
+ }
+
+ // Input
+
+ /**
+ * This method is called by SDL using JNI.
+ * @return an array which may be empty but is never null.
+ */
+ public static int[] inputGetInputDeviceIds(int sources) {
+ int[] ids = InputDevice.getDeviceIds();
+ int[] filtered = new int[ids.length];
+ int used = 0;
+ for (int i = 0; i < ids.length; ++i) {
+ InputDevice device = InputDevice.getDevice(ids[i]);
+ if ((device != null) && ((device.getSources() & sources) != 0)) {
+ filtered[used++] = device.getId();
+ }
+ }
+ return Arrays.copyOf(filtered, used);
+ }
+
+ // Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance
+ public static boolean handleJoystickMotionEvent(MotionEvent event) {
+ return mJoystickHandler.handleMotionEvent(event);
+ }
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static void pollInputDevices() {
+ if (SDLActivity.mSDLThread != null) {
+ mJoystickHandler.pollInputDevices();
+ SDLActivity.mSingleton.keepActive();
+ }
+ }
+
+ /**
+ * Trick needed for loading screen
+ */
+ public void keepActive() {
+ }
+
+ // APK extension files support
+
+ /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */
+ private Object expansionFile;
+
+ /** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */
+ private Method expansionFileMethod;
+
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public InputStream openAPKExtensionInputStream(String fileName) throws IOException {
+ // Get a ZipResourceFile representing a merger of both the main and patch files
+ if (expansionFile == null) {
+ Integer mainVersion = Integer.valueOf(nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"));
+ Integer patchVersion = Integer.valueOf(nativeGetHint("SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION"));
+
+ try {
+ // To avoid direct dependency on Google APK extension library that is
+ // not a part of Android SDK we access it using reflection
+ expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport")
+ .getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class)
+ .invoke(null, this, mainVersion, patchVersion);
+
+ expansionFileMethod = expansionFile.getClass()
+ .getMethod("getInputStream", String.class);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ expansionFile = null;
+ expansionFileMethod = null;
+ }
+ }
+
+ // Get an input stream for a known file inside the expansion file ZIPs
+ InputStream fileStream;
+ try {
+ fileStream = (InputStream)expansionFileMethod.invoke(expansionFile, fileName);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ fileStream = null;
+ }
+
+ if (fileStream == null) {
+ throw new IOException();
+ }
+
+ return fileStream;
+ }
+
+ // Messagebox
+
+ /** Result of current messagebox. Also used for blocking the calling thread. */
+ protected final int[] messageboxSelection = new int[1];
+
+ /** Id of current dialog. */
+ protected int dialogs = 0;
+
+ /**
+ * This method is called by SDL using JNI.
+ * Shows the messagebox from UI thread and block calling thread.
+ * buttonFlags, buttonIds and buttonTexts must have same length.
+ * @param buttonFlags array containing flags for every button.
+ * @param buttonIds array containing id for every button.
+ * @param buttonTexts array containing text for every button.
+ * @param colors null for default or array of length 5 containing colors.
+ * @return button id or -1.
+ */
+ public int messageboxShowMessageBox(
+ final int flags,
+ final String title,
+ final String message,
+ final int[] buttonFlags,
+ final int[] buttonIds,
+ final String[] buttonTexts,
+ final int[] colors) {
+
+ messageboxSelection[0] = -1;
+
+ // sanity checks
+
+ if ((buttonFlags.length != buttonIds.length) && (buttonIds.length != buttonTexts.length)) {
+ return -1; // implementation broken
+ }
+
+ // collect arguments for Dialog
+
+ final Bundle args = new Bundle();
+ args.putInt("flags", flags);
+ args.putString("title", title);
+ args.putString("message", message);
+ args.putIntArray("buttonFlags", buttonFlags);
+ args.putIntArray("buttonIds", buttonIds);
+ args.putStringArray("buttonTexts", buttonTexts);
+ args.putIntArray("colors", colors);
+
+ // trigger Dialog creation on UI thread
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ showDialog(dialogs++, args);
+ }
+ });
+
+ // block the calling thread
+
+ synchronized (messageboxSelection) {
+ try {
+ messageboxSelection.wait();
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ return -1;
+ }
+ }
+
+ // return selected value
+
+ return messageboxSelection[0];
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int ignore, Bundle args) {
+
+ // TODO set values from "flags" to messagebox dialog
+
+ // get colors
+
+ int[] colors = args.getIntArray("colors");
+ int backgroundColor;
+ int textColor;
+ int buttonBorderColor;
+ int buttonBackgroundColor;
+ int buttonSelectedColor;
+ if (colors != null) {
+ int i = -1;
+ backgroundColor = colors[++i];
+ textColor = colors[++i];
+ buttonBorderColor = colors[++i];
+ buttonBackgroundColor = colors[++i];
+ buttonSelectedColor = colors[++i];
+ } else {
+ backgroundColor = Color.TRANSPARENT;
+ textColor = Color.TRANSPARENT;
+ buttonBorderColor = Color.TRANSPARENT;
+ buttonBackgroundColor = Color.TRANSPARENT;
+ buttonSelectedColor = Color.TRANSPARENT;
+ }
+
+ // create dialog with title and a listener to wake up calling thread
+
+ final Dialog dialog = new Dialog(this);
+ dialog.setTitle(args.getString("title"));
+ dialog.setCancelable(false);
+ dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface unused) {
+ synchronized (messageboxSelection) {
+ messageboxSelection.notify();
+ }
+ }
+ });
+
+ // create text
+
+ TextView message = new TextView(this);
+ message.setGravity(Gravity.CENTER);
+ message.setText(args.getString("message"));
+ if (textColor != Color.TRANSPARENT) {
+ message.setTextColor(textColor);
+ }
+
+ // create buttons
+
+ int[] buttonFlags = args.getIntArray("buttonFlags");
+ int[] buttonIds = args.getIntArray("buttonIds");
+ String[] buttonTexts = args.getStringArray("buttonTexts");
+
+ final SparseArray