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