Compare commits

..

39 commits
master ... v3.8

Author SHA1 Message Date
Andree Buschmann
6ccd99a86a Port r29764 to v3.8 branch. Fixes iPod nano 2G LCD issues.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29765 a1c6a512-1295-4272-9138-f99709370657
2011-04-22 19:17:25 +00:00
Andree Buschmann
c351e62620 Merge r29708 to v3.8 branch. Fixes gapless playback (FS#12062).
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29709 a1c6a512-1295-4272-9138-f99709370657
2011-04-13 05:54:52 +00:00
Alex Parker
23ec0a537f Bump version numbers in scripts in preparation for 3.8.1.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29680 a1c6a512-1295-4272-9138-f99709370657
2011-04-04 18:08:48 +00:00
Michael Chicoine
95475eca87 Manual correction for entering quick screen from file browser
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29678 a1c6a512-1295-4272-9138-f99709370657
2011-04-04 01:59:57 +00:00
Bertrik Sikken
d1fdb485b1 Backport several AMSv2 sd fixes/cleanups for the 3.8.1 branch:
r29624,r29628,r29629,r29630,r29647,r29648,r29651,r29652,r29656,r29657,r29660,r29667


git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29676 a1c6a512-1295-4272-9138-f99709370657
2011-04-03 22:33:10 +00:00
Alex Parker
fde22376d4 Backport r29644 to the 3.8 branch - Fix error in Ohm's law formula as provided in FS#12023. Thanks to Leif Andersen.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29650 a1c6a512-1295-4272-9138-f99709370657
2011-03-26 21:14:12 +00:00
Alex Parker
017f61388b Backport r29577 to the 3.8 branch - Fix FS#11894 - Sansa Clip+ Volume Buttons don't switch when Upside Down is activated
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29649 a1c6a512-1295-4272-9138-f99709370657
2011-03-26 21:14:07 +00:00
Andree Buschmann
368e872c52 Backport r29642 to v3.8 branch. Fixes FS#12024.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29643 a1c6a512-1295-4272-9138-f99709370657
2011-03-24 19:02:56 +00:00
Michael Hohmuth
0b2894e2ec SD AMSv2: Restore access to the last 0xF000 sectors of internal drive
Fixes FS#11965 and FS#12001.  Backports r29625, r29637, r29638.
Repairs r29169.  Thanks to saratoga and funman!

git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29641 a1c6a512-1295-4272-9138-f99709370657
2011-03-24 16:59:18 +00:00
Andree Buschmann
90df1b4a76 Backport r29622 to v3.8 branch. Fixes FS#12019, a bug in the AAC SBR decoding.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29623 a1c6a512-1295-4272-9138-f99709370657
2011-03-20 16:02:34 +00:00
Thomas Martitz
eabebcbc90 Fix FS#12012 - Radio Art broken since r29259 - Embedded album art support
Forgot to adapt radio art to the new bufopen user_data argument.

git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29599 a1c6a512-1295-4272-9138-f99709370657
2011-03-16 10:25:20 +00:00
Michael Hohmuth
38bd69905a Backport r29548: autoresume: Manual: Clarify precedence rules for resume positions
Resume positions stored in bookmarks take precedence over autoresume.

Technically, the resume position for the "Resume Playback" function
(which is also saved across power-off/power-on) also takes precedence
over autoresume.  However, there is no way for a user to tell as it is
identical to the autoresume position for the last-played track, so
don't highlight it in the manual.

git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29549 a1c6a512-1295-4272-9138-f99709370657
2011-03-08 23:07:43 +00:00
Andree Buschmann
57e272cf5d Integrate r29513 to v3.8 branch. Fixes FS#11973.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29514 a1c6a512-1295-4272-9138-f99709370657
2011-03-03 20:58:50 +00:00
Andree Buschmann
488df30245 Backport r29476 to v3.8 branch. Disabled ATA_DMA for PP targets.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29503 a1c6a512-1295-4272-9138-f99709370657
2011-03-02 20:13:20 +00:00
Thomas Martitz
bd4f3c9c60 Backport r29463: Fix returning to wps from a plugin.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29464 a1c6a512-1295-4272-9138-f99709370657
2011-02-28 14:41:30 +00:00
Alex Parker
a1d157ba1e Backport r29435 to 3.8 branch.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29439 a1c6a512-1295-4272-9138-f99709370657
2011-02-27 21:01:31 +00:00
Alex Parker
2076ed09eb Fix corrupted metadata on manual track change on hwcodec. Thanks to kugel for the patch.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29431 a1c6a512-1295-4272-9138-f99709370657
2011-02-27 19:12:09 +00:00
Dominik Riebeling
01db859191 Manual: switch to inputenx and load additional characters.
Since we're now loading a file from inputenx directly change to inputenx in
general to avoid issues between those two packages. Fixes manual builds that
broke because of U+0101 and U+0146 glyphs which aren't defined in the utf8
inputenc package.


git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29429 a1c6a512-1295-4272-9138-f99709370657
2011-02-27 16:48:02 +00:00
Frank Gevaerts
de4696ff21 Simplified Chinese update by Li Jie
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29424 a1c6a512-1295-4272-9138-f99709370657
2011-02-27 14:17:00 +00:00
Alex Parker
f57a698eff Tweak dansk.lang, from rasher
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29423 a1c6a512-1295-4272-9138-f99709370657
2011-02-27 12:54:07 +00:00
Alex Parker
a9357262e2 FS#11970 by Mārtiņš Šimis - update Latvian
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29419 a1c6a512-1295-4272-9138-f99709370657
2011-02-27 12:08:40 +00:00
Alex Parker
5c8f69d8a0 FS#11969 by Lev Panov - Russian translation
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29416 a1c6a512-1295-4272-9138-f99709370657
2011-02-26 23:16:21 +00:00
Alex Parker
604ea9fc9a FS#11968 by Peter Lecky - Slovak language update
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29413 a1c6a512-1295-4272-9138-f99709370657
2011-02-26 22:14:48 +00:00
Alex Parker
4e3d8c5f59 Forgot to add the help text for make elfzip.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29407 a1c6a512-1295-4272-9138-f99709370657
2011-02-26 20:50:30 +00:00
Alex Parker
620c8434db Bump versions to 3.8
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29403 a1c6a512-1295-4272-9138-f99709370657
2011-02-26 18:27:59 +00:00
Bertrik Sikken
d5d331b24d Latvian language translation - FS#11967 by Mārtiņš Šimis
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29400 a1c6a512-1295-4272-9138-f99709370657
2011-02-25 20:32:20 +00:00
Michael Chicoine
e9b8b5ba17 Return valid tuner ID even when tuner is not detected properly. Fixes FS#11791
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29379 a1c6a512-1295-4272-9138-f99709370657
2011-02-22 14:03:04 +00:00
Mustapha Senhaji
2122eb8fb3 Add Ismael Castiñeira Álvarez to the credits and on the galego translation files
for his patch FS#11938 committed as r28823


git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29374 a1c6a512-1295-4272-9138-f99709370657
2011-02-22 01:46:54 +00:00
Alex Parker
a4960ea764 Fix yellow
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29370 a1c6a512-1295-4272-9138-f99709370657
2011-02-21 18:48:57 +00:00
Alex Parker
86878f0c2b FS#11938 by Ismael Castiñeira Álvarez - update for Galician language.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29369 a1c6a512-1295-4272-9138-f99709370657
2011-02-21 18:35:40 +00:00
Alex Parker
2f99e609f9 Revert r29327 - "Implement cooperative threads on hosted platforms using C code" on the release branch. Thanks to kugel for the patch.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29364 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 20:26:42 +00:00
Alex Parker
cad99bae1d Also build and keep elfs zip file for the release.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29363 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 20:07:51 +00:00
Alex Parker
4952e59f38 Add "elfzip" target to make which creates a zip of all elf files, as mapzip does for map files.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29361 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 19:57:04 +00:00
Alex Parker
2f857c6b6c * Keep the map files instead of building then throwing them away in the release script.
* Pass the release version to make in the release script instead of having to remember to hack up version.sh in the release branch.

git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29359 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 19:27:26 +00:00
Jonas Häggqvist
43d4dc1aca Add 2 deprecated strings to appease genlang and correct stats
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29356 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 18:16:15 +00:00
Jonas Häggqvist
f9fa70fdaf Update Danish translation.
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29354 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 17:59:37 +00:00
Bertrik Sikken
c358711cd6 FS#11953 - Dutch (nederlands) translation update
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29351 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 16:35:42 +00:00
Alex Parker
24419baf1f Bump scripts to 3.8RC
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29346 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 14:48:15 +00:00
Alex Parker
ef3ec72bfb Branch for 3.8
git-svn-id: svn://svn.rockbox.org/rockbox/branches/v3_8@29345 a1c6a512-1295-4272-9138-f99709370657
2011-02-20 14:14:27 +00:00
8159 changed files with 389097 additions and 1718542 deletions

16
.gitattributes vendored
View file

@ -1,16 +0,0 @@
* text=auto
*.bmp binary
*.cat -text
*.dll binary
*.fnt binary
*.icns binary
*.ico binary
*.inf -text
*.jpg binary
*.pdf binary
*.png binary
*.svg binary
*.sys binary
*.vcproj -text
*.wav binary
*.xcf binary

303
.gitignore vendored
View file

@ -1,303 +0,0 @@
# /
/build*
/sim*
/output
*.elf
*.exe
*.so
*.o
*.a
*~
__pycache__
# Intermediate language files
/apps/lang/*.update
/apps/lang/*.new
# checkwps
/tools/checkwps/output
/tools/checkwps/Makefile
/tools/checkwps/autoconf.h
/tools/checkwps/make.dep
/tools/checkwps/rockbox-info.txt
/tools/checkwps/checkwps.failures
# android: java build system
/android/bin
/android/data
/android/gen
/android/libs
/android/local.properties
# android: our build system
/android/autoconf.h
/android/Makefile
/android/make.dep
/android/apps
/android/bitmaps
/android/pluginbitmaps
/android/firmware
/android/lang
/android/lib
/android/rockbox.*
/android/rockbox-info.txt
/android/sysfont.c
/android/sysfont.h
/android/version.h
/android/credits.raw
# android: eclipse stuff
/android/.settings
# buflib test code
/firmware/test/buflib/test_main
/firmware/test/buflib/test_main2
/firmware/test/buflib/test_max
/firmware/test/buflib/test_move
/firmware/test/buflib/test_move2
/firmware/test/buflib/test_shrink
/firmware/test/buflib/test_shrink_cb
/firmware/test/buflib/test_shrink_startchanged
/firmware/test/buflib/test_shrink_unaligned
# /utils/
/utils/Makefile
/utils/rbutil
# /utils/ipodpatcher/
/utils/ipodpatcher/ipodpatcher
# /utils/chinachippatcher/
/utils/chinachippatcher/chinachip
# /utils/bspatch/
/utils/bspatch/bspatch
# /utils/rbutilqt/
/utils/rbutilqt/build
/utils/rbutilqt/RockboxUtility
/utils/rbutilqt/RockboxUtility.*
/utils/rbutilqt/Makefile
/utils/rbutilqt/*.qm
/utils/rbutilqt/release
/utils/rbutilqt/debug
/utils/rbutilqt/*.Debug
/utils/rbutilqt/*.Release
/utils/rbutilqt/tags
/utils/rbutilqt/.qmake.stash
# /utils/rbutilqt/lang/
/utils/rbutilqt/lang/*.qm
# More rbutil
/utils/*/buildposix
/utils/*/uninstall_script.[ch]
/utils/*/install_script.[ch]
/utils/mkimxboot/mkimxboot
/utils/mknwzboot/mknwzboot
/utils/mkzenboot/mkzenboot
/utils/sansapatcher/sansapatcher
/utils/jztool/jztool
/utils/tools/bin2c
# /tools/
/tools/bdf2bmp
/tools/scramble
/tools/generate_rocklatin
/tools/descramble
/tools/convbdf
/tools/bmp2rb
/tools/codepages
/tools/rdf2binary
/tools/mkboot
/tools/uclpack
/tools/ipod_fw
/tools/wavtrim
/tools/voicefont
/tools/rbspeexenc
/tools/rbspeexdec
/tools/mknkboot
/tools/mktccboot
/tools/mkzenboot
/tools/mkspl-x1000
/tools/iaudio_bl_flash.c
/tools/iaudio_bl_flash.h
/tools/.vagrant
/tools/*-console.log
# /tools/database/
/tools/database/database
# /tools/rbspeex/
/tools/rbspeex/build*
/tools/rbspeex/libspeex.a
/tools/rbspeex/librbspeex.a
/tools/rbspeex/dep-speex
# /tools/ucl/src/
/tools/ucl/src/libucl.a
# /utils/MTP/
/utils/MTP/sendfirm
# /utils/MTP/beastpatcher/
/utils/MTP/beastpatcher/bootimg.*
/utils/MTP/beastpatcher/beastpatcher
/utils/MTP/beastpatcher/bin2c*
# /utils/MTP/beastpatcher/vs2005/
/utils/MTP/beastpatcher/vs2005/*.ncb
/utils/MTP/beastpatcher/vs2005/*.suo
/utils/MTP/beastpatcher/vs2005/*.user
/utils/MTP/beastpatcher/vs2005/Debug
/utils/MTP/beastpatcher/vs2005/Release
# /utils/jz4740_tools/
/utils/jz4740_tools/HXFreplace
/utils/jz4740_tools/HXF2IHFS
/utils/jz4740_tools/usbtool
/utils/jz4740_tools/DLanalyser
/utils/jz4740_tools/HXFsplit
/utils/jz4740_tools/HXFmerge
/utils/jz4740_tools/IHFSsplit
/utils/jz4740_tools/jz_xloader.*
/utils/jz4740_tools/bin2c
# /utils/jz4760_tools
/utils/jz4760_tools/packtools
/utils/jz4760_tools/usbboot
# /utils/ingenic_tools
/utils/ingenic_tools/usbboot
# /utils/nwztools
/utils/nwztools/scsitools/scsitool
/utils/nwztools/upgtools/upgtool
# utils/rk27utils
/utils/rk27utils/rkboottool/rkboottool
# /utils/themeeditor/
/utils/themeeditor/debug
/utils/themeeditor/release
/utils/themeeditor/build
/utils/themeeditor/Makefile*
/utils/themeeditor/object_script*
/utils/themeeditor/rbthemeeditor
# /utils/zenutils/
/utils/zenutils/build
/utils/zenutils/bin
/utils/zenutils/CMakeCache.txt
/utils/zenutils/CMakeFiles
/utils/zenutils/cmake_install.cmake
/utils/zenutils/Makefile
# /utils/zenutils/libraries/
/utils/zenutils/libraries/CMakeCache.txt
/utils/zenutils/libraries/CMakeFiles
/utils/zenutils/libraries/cmake_install.cmake
/utils/zenutils/libraries/Makefile
# /utils/zenutils/libraries/beecrypt-4.1.2/
/utils/zenutils/libraries/beecrypt-4.1.2/CMakeCache.txt
/utils/zenutils/libraries/beecrypt-4.1.2/CMakeFiles
/utils/zenutils/libraries/beecrypt-4.1.2/cmake_install.cmake
/utils/zenutils/libraries/beecrypt-4.1.2/Makefile
# /utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/
/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/CMakeCache.txt
/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/CMakeFiles
/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/cmake_install.cmake
/utils/zenutils/libraries/beecrypt-4.1.2/beecrypt/Makefile
# /utils/zenutils/libraries/getpot-c++-1.1.18/
/utils/zenutils/libraries/getpot-c++-1.1.18/CMakeCache.txt
/utils/zenutils/libraries/getpot-c++-1.1.18/CMakeFiles
/utils/zenutils/libraries/getpot-c++-1.1.18/cmake_install.cmake
/utils/zenutils/libraries/getpot-c++-1.1.18/Makefile
# /utils/zenutils/libraries/getpot-c++-1.1.18/getpot/
/utils/zenutils/libraries/getpot-c++-1.1.18/getpot/CMakeCache.txt
/utils/zenutils/libraries/getpot-c++-1.1.18/getpot/CMakeFiles
/utils/zenutils/libraries/getpot-c++-1.1.18/getpot/cmake_install.cmake
/utils/zenutils/libraries/getpot-c++-1.1.18/getpot/Makefile
# /utils/zenutils/libraries/pelib-0.9/
/utils/zenutils/libraries/pelib-0.9/CMakeCache.txt
/utils/zenutils/libraries/pelib-0.9/CMakeFiles
/utils/zenutils/libraries/pelib-0.9/cmake_install.cmake
/utils/zenutils/libraries/pelib-0.9/Makefile
# /utils/zenutils/libraries/pelib-0.9/pelib/
/utils/zenutils/libraries/pelib-0.9/pelib/CMakeCache.txt
/utils/zenutils/libraries/pelib-0.9/pelib/CMakeFiles
/utils/zenutils/libraries/pelib-0.9/pelib/cmake_install.cmake
/utils/zenutils/libraries/pelib-0.9/pelib/Makefile
# /utils/zenutils/libraries/pelib-0.9/pelib/buffer/
/utils/zenutils/libraries/pelib-0.9/pelib/buffer/CMakeCache.txt
/utils/zenutils/libraries/pelib-0.9/pelib/buffer/CMakeFiles
/utils/zenutils/libraries/pelib-0.9/pelib/buffer/cmake_install.cmake
/utils/zenutils/libraries/pelib-0.9/pelib/buffer/Makefile
# /utils/zenutils/libraries/zlib123/
/utils/zenutils/libraries/zlib123/CMakeCache.txt
/utils/zenutils/libraries/zlib123/CMakeFiles
/utils/zenutils/libraries/zlib123/cmake_install.cmake
/utils/zenutils/libraries/zlib123/Makefile
# /utils/zenutils/libraries/zlib123/zlib/
/utils/zenutils/libraries/zlib123/zlib/CMakeCache.txt
/utils/zenutils/libraries/zlib123/zlib/CMakeFiles
/utils/zenutils/libraries/zlib123/zlib/cmake_install.cmake
/utils/zenutils/libraries/zlib123/zlib/Makefile
# /utils/zenutils/source/
/utils/zenutils/source/CMakeCache.txt
/utils/zenutils/source/CMakeFiles
/utils/zenutils/source/cmake_install.cmake
/utils/zenutils/source/Makefile
# /utils/zenutils/source/firmware_extract/
/utils/zenutils/source/firmware_extract/CMakeCache.txt
/utils/zenutils/source/firmware_extract/CMakeFiles
/utils/zenutils/source/firmware_extract/cmake_install.cmake
/utils/zenutils/source/firmware_extract/Makefile
# /utils/zenutils/source/firmware_make/
/utils/zenutils/source/firmware_make/CMakeCache.txt
/utils/zenutils/source/firmware_make/CMakeFiles
/utils/zenutils/source/firmware_make/cmake_install.cmake
/utils/zenutils/source/firmware_make/Makefile
# /utils/zenutils/source/shared/
/utils/zenutils/source/shared/CMakeCache.txt
/utils/zenutils/source/shared/CMakeFiles
/utils/zenutils/source/shared/cmake_install.cmake
/utils/zenutils/source/shared/Makefile
# /utils/zenutils/source/update_extract/
/utils/zenutils/source/update_extract/CMakeCache.txt
/utils/zenutils/source/update_extract/CMakeFiles
/utils/zenutils/source/update_extract/cmake_install.cmake
/utils/zenutils/source/update_extract/Makefile
# /utils/zenutils/source/update_patch/
/utils/zenutils/source/update_patch/CMakeCache.txt
/utils/zenutils/source/update_patch/CMakeFiles
/utils/zenutils/source/update_patch/cmake_install.cmake
/utils/zenutils/source/update_patch/Makefile
# /utils/zenutils/source/zen_crypt/
/utils/zenutils/source/zen_crypt/CMakeCache.txt
/utils/zenutils/source/zen_crypt/CMakeFiles
/utils/zenutils/source/zen_crypt/cmake_install.cmake
/utils/zenutils/source/zen_crypt/Makefile
# /utils/regtools/
/utils/regtools/headergen_v1
/utils/regtools/headergen_v2
/utils/regtools/regtool
/utils/regtools/swiss_knife
/utils/regtools/tester_v1

View file

@ -1,5 +0,0 @@
[gerrit]
host=gerrit.rockbox.org
port=29418
project=rockbox.git
defaultbranch=master

View file

@ -3,7 +3,5 @@
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${workspace}"/>
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="false"/>
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="/usr/bin/make"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,auto,"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="libs NODEPS=''"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Rockbox}"/>
</launchConfiguration>

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType">
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${project_loc}/../tools/configure"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="--target=201 --type=ad --lcdwidth=320 --lcdheight=480"/>
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/>
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${project_loc}"/>
</launchConfiguration>

View file

@ -5,26 +5,6 @@
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>full,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/tools_configure.launch</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
<triggers>auto,full,incremental,</triggers>
<arguments>
<dictionary>
<key>LaunchConfigHandle</key>
<value>&lt;project&gt;/.externalToolBuilders/make libs.launch</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>

View file

@ -19,13 +19,7 @@
</intent-filter>
</activity>
<service android:name=".RockboxService">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.MEDIA_BUTTON" />
<action android:name="org.rockbox.ResendTrackUpdateInfo" />
</intent-filter>
</service>
<service android:name=".RockboxService"/>
<receiver android:name=".Helper.MediaButtonReceiver$MediaReceiver"
android:enabled="true"
@ -60,17 +54,6 @@
android:resource="@xml/appwidget_provider_2x2" />
</receiver>
<receiver android:name=".widgets.RockboxWidgetProvider3x3"
android:label="@string/appwidget_label_3x3">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="org.rockbox.TrackUpdateInfo" />
<action android:name="org.rockbox.TrackFinish" />
<action android:name="org.rockbox.UpdateState" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_provider_3x3" />
</receiver>
<!-- Widget configuration -->
<activity android:name=".widgets.RockboxWidgetConfigure">
<intent-filter>
@ -80,7 +63,7 @@
</application>
<uses-sdk android:minSdkVersion="5" />
<uses-sdk android:minSdkVersion="4" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
</manifest>

View file

@ -7,107 +7,83 @@
# $Id$
#
PACKAGE=org.rockbox
PACKAGE_PATH=org/rockbox
BINLIB_DIR=$(BUILDDIR)/libs/$(ANDROID_ARCH)
ANDROID_DIR=$(ROOTDIR)/android
# this is a glibc compatibility hack to provide a get_nprocs() replacement.
# The NDK ships cpu-features.c which has a compatible function android_getCpuCount()
CPUFEAT = $(ANDROID_NDK_PATH)/sources/android/cpufeatures
CPUFEAT_BUILD = $(BUILDDIR)
INCLUDES += -I$(CPUFEAT)
OTHER_SRC += $(CPUFEAT)/cpu-features.c
CLEANOBJS += $(CPUFEAT_BUILD)/cpu-features.o
$(CPUFEAT_BUILD)/cpu-features.o: $(CPUFEAT)/cpu-features.c
$(SILENT)mkdir -p $(dir $@)
$(call PRINTS,CC $(subst $(CPUFEAT)/,,$<))$(CC) -o $@ -c $^ $(GCCOPTS) -Wno-unused
.SECONDEXPANSION: # $$(JAVA_OBJ) is not populated until after this
.SECONDEXPANSION: # $$(OBJ) is not populated until after this
.PHONY: apk classes clean dex dirs libs jar
$(BUILDDIR)/$(BINARY): $$(OBJ) $(VOICESPEEXLIB) $(FIRMLIB) $(SKINLIB)
$(call PRINTS,LD $(BINARY))$(CC) -o $@ $^ $(LDOPTS) $(GLOBAL_LDOPTS)
PACKAGE=org.rockbox
PACKAGE_PATH=org/rockbox
ANDROID_DIR=$(ROOTDIR)/android
BINLIB_DIR=$(BUILDDIR)/libs/armeabi
java2class = $(addsuffix .class,$(basename $(subst $(ANDROID_DIR),$(BUILDDIR),$(1))))
# API version
#ANDROID_PLATFORM_VERSION=19 # Set by configure script
ANDROID_PLATFORM_VERSION=8
ANDROID_PLATFORM=$(ANDROID_SDK_PATH)/platforms/android-$(ANDROID_PLATFORM_VERSION)
# Use oldest version available..
BUILD_TOOLS_VERSION=$(notdir $(firstword $(wildcard $(ANDROID_SDK_PATH)/build-tools/*)))
# android tools
AAPT=$(ANDROID_SDK_PATH)/build-tools/$(BUILD_TOOLS_VERSION)/aapt
DX=$(ANDROID_SDK_PATH)/build-tools/$(BUILD_TOOLS_VERSION)/dx
ifneq ("$(wildcard $(ANDROID_SDK_PATH)/tools/zipalign)","")
ZIPALIGN=$(ANDROID_SDK_PATH)/tools/zipalign
else
ZIPALIGN=$(ANDROID_SDK_PATH)/build-tools/$(BUILD_TOOLS_VERSION)/zipalign
endif
AAPT=$(ANDROID_PLATFORM)/tools/aapt
DX=$(ANDROID_PLATFORM)/tools/dx
APKBUILDER=$(ANDROID_SDK_PATH)/tools/apkbuilder
ZIPALIGN=$(ANDROID_SDK_PATH)/tools/zipalign
KEYSTORE=$(HOME)/.android/debug.keystore
ADB=$(ANDROID_SDK_PATH)/platform-tools/adb
BUILDAPK=$(ANDROID_DIR)/buildapk.sh
CLASSPATH := $(BUILDDIR)/bin/classes
MANIFEST := $(BUILDDIR)/bin/AndroidManifest.xml
MANIFEST_SRC := $(ANDROID_DIR)/AndroidManifest.xml
MANIFEST := $(ANDROID_DIR)/AndroidManifest.xml
R_JAVA := $(BUILDDIR)/gen/$(PACKAGE_PATH)/R.java
R_OBJ := $(CLASSPATH)/$(PACKAGE_PATH)/R.class
R_OBJ := $(BUILDDIR)/bin/$(PACKAGE_PATH)/R.class
JAVA_SRC := $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/*.java)
JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/Helper/*.java)
JAVA_SRC := $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/Helper/*.java)
JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/*.java)
JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/widgets/*.java)
JAVA_SRC += $(wildcard $(ANDROID_DIR)/src/$(PACKAGE_PATH)/monitors/*.java)
java2class = $(addsuffix .class,$(basename $(subst $(ANDROID_DIR)/src,$(CLASSPATH),$(1))))
JAVA_OBJ := $(call java2class,$(JAVA_SRC))
JAVA_OBJ := $(call java2class,$(subst $(ANDROID)/src/$(PACKAGE_PATH),$(ANDROID)/bin/$(PACKAGE_PATH),$(JAVA_SRC)))
LIBS := $(BINLIB_DIR)/$(BINARY) $(BINLIB_DIR)/libmisc.so
LIBS += $(addprefix $(BINLIB_DIR)/lib,$(patsubst %.codec,%.so,$(notdir $(CODECS))))
TEMP_APK := $(BUILDDIR)/bin/_rockbox.apk
TEMP_APK2 := $(BUILDDIR)/bin/__rockbox.apk
DEX := $(BUILDDIR)/bin/classes.dex
JAR := $(BUILDDIR)/bin/classes.jar
AP_ := $(BUILDDIR)/bin/resources.ap_
APK := $(BUILDDIR)/rockbox.apk
DEX := $(BUILDDIR)/bin/classes.dex
JAR := $(BUILDDIR)/bin/classes.jar
AP_ := $(BUILDDIR)/bin/resources.ap_
APK := $(BUILDDIR)/rockbox.apk
_DIRS := $(BUILDDIR)/___/$(PACKAGE_PATH)
DIRS := $(subst ___,bin,$(_DIRS))
DIRS += $(subst ___,gen,$(_DIRS))
DIRS += $(subst ___,data,$(_DIRS))
DIRS += $(BUILDDIR)/libs/$(ANDROID_ARCH)
DIRS += $(CPUFEAT_BUILD)
DIRS += $(CLASSPATH)
DIRS += $(BUILDDIR)/libs/armeabi
RES := $(wildcard $(ANDROID_DIR)/res/*/*)
CLEANOBJS += bin gen libs data
JAVAC_OPTS += -source 1.6 -target 1.6 -implicit:none -classpath $(ANDROID_PLATFORM)/android.jar:$(CLASSPATH)
.PHONY:
$(MANIFEST): $(MANIFEST_SRC) $(DIRS)
$(call PRINTS,MANIFEST $(@F))sed -e 's/versionName="1.0"/versionName="$(SVNVERSION)"/;s/screenOrientation="portrait"/screenOrientation="$(LCDORIENTATION)"/' $(MANIFEST_SRC) > $(MANIFEST)
JAVAC_OPTS += -implicit:none -classpath $(ANDROID_PLATFORM)/android.jar:$(BUILDDIR)/bin
$(R_JAVA) $(AP_): $(MANIFEST) $(RES) | $(DIRS)
$(call PRINTS,AAPT $(subst $(BUILDDIR)/,,$@))$(AAPT) package -f -m \
-J $(BUILDDIR)/gen -M $(MANIFEST) -S $(ANDROID_DIR)/res \
-I $(ANDROID_PLATFORM)/android.jar -F $(AP_)
$(CLASSPATH)/$(PACKAGE_PATH)/R.class: $(R_JAVA)
$(BUILDDIR)/bin/$(PACKAGE_PATH)/R.class: $(R_JAVA)
$(call PRINTS,JAVAC $(subst $(ROOTDIR)/,,$<))javac -d $(BUILDDIR)/bin \
$(JAVAC_OPTS) -sourcepath $(ANDROID_DIR)/gen $<
$(JAVAC_OPTS) \
-sourcepath $(ANDROID_DIR)/gen $<
$(CLASSPATH)/$(PACKAGE_PATH)/%.class: $(ANDROID_DIR)/src/$(PACKAGE_PATH)/%.java $(CLASSPATH)/$(PACKAGE_PATH)/R.class
$(call PRINTS,JAVAC $(subst $(ROOTDIR)/,,$<))javac -d $(CLASSPATH) \
$(JAVAC_OPTS) -sourcepath $(ANDROID_DIR)/src $<
$(BUILDDIR)/bin/$(PACKAGE_PATH)/%.class: $(ANDROID_DIR)/src/$(PACKAGE_PATH)/%.java $(BUILDDIR)/bin/$(PACKAGE_PATH)/R.class
$(call PRINTS,JAVAC $(subst $(ROOTDIR)/,,$<))javac -d $(BUILDDIR)/bin \
$(JAVAC_OPTS) \
-sourcepath $(ANDROID_DIR)/src $<
$(JAR): $(JAVA_SRC) $(R_JAVA)
$(call PRINTS,JAVAC $(subst $(ROOTDIR)/,,$?))javac -d $(CLASSPATH) \
$(JAVAC_OPTS) -sourcepath $(ANDROID_DIR)/src:$(ANDROID_DIR)/gen $?
$(call PRINTS,JAR $(subst $(BUILDDIR)/,,$@))jar cf $(JAR) -C $(CLASSPATH) org
$(call PRINTS,JAVAC $(subst $(ROOTDIR)/,,$?))javac -d $(BUILDDIR)/bin \
$(JAVAC_OPTS) \
-sourcepath $(ANDROID_DIR)/src:$(ANDROID_DIR)/gen $?
$(call PRINTS,JAR $(subst $(BUILDDIR)/,,$@))jar cf $(JAR) -C $(BUILDDIR)/bin org
jar: $(JAR)
@ -120,43 +96,29 @@ dex: $(DEX)
classes: $(R_OBJ) $(JAVA_OBJ)
$(BUILDDIR)/$(BINARY): $$(OBJ) $(FIRMLIB) $(VOICESPEEXLIB) $(CORE_LIBS) $(CPUFEAT_BUILD)/cpu-features.o
$(call PRINTS,LD $(BINARY))$(CC) -o $@ $^ $(LDOPTS) $(GLOBAL_LDOPTS) -Wl,-Map,$(BUILDDIR)/rockbox.map
$(call PRINTS,OC $(@F))$(call objcopy,$@,$@)
$(BINLIB_DIR)/$(BINARY): $(BUILDDIR)/$(BINARY)
$(call PRINTS,CP $(BINARY))cp $^ $@
$(BINLIB_DIR)/libmisc.so: $(BUILDDIR)/rockbox.zip
$(call PRINTS,CP rockbox.zip)cp $^ $@
$(BINLIB_DIR)/lib%.so: $(RBCODEC_BLD)/codecs/%.codec
$(call PRINTS,CP $(@F))cp $^ $@
libs: $(DIRS) $(LIBS)
libs: $(LIBS)
$(TEMP_APK): $(AP_) $(LIBS) $(DEX) | $(DIRS)
$(call PRINTS,APK $(subst $(BUILDDIR)/,,$@))$(BUILDAPK) $(BUILDDIR) $(notdir $@) $(BUILD_TOOLS_VERSION)
$(call PRINTS,APK $(subst $(BUILDDIR)/,,$@))$(APKBUILDER) $@ \
-u -z $(AP_) -f $(DEX) -nf $(BUILDDIR)/libs
$(KEYSTORE):
$(SILENT)mkdir -p $(HOME)/.android
$(call PRINTS,KEYTOOL debug.keystore)keytool -genkey \
-alias androiddebugkey -keystore $@ \
-storepass android -keypass android -validity 365 \
-sigalg MD5withRSA -keyalg RSA -keysize 1024 \
-dname "CN=Android Debug,O=Android,C=US"
ifdef NODEPS
$(APK): $(TEMP_APK) $(KEYSTORE)
else
$(APK): $(TEMP_APK) $(BUILDDIR)/rockbox.zip $(KEYSTORE)
endif
$(SILENT)rm -f $@
$(call PRINTS,SIGN $(subst $(BUILDDIR)/,,$@))jarsigner \
-keystore "$(KEYSTORE)" -storepass "android" -keypass "android" \
-signedjar $(TEMP_APK2) $(TEMP_APK) "androiddebugkey" \
-sigalg MD5withRSA -digestalg SHA1
-signedjar $(TEMP_APK2) $(TEMP_APK) "androiddebugkey"
$(SILENT)$(ZIPALIGN) -v 4 $(TEMP_APK2) $@ > /dev/null
$(DIRS):
@ -167,7 +129,5 @@ dirs: $(DIRS)
apk: $(APK)
install: apk
$(SILENT)$(ADB) install -r $(APK)
$(ADB) install -r $(APK)
launch:
$(SILENT)echo 'am start -a android.intent.action.MAIN -n org.rockbox/.RockboxActivity; exit' | $(ADB) shell >/dev/null

View file

@ -1,12 +0,0 @@
# Override some props according to android.make
# see $ANDROID_SDK_PATH/tools/ant/build.xml for what's overridable
# Once we can build signed *release* builds, we should have a different
# names for the debug builds
# the signed, unzipaligned file is bin/__rockbox.apk
out.packaged.file=bin/__${ant.project.name}.apk
# the final file is rockbox.apk, in the build dir
out.packaged.file=${ant.project.name}.apk

View file

@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="rockbox" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through an env var"
unless="sdk.dir"
/>
<!-- extension targets. Uncomment the ones where you want to do custom work
in between standard targets -->
<!--
<target name="-pre-build">
</target>
<target name="-pre-compile">
</target>
/* This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir} */
<target name="-post-compile">
</target>
-->
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

View file

@ -1,19 +0,0 @@
#!/bin/sh
BUILDDIR=$1
APK=$2
SDKV=$3
[ -z $ANDROID_SDK_PATH ] && exit 1
[ -z $BUILDDIR ] && exit 1
[ -d $BUILDDIR ] || exit 1
# need to cd into the bin dir and create a symlink to the libraries
# so that aapt puts the libraries with the correct prefix into the apk
cd $BUILDDIR/bin
ln -nfs $BUILDDIR/libs lib
cp resources.ap_ $APK
$ANDROID_SDK_PATH/build-tools/$SDKV/aapt add $APK classes.dex > /dev/null
$ANDROID_SDK_PATH/build-tools/$SDKV/aapt add $APK lib/*/* > /dev/null
exit 0

View file

@ -0,0 +1,11 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-8

10
android/installApk.sh Executable file
View file

@ -0,0 +1,10 @@
#!/bin/sh
ADB="$ANDROID_SDK_PATH/tools/adb"
if [ ! -e $ADB ]
then
# Starting with the gingerbread sdk, the adb location changed
ADB="$ANDROID_SDK_PATH/platform-tools/adb"
fi
$ADB install -r rockbox.apk
echo 'am start -a android.intent.action.MAIN -n org.rockbox/.RockboxActivity; exit' | $ADB shell

View file

@ -6,35 +6,10 @@
# it stopped
set -e
SDK_DOWNLOAD_URL="http://developer.android.com/sdk/index.html"
NDK_DOWNLOAD_URL="http://developer.android.com/sdk/ndk/index.html"
find_url() {
base_url="$1"
os="$2"
wget -q -O - $base_url | grep dl.google.com | sed 's/.*"\(http:\/\/.*\)".*/\1/' | grep $os | grep -v bundle | grep -v .exe # Windows hack
}
OS=`uname`
case $OS in
Linux)
SDK_URL=$(find_url $SDK_DOWNLOAD_URL linux)
NDK_URL=$(find_url $NDK_DOWNLOAD_URL linux)
ANDROID=tools/android
;;
Darwin)
SDK_URL=$(find_url $SDK_DOWNLOAD_URL mac)
NDK_URL=$(find_url $NDK_DOWNLOAD_URL darwin)
ANDROID=tools/android
;;
CYGWIN*)
SDK_URL=$(find_url $SDK_DOWNLOAD_URL windows)
NDK_URL=$(find_url $NDK_DOWNLOAD_URL windows)
ANDROID=tools/android.bat
;;
esac
# http://developer.android.com/sdk/index.html
SDK_URL="http://dl.google.com/android/android-sdk_r09-linux_x86.tgz"
# http://developer.android.com/sdk/ndk/index.html
NDK_URL="http://dl.google.com/android/ndk/android-ndk-r5b-linux-x86.tar.bz2"
prefix="${INSTALL_PREFIX:-$HOME}"
dldir="${DOWNLOAD_DIR:-/tmp}"
@ -52,14 +27,14 @@ download_and_extract() {
fi
echo " * Extracting $name..."
case ${local_file} in
*.zip)
case ${local_file#*.} in
zip)
unzip -qo -d "$prefix" "$local_file"
;;
*.tgz|*.tar.gz)
(cd $prefix; tar -xzf "$local_file")
tgz|tar.gz)
(cd $prefix; tar -xf "$local_file")
;;
*.tar.bz2)
tar.bz2)
(cd $prefix; tar -xjf "$local_file")
;;
*)
@ -70,17 +45,16 @@ download_and_extract() {
if [ -z "$SDK_PATH" ]; then
download_and_extract $SDK_URL
# OS X doesn't know about realname, use basename instead.
SDK_PATH=$prefix/$(basename $prefix/android-sdk-*)
SDK_PATH=$(realpath $prefix/android-sdk-*)
fi
if [ -z "$NDK_PATH" ]; then
download_and_extract $NDK_URL
NDK_PATH=$prefix/$(basename $prefix/android-ndk-*)
NDK_PATH=$(realpath $prefix/android-ndk-*)
fi
if [ -z "$(find $SDK_PATH/platforms -type d -name 'android-*')" ]; then
echo " * Installing Android platforms..."
$SDK_PATH/$ANDROID update sdk --no-ui --filter platform,platform-tool,tool
$SDK_PATH/tools/android update sdk --no-ui --filter platform,tool
fi
cat <<EOF

View file

@ -1,40 +0,0 @@
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

View file

@ -1,11 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-19

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View file

@ -8,12 +8,10 @@
android:background="@drawable/appwidget_background">
<!-- style="@style/appwidget_background"-->
<ImageButton android:id="@+id/logo"
android:layout_marginTop="5dp"
<ImageView android:id="@+id/logo"
android:layout_width="fill_parent"
android:layout_height="80dp"
android:scaleType="centerInside"
android:background="@drawable/appwidget_infodisplay_background"
android:layout_height="40dp"
android:scaleType="centerInside"
android:src="@drawable/rockbox" />
<Button android:id="@+id/infoDisplay"
style="@style/appwidget_infodisplay"

View file

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center"
android:background="@drawable/appwidget_background">
<!-- style="@style/appwidget_background"-->
<ImageView android:layout_height="16dp"
android:layout_width="wrap_content"
android:layout_marginTop="6dp"
android:scaleType="centerInside"
android:background="@drawable/appwidget_infodisplay_background"
android:src="@drawable/nowplaying" />
<ImageButton android:id="@+id/logo"
android:layout_marginTop="6dp"
android:layout_width="fill_parent"
android:layout_height="130dp"
android:scaleType="centerInside"
android:background="@drawable/appwidget_infodisplay_background"
android:src="@drawable/rockbox" />
<Button android:id="@+id/infoDisplay"
style="@style/appwidget_infodisplay"
android:layout_width="fill_parent"
android:text="@string/appwidget_infoDisplay" />
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center"
android:orientation="horizontal">
<ImageButton android:id="@+id/prev"
style="@style/appwidget_button"
android:layout_weight="1"
android:src="@drawable/appwidget_prev" />
<ImageButton android:id="@+id/stop"
style="@style/appwidget_button"
android:layout_weight="1"
android:src="@drawable/appwidget_stop" />
<ImageButton android:id="@+id/playPause"
style="@style/appwidget_button"
android:layout_weight="1"
android:src="@drawable/appwidget_play" />
<ImageButton android:id="@+id/next"
style="@style/appwidget_button"
android:layout_weight="1"
android:src="@drawable/appwidget_next" />
</LinearLayout>
</LinearLayout>

View file

@ -8,12 +8,6 @@
android:background="@drawable/appwidget_background">
<!-- style="@style/appwidget_background"-->
<ImageButton android:id="@+id/logo"
android:layout_width="68dp"
android:layout_height="fill_parent"
android:scaleType="centerInside"
android:background="@drawable/appwidget_infodisplay_background"
android:src="@drawable/rockbox" />
<Button android:id="@+id/infoDisplay"
style="@style/appwidget_infodisplay"
android:layout_height="fill_parent"

View file

@ -1,10 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<LinearLayout android:layout_width="fill_parent"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
@ -18,10 +15,6 @@
android:layout_height="wrap_content"
android:text="@string/appwidget_configure_instructions"/>
<CheckBox android:id="@+id/enable_aa"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/appwidget_configure_albumart"/>
<CheckBox android:id="@+id/enable_prev"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
@ -44,5 +37,4 @@
android:layout_height="wrap_content"
android:text="@string/appwidget_configure_confirm"/>
</LinearLayout>
</ScrollView>

View file

@ -8,20 +8,19 @@
android:paddingBottom="0dp"
android:orientation="horizontal">
<ImageView android:id="@+id/artwork"
android:gravity="center"
android:padding="2dp"
android:scaleType="center"
android:adjustViewBounds="false"
android:layout_width="wrap_content"
android:layout_height="fill_parent">
</ImageView>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView android:src="@drawable/notification_small"
android:gravity="center"
android:paddingTop="2dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</ImageView>
<TextView android:id="@+id/title"
android:layout_width="wrap_content"
@ -39,7 +38,7 @@
<LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="3dp"
android:orientation="horizontal">
android:orientation="vertical">
<TextView android:id="@+id/content"
android:layout_gravity="left"
android:scrollHorizontally="true"

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">afrikaans.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">arabic.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">bulgarian.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">portugues-brasileiro.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">catala.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">wallisertitsch.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">czech.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">dansk.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">deutsch.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">greek.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">esperanto.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">espanol.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">eesti.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">finnish.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">francais.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">galego.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">hebrew.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">hindi.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">hrvatski.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">magyar.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">islenska.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">italiano.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">japanese.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">korean.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">lietuviu.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">nederlands.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">norsk-nynorsk.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">norsk.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">polski.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">portugues.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">romaneste.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">russian.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">slovak.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">slovenscina.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">srpski.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">svenska.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">thai.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">tagalog.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">turkce.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">ukrainian.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">walon.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">chinese-simp.lng</string>
</resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="rockbox_language_file">chinese-trad.lng</string>
</resources>

View file

@ -6,24 +6,18 @@
<string name="OK">OK</string>
<string name="Cancel">Cancel</string>
<string name="KbdInputTitle">Rockbox Keyboard Input</string>
<string name="YesNoTitle">Rockbox</string>
<string name="Yes">Yes</string>
<string name="No">No</string>
<string name="error_extraction">Error occured during extraction!</string>
<string name="rockbox_extracting">Rockbox is loading. Please wait...</string>
<!-- Rockbox initial configuration values -->
<string name="rockbox_language_file">english.lng</string>
<!-- Widget -->
<string name="appwidget_label_4x1">Rockbox (line)</string>
<string name="appwidget_label_2x2">Rockbox (square)</string>
<string name="appwidget_label_3x3">Rockbox (big square)</string>
<string name="appwidget_infoDisplay">Touch to launch app</string>
<!-- Widget configuration -->
<string name="appwidget_configure_instructions">Please chose elements to display in widget.</string>
<string name="appwidget_configure_albumart">Cover Art</string>
<string name="appwidget_configure_prev">Prev Button</string>
<string name="appwidget_configure_stop">Stop Button</string>
<string name="appwidget_configure_playpause">Play/Pause Button</string>

View file

@ -1,8 +0,0 @@
<!-- cell size is (number of cells * 74) - 2 dp according to http://developer.android.com/guide/topics/appwidgets/index.html#MetaData -->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="220dp"
android:minHeight="220dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/appwidget_3x3"
android:configure="org.rockbox.widgets.RockboxWidgetConfigure">
</appwidget-provider>

View file

@ -1,48 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 Thomas Martitz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
package org.rockbox.Helper;
import android.util.Log;
public class Logger
{
private static final String TAG = "Rockbox";
public static void i(String s)
{
Log.i(TAG, s);
}
public static void d(String s)
{
Log.d(TAG, s);
}
public static void d(String s, Throwable t)
{
Log.d(TAG, s, t);
}
public static void e(String s)
{
Log.e(TAG, s);
}
}

View file

@ -21,8 +21,10 @@
package org.rockbox.Helper;
import org.rockbox.RockboxFramebuffer;
import java.lang.reflect.Method;
import org.rockbox.RockboxService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@ -54,11 +56,8 @@ public class MediaButtonReceiver
{
try {
api = new NewApi(c);
} catch (Throwable t) {
/* Throwable includes Exception and the expected
* NoClassDefFoundError */
} catch (Exception e) {
api = new OldApi(c);
Logger.i("MediaButtonReceiver: Falling back to compatibility API");
}
}
@ -69,17 +68,12 @@ public class MediaButtonReceiver
public void unregister()
{
api.unregister();
api.register();
}
/* helper class for the manifest */
public static class MediaReceiver extends BroadcastReceiver
{
private void startService(Context c, Intent baseIntent)
{
baseIntent.setClass(c, RockboxService.class);
c.startService(baseIntent);
}
{
@Override
public void onReceive(Context context, Intent intent)
{
@ -87,11 +81,8 @@ public class MediaButtonReceiver
{
KeyEvent key = (KeyEvent)intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
if (key.getAction() == KeyEvent.ACTION_UP)
{ /* pass the pressed key to Rockbox, starting it if needed */
RockboxService s = RockboxService.getInstance();
if (s == null || !s.isRockboxRunning())
startService(context, intent);
else if (RockboxFramebuffer.buttonHandler(key.getKeyCode(), false))
{ /* pass the pressed key to Rockbox */
if (RockboxService.get_instance().get_fb().dispatchKeyEvent(key))
abortBroadcast();
}
}
@ -104,54 +95,46 @@ public class MediaButtonReceiver
void unregister();
}
private static class NewApi
implements IMultiMediaReceiver, AudioManager.OnAudioFocusChangeListener
private static class NewApi implements IMultiMediaReceiver
{
private Method register_method;
private Method unregister_method;
private AudioManager audio_manager;
private ComponentName receiver_name;
private boolean running = false;
NewApi(Context c)
/* the constructor gets the methods through reflection so that
* this compiles on pre-2.2 devices */
NewApi(Context c) throws SecurityException, NoSuchMethodException
{
register_method = AudioManager.class.getMethod(
"registerMediaButtonEventReceiver",
new Class[] { ComponentName.class } );
unregister_method = AudioManager.class.getMethod(
"unregisterMediaButtonEventReceiver",
new Class[] { ComponentName.class } );
audio_manager = (AudioManager)c.getSystemService(Context.AUDIO_SERVICE);
receiver_name = new ComponentName(c, MediaReceiver.class);
}
public void register()
{
try {
audio_manager.registerMediaButtonEventReceiver(receiver_name);
audio_manager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
running = true;
register_method.invoke(audio_manager, receiver_name);
} catch (Exception e) {
// Nothing
e.printStackTrace();
}
}
}
public void unregister()
{
try
{
audio_manager.unregisterMediaButtonEventReceiver(receiver_name);
audio_manager.abandonAudioFocus(this);
running = false;
unregister_method.invoke(audio_manager, receiver_name);
} catch (Exception e) {
// Nothing
e.printStackTrace();
}
}
public void onAudioFocusChange(int focusChange)
{
Logger.d("Audio focus" + ((focusChange>0)?"gained":"lost")+
": "+ focusChange);
if (running)
{ /* Play nice and stop for the the other app */
if (focusChange == AudioManager.AUDIOFOCUS_LOSS)
RockboxFramebuffer.buttonHandler(KeyEvent.KEYCODE_MEDIA_STOP, false);
}
}
}

View file

@ -1,18 +1,18 @@
package org.rockbox.Helper;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.rockbox.R;
import org.rockbox.RockboxActivity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.net.Uri;
import android.util.Log;
import android.widget.RemoteViews;
public class RunForegroundManager
@ -24,9 +24,6 @@ public class RunForegroundManager
private NotificationManager mNM;
private IRunForeground api;
private Service mCurrentService;
private Handler mServiceHandler;
private Intent mWidgetUpdate;
private int iconheight;
public RunForegroundManager(Service service)
{
@ -38,11 +35,6 @@ public class RunForegroundManager
Intent intent = new Intent(service, RockboxActivity.class);
intent = intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
/* retrieve height of launcher icon. Used to scale down album art. */
Resources resources = service.getResources();
Drawable draw = resources.getDrawable(R.drawable.launcher);
iconheight = draw.getIntrinsicHeight();
mNotification = new Notification();
mNotification.tickerText = service.getString(R.string.notification);
mNotification.icon = R.drawable.notification;
@ -51,18 +43,19 @@ public class RunForegroundManager
mNotification.contentIntent = PendingIntent.getActivity(service, 0, intent, 0);
try {
api = new NewForegroundApi(R.string.notification, mNotification);
} catch (Throwable t) {
/* Throwable includes Exception and the expected
* NoClassDefFoundError for Android 1.x */
try {
api = new OldForegroundApi();
Logger.i("RunForegroundManager: Falling back to compatibility API");
} catch (Exception e) {
Logger.e("Cannot run in foreground: No available API");
}
api = new newForegroundApi(R.string.notification, mNotification);
} catch (NoSuchMethodException e) {
/* Fall back on the old API */
api = new oldForegroundApi();
}
mServiceHandler = new Handler(service.getMainLooper());
}
private void LOG(CharSequence text)
{
Log.d("Rockbox", (String)text);
}
private void LOG(CharSequence text, Throwable tr)
{
Log.d("Rockbox", (String)text, tr);
}
public void startForeground()
@ -88,72 +81,29 @@ public class RunForegroundManager
*/
mNM.cancel(R.string.notification);
api.stopForeground();
mWidgetUpdate = null;
}
public void updateNotification(final String title, final String artist, final String album, final String albumart)
public void updateNotification(String title, String artist, String album)
{
/* do this on the main thread for 2 reasons
* 1) Don't delay track switching with possibly costly albumart
* loading (i.e. off-load from the Rockbox thread)
* 2) Work around a bug in Android where decodeFile() fails outside
* of the main thread (http://stackoverflow.com/q/7228633)
*/
mServiceHandler.post(new Runnable()
{
@Override
public void run()
{
final RemoteViews views = mNotification.contentView;
views.setTextViewText(R.id.title, title);
views.setTextViewText(R.id.content, artist+"\n"+album);
if (artist.equals(""))
mNotification.tickerText = title;
else
mNotification.tickerText = title+" - "+artist;
RemoteViews views = mNotification.contentView;
views.setTextViewText(R.id.title, title);
views.setTextViewText(R.id.content, artist+"\n"+album);
if (artist.equals(""))
mNotification.tickerText = title;
else
mNotification.tickerText = title+" - "+artist;
mNM.notify(R.string.notification, mNotification);
if (albumart != null) {
/* The notification area doesn't have permissions to access the SD card.
* Push the data as Bitmap instead of Uri. Scale down to size of
* launcher icon -- broadcasting the unscaled image may yield in
* too much data, causing UI hangs of Rockbox. */
Bitmap b = BitmapFactory.decodeFile(albumart);
if(b != null) {
/* scale width to keep aspect ratio -- height is the constraint */
int scaledwidth = Math.round(iconheight*((float)b.getWidth()/b.getHeight()));
views.setImageViewBitmap(R.id.artwork,
Bitmap.createScaledBitmap(b, scaledwidth, iconheight, false));
}
else {
views.setImageViewResource(R.id.artwork, R.drawable.launcher);
}
}
else {
views.setImageViewResource(R.id.artwork, R.drawable.launcher);
}
mWidgetUpdate = new Intent("org.rockbox.TrackUpdateInfo");
mWidgetUpdate.putExtra("title", title);
mWidgetUpdate.putExtra("artist", artist);
mWidgetUpdate.putExtra("album", album);
mWidgetUpdate.putExtra("albumart", albumart);
mCurrentService.sendBroadcast(mWidgetUpdate);
/* notify in this runnable to make sure the notification
* has the correct albumart */
mNM.notify(R.string.notification, mNotification);
}
});
}
public void resendUpdateNotification()
{
if (mWidgetUpdate != null)
mCurrentService.sendBroadcast(mWidgetUpdate);
Intent widgetUpdate = new Intent("org.rockbox.TrackUpdateInfo");
widgetUpdate.putExtra("title", title);
widgetUpdate.putExtra("artist", artist);
widgetUpdate.putExtra("album", album);
mCurrentService.sendBroadcast(widgetUpdate);
}
public void finishNotification()
{
Logger.d("TrackFinish");
Log.d("Rockbox", "TrackFinish");
Intent widgetUpdate = new Intent("org.rockbox.TrackFinish");
mCurrentService.sendBroadcast(widgetUpdate);
}
@ -164,57 +114,68 @@ public class RunForegroundManager
void stopForeground();
}
private class NewForegroundApi implements IRunForeground
private class newForegroundApi implements IRunForeground
{
int id;
Notification mNotification;
NewForegroundApi(int _id, Notification _notification)
Class<?>[] mStartForegroundSignature =
new Class[] { int.class, Notification.class };
Class<?>[] mStopForegroundSignature =
new Class[] { boolean.class };
private Method mStartForeground;
private Method mStopForeground;
private Object[] mStartForegroundArgs = new Object[2];
private Object[] mStopForegroundArgs = new Object[1];
newForegroundApi(int id, Notification notification)
throws SecurityException, NoSuchMethodException
{
id = _id;
mNotification = _notification;
/*
* Get the new API through reflection
*/
mStartForeground = Service.class.getMethod("startForeground",
mStartForegroundSignature);
mStopForeground = Service.class.getMethod("stopForeground",
mStopForegroundSignature);
mStartForegroundArgs[0] = id;
mStartForegroundArgs[1] = notification;
mStopForegroundArgs[0] = Boolean.TRUE;
}
public void startForeground()
{
mCurrentService.startForeground(id, mNotification);
try {
mStartForeground.invoke(mCurrentService, mStartForegroundArgs);
} catch (InvocationTargetException e) {
/* Should not happen. */
LOG("Unable to invoke startForeground", e);
} catch (IllegalAccessException e) {
/* Should not happen. */
LOG("Unable to invoke startForeground", e);
}
}
public void stopForeground()
{
mCurrentService.stopForeground(true);
try {
mStopForeground.invoke(mCurrentService, mStopForegroundArgs);
} catch (InvocationTargetException e) {
/* Should not happen. */
LOG("Unable to invoke stopForeground", e);
} catch (IllegalAccessException e) {
/* Should not happen. */
LOG("Unable to invoke stopForeground", e);
}
}
}
private class OldForegroundApi implements IRunForeground
private class oldForegroundApi implements IRunForeground
{
/*
* Get the new API through reflection because it's unavailable
* in honeycomb
*/
private Method mSetForeground;
public OldForegroundApi() throws SecurityException, NoSuchMethodException
{
mSetForeground = getClass().getMethod("setForeground",
new Class[] { boolean.class });
}
public void startForeground()
{
try {
mSetForeground.invoke(mCurrentService, Boolean.TRUE);
} catch (Exception e) {
Logger.e("startForeground compat error: " + e.getMessage());
e.printStackTrace();
}
mCurrentService.setForeground(false);
}
public void stopForeground()
{
try {
mSetForeground.invoke(mCurrentService, Boolean.FALSE);
} catch (Exception e) {
Logger.e("stopForeground compat error: " + e.getMessage());
}
mCurrentService.setForeground(false);
}
}
}

View file

@ -28,12 +28,17 @@ import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Toast;
public class RockboxActivity extends Activity
{
private RockboxService rbservice;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
@ -42,11 +47,11 @@ public class RockboxActivity extends Activity
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Intent intent = new Intent(this, RockboxService.class);
intent.setAction(Intent.ACTION_MAIN);
intent.putExtra("callback", new ResultReceiver(new Handler(getMainLooper())) {
private boolean unzip = false;
private ProgressDialog loadingdialog;
private void createProgressDialog()
{
loadingdialog = new ProgressDialog(RockboxActivity.this);
@ -60,40 +65,27 @@ public class RockboxActivity extends Activity
@Override
protected void onReceiveResult(final int resultCode, final Bundle resultData)
{
RockboxFramebuffer fb;
switch (resultCode) {
case RockboxService.RESULT_INVOKING_MAIN:
if (loadingdialog != null)
loadingdialog.dismiss();
fb = new RockboxFramebuffer(RockboxActivity.this);
setContentView(fb);
fb.requestFocus();
break;
case RockboxService.RESULT_LIB_LOAD_PROGRESS:
if (loadingdialog == null)
createProgressDialog();
loadingdialog.setIndeterminate(false);
loadingdialog.setMax(resultData.getInt("max", 100));
loadingdialog.setProgress(resultData.getInt("value", 0));
break;
case RockboxService.RESULT_LIB_LOADED:
unzip = resultData.getBoolean("unzip");
break;
case RockboxService.RESULT_SERVICE_RUNNING:
if (!unzip) /* defer to RESULT_INVOKING_MAIN */
{
fb = new RockboxFramebuffer(RockboxActivity.this);
setContentView(fb);
fb.requestFocus();
}
rbservice = RockboxService.get_instance();
setServiceActivity(true);
attachFramebuffer();
break;
case RockboxService.RESULT_ERROR_OCCURED:
Toast.makeText(RockboxActivity.this, resultData.getString("error"), Toast.LENGTH_LONG);
break;
case RockboxService.RESULT_ROCKBOX_EXIT:
finish();
break;
}
}
});
@ -102,16 +94,33 @@ public class RockboxActivity extends Activity
private void setServiceActivity(boolean set)
{
RockboxService s = RockboxService.getInstance();
if (s != null)
s.setActivity(set ? this : null);
if (rbservice != null)
rbservice.set_activity(set ? this : null);
}
private void attachFramebuffer()
{
View rbFramebuffer = null;
try {
rbFramebuffer = rbservice.get_fb();
setContentView(rbFramebuffer);
} catch (IllegalStateException e) {
/* we are already using the View,
* need to remove it and re-attach it */
ViewGroup g = (ViewGroup) rbFramebuffer.getParent();
g.removeView(rbFramebuffer);
setContentView(rbFramebuffer);
} catch (NullPointerException e) {
return;
}
rbFramebuffer.requestFocus();
}
public void onResume()
{
super.onResume();
setVisible(true);
setServiceActivity(true);
attachFramebuffer();
}
/* this is also called when the backlight goes off,
@ -139,4 +148,9 @@ public class RockboxActivity extends Activity
super.onDestroy();
setServiceActivity(false);
}
private void LOG(CharSequence text)
{
Log.d("Rockbox", (String) text);
}
}

View file

@ -28,6 +28,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
@ -39,6 +40,7 @@ public class RockboxFramebuffer extends SurfaceView
{
private final DisplayMetrics metrics;
private final ViewConfiguration view_config;
private ByteBuffer native_buf;
private Bitmap btm;
/* first stage init; needs to run from a thread that has a Looper
@ -46,6 +48,7 @@ public class RockboxFramebuffer extends SurfaceView
public RockboxFramebuffer(Context c)
{
super(c);
metrics = c.getResources().getDisplayMetrics();
view_config = ViewConfiguration.get(c);
getHolder().addCallback(this);
@ -57,14 +60,22 @@ public class RockboxFramebuffer extends SurfaceView
setEnabled(false);
}
private void update(ByteBuffer framebuffer)
/* second stage init; called from Rockbox with information about the
* display framebuffer */
@SuppressWarnings("unused")
private void java_lcd_init(int lcd_width, int lcd_height, ByteBuffer native_fb)
{
btm = Bitmap.createBitmap(lcd_width, lcd_height, Bitmap.Config.RGB_565);
native_buf = native_fb;
setEnabled(true);
}
@SuppressWarnings("unused")
private void java_lcd_update()
{
SurfaceHolder holder = getHolder();
Canvas c = holder.lockCanvas();
if (c == null)
return;
btm.copyPixelsFromBuffer(framebuffer);
Canvas c = holder.lockCanvas(null);
btm.copyPixelsFromBuffer(native_buf);
synchronized (holder)
{ /* draw */
c.drawBitmap(btm, 0.0f, 0.0f, null);
@ -72,16 +83,15 @@ public class RockboxFramebuffer extends SurfaceView
holder.unlockCanvasAndPost(c);
}
private void update(ByteBuffer framebuffer, Rect dirty)
@SuppressWarnings("unused")
private void java_lcd_update_rect(int x, int y, int width, int height)
{
SurfaceHolder holder = getHolder();
Rect dirty = new Rect(x, y, x+width, y+height);
Canvas c = holder.lockCanvas(dirty);
if (c == null)
return;
/* can't copy a partial buffer, but it doesn't make a noticeable difference anyway */
btm.copyPixelsFromBuffer(framebuffer);
/* can't copy a partial buffer,
* but it doesn't make a noticeable difference anyway */
btm.copyPixelsFromBuffer(native_buf);
synchronized (holder)
{ /* draw */
c.drawBitmap(btm, dirty, dirty, null);
@ -89,6 +99,12 @@ public class RockboxFramebuffer extends SurfaceView
holder.unlockCanvasAndPost(c);
}
@SuppressWarnings("unused")
private void LOG(CharSequence text)
{
Log.d("Rockbox", (String) text);
}
public boolean onTouchEvent(MotionEvent me)
{
int x = (int) me.getX();
@ -119,25 +135,24 @@ public class RockboxFramebuffer extends SurfaceView
return buttonHandler(keyCode, false);
}
@SuppressWarnings("unused")
private int getDpi()
{
return metrics.densityDpi;
}
@SuppressWarnings("unused")
private int getScrollThreshold()
{
return view_config.getScaledTouchSlop();
}
private native void touchHandler(boolean down, int x, int y);
public native static boolean buttonHandler(int keycode, boolean state);
private native static boolean buttonHandler(int keycode, boolean state);
public native void surfaceCreated(SurfaceHolder holder);
public native void surfaceDestroyed(SurfaceHolder holder);
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
btm = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
setEnabled(true);
}
}

View file

@ -35,7 +35,7 @@ public class RockboxKeyboardInput
{
public void kbd_input(final String text, final String ok, final String cancel)
{
final Activity c = RockboxService.getInstance().getActivity();
final Activity c = RockboxService.get_instance().get_activity();
c.runOnUiThread(new Runnable() {
public void run()
@ -72,8 +72,9 @@ public class RockboxKeyboardInput
private native void put_result(boolean accepted, String new_string);
@SuppressWarnings("unused")
public boolean is_usable()
{
return RockboxService.getInstance().getActivity() != null;
return RockboxService.get_instance().get_activity() != null;
}
}

View file

@ -22,297 +22,183 @@
package org.rockbox;
import java.util.Arrays;
import org.rockbox.Helper.Logger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
import android.util.Log;
public class RockboxPCM extends AudioTrack
{
private static final int streamtype = AudioManager.STREAM_MUSIC;
private byte[] raw_data;
private PCMListener l;
private HandlerThread ht;
private Handler h = null;
private static final int samplerate = 44100;
/* should be CHANNEL_OUT_STEREO in 2.0 and above */
private static final int channels =
AudioFormat.CHANNEL_OUT_STEREO;
AudioFormat.CHANNEL_CONFIGURATION_STEREO;
private static final int encoding =
AudioFormat.ENCODING_PCM_16BIT;
private AudioManager audiomanager;
private RockboxService rbservice;
private byte[] raw_data;
/* 24k is plenty, but some devices may have a higher minimum */
private static final int buf_len =
Math.max(24<<10, getMinBufferSize(samplerate, channels, encoding));
private int refillmark;
private int maxstreamvolume;
private int setstreamvolume = -1;
private float minpcmvolume;
private float curpcmvolume = 0;
private float pcmrange;
/* 8k is plenty, but some devices may have a higher minimum.
* 8k represents 125ms of audio */
private static final int chunkSize =
Math.max(8<<10, getMinBufferSize(samplerate, channels, encoding));
Streamer streamer;
private void LOG(CharSequence text)
{
Log.d("Rockbox", (String) text);
}
public RockboxPCM()
{
super(streamtype, samplerate, channels, encoding,
chunkSize, AudioTrack.MODE_STREAM);
streamer = new Streamer(chunkSize);
streamer.start();
raw_data = new byte[chunkSize]; /* in shorts */
super(AudioManager.STREAM_MUSIC, samplerate, channels, encoding,
buf_len, AudioTrack.MODE_STREAM);
ht = new HandlerThread("audio thread",
Process.THREAD_PRIORITY_URGENT_AUDIO);
ht.start();
raw_data = new byte[buf_len]; /* in shorts */
Arrays.fill(raw_data, (byte) 0);
/* find cleaner way to get context? */
rbservice = RockboxService.getInstance();
audiomanager =
(AudioManager) rbservice.getSystemService(Context.AUDIO_SERVICE);
maxstreamvolume = audiomanager.getStreamMaxVolume(streamtype);
minpcmvolume = getMinVolume();
pcmrange = getMaxVolume() - minpcmvolume;
setupVolumeHandler();
postVolume(audiomanager.getStreamVolume(streamtype));
}
/**
* This class does the actual playback work. Its run() method
* continuously writes data to the AudioTrack. This operation blocks
* and should therefore be run on its own thread.
*/
private class Streamer extends Thread
{
byte[] buffer;
private boolean quit = false;
Streamer(int bufsize)
{
super("audio thread");
buffer = new byte[bufsize];
}
@Override
public void run()
{
/* THREAD_PRIORITY_URGENT_AUDIO can only be specified via
* setThreadPriority(), and not via thread.setPriority(). This is
* also how the android's HandlerThread class implements it */
Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);
while (!quit)
{
switch(getPlayState())
{
case PLAYSTATE_PLAYING:
nativeWrite(buffer, buffer.length);
break;
case PLAYSTATE_PAUSED:
case PLAYSTATE_STOPPED:
{
synchronized (this)
{
try
{
wait();
}
catch (InterruptedException e) { e.printStackTrace(); }
break;
}
}
}
}
}
synchronized void quit()
{
quit = true;
notify();
}
synchronized void kick()
{
notify();
}
void quitAndJoin()
{
while(true)
{
try
{
quit();
join();
return;
}
catch (InterruptedException e) { }
}
}
}
private native void postVolumeChangedEvent(int volume);
private void postVolume(int volume)
{
int rbvolume = ((maxstreamvolume - volume) * -99) /
maxstreamvolume;
Logger.d("java:postVolumeChangedEvent, avol "+volume+" rbvol "+rbvolume);
postVolumeChangedEvent(rbvolume);
}
private void setupVolumeHandler()
{
BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
int streamType = intent.getIntExtra(
"android.media.EXTRA_VOLUME_STREAM_TYPE", -1);
int volume = intent.getIntExtra(
"android.media.EXTRA_VOLUME_STREAM_VALUE", -1);
if (streamType == RockboxPCM.streamtype &&
volume != -1 &&
volume != setstreamvolume &&
rbservice.isRockboxRunning())
{
postVolume(volume);
}
}
};
/* at startup, change the internal rockbox volume to what the global
android music stream volume is */
int volume = audiomanager.getStreamVolume(streamtype);
int rbvolume = ((maxstreamvolume - volume) * -99) / maxstreamvolume;
postVolumeChangedEvent(rbvolume);
/* We're relying on internal API's here,
this can break in the future! */
rbservice.registerReceiver(
broadcastReceiver,
new IntentFilter("android.media.VOLUME_CHANGED_ACTION"));
}
l = new PCMListener(buf_len);
}
private int bytes2frames(int bytes)
{
/* 1 sample is 2 bytes, 2 samples are 1 frame */
return (bytes/4);
}
private int frames2bytes(int frames)
{
/* 1 frame is 2 samples, 1 sample is 2 bytes */
return (frames*4);
}
private void play_pause(boolean pause)
{
RockboxService service = RockboxService.getInstance();
@SuppressWarnings("unused")
private void play_pause(boolean pause) {
if (pause)
{
Intent widgetUpdate = new Intent("org.rockbox.UpdateState");
widgetUpdate.putExtra("state", "pause");
service.sendBroadcast(widgetUpdate);
service.stopForeground();
RockboxService.get_instance().sendBroadcast(widgetUpdate);
pause();
}
else
{
Intent widgetUpdate = new Intent("org.rockbox.UpdateState");
widgetUpdate.putExtra("state", "play");
service.sendBroadcast(widgetUpdate);
service.startForeground();
RockboxService.get_instance().sendBroadcast(widgetUpdate);
if (getPlayState() == AudioTrack.PLAYSTATE_STOPPED)
{
/* need to fill with silence before starting playback */
write(raw_data, 0, raw_data.length);
RockboxService.get_instance().startForeground();
if (getState() == AudioTrack.STATE_INITIALIZED)
{
if (h == null)
h = new Handler(ht.getLooper());
if (setNotificationMarkerPosition(bytes2frames(buf_len)/4)
!= AudioTrack.SUCCESS)
LOG("setNotificationMarkerPosition Error");
else
setPlaybackPositionUpdateListener(l, h);
}
/* need to fill with silence before starting playback */
write(raw_data, frames2bytes(getPlaybackHeadPosition()),
raw_data.length);
}
play();
}
}
@Override
public void play() throws IllegalStateException
public void stop() throws IllegalStateException
{
super.play();
/* when stopped or paused the streamer is in a wait() state. need
* it to wake it up */
streamer.kick();
}
@Override
public synchronized void stop() throws IllegalStateException
{
/* flush pending data, but turn the volume off so it cannot be heard.
* This is so that we don't hear old data if music is resumed very
* quickly after (e.g. when seeking).
*/
float old_vol = curpcmvolume;
try {
setStereoVolume(0, 0);
flush();
super.stop();
} catch (IllegalStateException e) {
throw new IllegalStateException(e);
} finally {
setStereoVolume(old_vol, old_vol);
}
RockboxService.get_instance().stopForeground();
Intent widgetUpdate = new Intent("org.rockbox.UpdateState");
widgetUpdate.putExtra("state", "stop");
RockboxService.getInstance().sendBroadcast(widgetUpdate);
RockboxService.getInstance().stopForeground();
}
@Override
public void release()
{
super.release();
/* stop streamer if this AudioTrack is destroyed by whomever */
streamer.quitAndJoin();
}
public int setStereoVolume(float leftVolume, float rightVolume)
{
curpcmvolume = leftVolume;
return super.setStereoVolume(leftVolume, rightVolume);
RockboxService.get_instance().sendBroadcast(widgetUpdate);
}
@SuppressWarnings("unused")
private void set_volume(int volume)
{
Logger.d("java:set_volume("+volume+")");
/* Rockbox 'volume' is 0..-990 deci-dB attenuation.
Android streams have rather low resolution volume control,
typically 8 or 15 steps.
Therefore we use the pcm volume to add finer steps between
every android stream volume step.
It's not "real" dB, but it gives us 100 volume steps.
*/
float fraction = 1 - (volume / -990.0f);
int streamvolume = (int)Math.ceil(maxstreamvolume * fraction);
if (streamvolume > 0) {
float streamfraction = (float)streamvolume / maxstreamvolume;
float pcmvolume =
(fraction / streamfraction) * pcmrange + minpcmvolume;
setStereoVolume(pcmvolume, pcmvolume);
}
int oldstreamvolume = audiomanager.getStreamVolume(streamtype);
if (streamvolume != oldstreamvolume) {
Logger.d("java:setStreamVolume("+streamvolume+")");
setstreamvolume = streamvolume;
audiomanager.setStreamVolume(streamtype, streamvolume, 0);
}
/* volume comes from 0..-990 from Rockbox */
/* TODO:
* volume is in dB, but this code acts as if it were in %, convert? */
float fvolume;
/* special case min and max volume to not suffer from
* floating point accuracy */
if (volume == 0)
fvolume = 1.0f;
else if (volume == -990)
fvolume = 0.0f;
else
fvolume = (volume + 990)/990.0f;
setStereoVolume(fvolume, fvolume);
}
public native int nativeWrite(byte[] temp, int len);
public native void pcmSamplesToByteArray(byte[] dest);
private class PCMListener implements OnPlaybackPositionUpdateListener
{
private int max_len;
private int refill_mark;
private byte[] buf;
public PCMListener(int len)
{
max_len = len;
/* refill to 100% when reached the 25% */
buf = new byte[max_len*3/4];
refill_mark = max_len - buf.length;
}
public void onMarkerReached(AudioTrack track)
{
/* push new data to the hardware */
RockboxPCM pcm = (RockboxPCM)track;
int result = -1;
pcm.pcmSamplesToByteArray(buf);
result = track.write(buf, 0, buf.length);
if (result >= 0)
{
switch(track.getPlayState())
{
case AudioTrack.PLAYSTATE_PLAYING:
case AudioTrack.PLAYSTATE_PAUSED:
/* refill at 25% no matter of how many
* bytes we've written */
if (setNotificationMarkerPosition(
bytes2frames(refill_mark))
!= AudioTrack.SUCCESS)
{
LOG("Error in onMarkerReached: " +
"Could not set notification marker");
}
else /* recharge */
setPlaybackPositionUpdateListener(this, h);
break;
case AudioTrack.PLAYSTATE_STOPPED:
LOG("State STOPPED");
break;
}
}
else
{
LOG("Error in onMarkerReached (result="+result+")");
stop();
}
}
public void onPeriodicNotification(AudioTrack track)
{
}
}
}

View file

@ -25,204 +25,215 @@ import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.Enumeration;
import java.util.Timer;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.rockbox.Helper.Logger;
import org.rockbox.Helper.MediaButtonReceiver;
import org.rockbox.Helper.RunForegroundManager;
import android.app.Activity;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.os.ResultReceiver;
import android.util.Log;
import android.view.KeyEvent;
/* This class is used as the main glue between java and c.
* All access should be done through RockboxService.get_instance() for safety.
*/
public class RockboxService extends Service
public class RockboxService extends Service
{
/* this Service is really a singleton class - well almost. */
/* this Service is really a singleton class - well almost.
* To do it properly this line should be instance = new RockboxService()
* but apparently that doesnt work with the way android Services are created.
*/
private static RockboxService instance = null;
/* locals needed for the c code and Rockbox state */
private static volatile boolean rockbox_running;
private Activity mCurrentActivity = null;
private RunForegroundManager mFgRunner;
/* locals needed for the c code and rockbox state */
private RockboxFramebuffer fb = null;
private volatile boolean rockbox_running;
private Activity current_activity = null;
private IntentFilter itf;
private BroadcastReceiver batt_monitor;
private RunForegroundManager fg_runner;
private MediaButtonReceiver mMediaButtonReceiver;
private ResultReceiver mResultReceiver;
@SuppressWarnings("unused")
private int battery_level;
private ResultReceiver resultReceiver;
final private Object lock = new Object();
/* possible result values for intent handling */
public static final int RESULT_INVOKING_MAIN = 0;
public static final int RESULT_LIB_LOAD_PROGRESS = 1;
public static final int RESULT_FB_INITIALIZED = 2;
public static final int RESULT_SERVICE_RUNNING = 3;
public static final int RESULT_ERROR_OCCURED = 4;
public static final int RESULT_LIB_LOADED = 5;
public static final int RESULT_ROCKBOX_EXIT = 6;
@Override
public void onCreate()
{
instance = this;
mMediaButtonReceiver = new MediaButtonReceiver(this);
mFgRunner = new RunForegroundManager(this);
}
public static RockboxService getInstance()
{
/* don't call the constructor here, the instances are managed by
* android, so we can't just create a new one */
return instance;
}
public boolean isRockboxRunning()
{
return rockbox_running;
}
public Activity getActivity()
{
return mCurrentActivity;
}
public void setActivity(Activity a)
{
mCurrentActivity = a;
fg_runner = new RunForegroundManager(this);
}
private void putResult(int resultCode)
public static RockboxService get_instance()
{
putResult(resultCode, null);
return instance;
}
public RockboxFramebuffer get_fb()
{
return fb;
}
public Activity get_activity()
{
return current_activity;
}
public void set_activity(Activity a)
{
current_activity = a;
}
private void putResult(int resultCode, Bundle resultData)
private void do_start(Intent intent)
{
if (mResultReceiver != null)
mResultReceiver.send(resultCode, resultData);
}
LOG("Start Service");
private void doStart(Intent intent)
{
Logger.d("Start RockboxService (Intent: " + intent.getAction() + ")");
if (intent != null && intent.hasExtra("callback"))
resultReceiver = (ResultReceiver) intent.getParcelableExtra("callback");
if (intent.getAction().equals("org.rockbox.ResendTrackUpdateInfo"))
{
if (rockbox_running)
mFgRunner.resendUpdateNotification();
return;
/* Display a notification about us starting.
* We put an icon in the status bar. */
if (fg_runner == null)
{ /* needs to be initialized before main() runs */
try {
} catch (Exception e) {
e.printStackTrace();
}
}
if (intent.hasExtra("callback"))
mResultReceiver = (ResultReceiver) intent.getParcelableExtra("callback");
if (!rockbox_running)
startService();
if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON))
{
KeyEvent kev = intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
RockboxFramebuffer.buttonHandler(kev.getKeyCode(),
kev.getAction() == KeyEvent.ACTION_DOWN);
synchronized(lock)
{
startservice();
while(true) {
try {
lock.wait();
} catch (InterruptedException e) {
continue;
}
break;
}
fb = new RockboxFramebuffer(this);
if (resultReceiver != null)
resultReceiver.send(RESULT_FB_INITIALIZED, null);
}
}
if (resultReceiver != null)
resultReceiver.send(RESULT_LIB_LOADED, null);
if (intent != null && intent.getAction() != null)
{
Log.d("RockboxService", intent.getAction());
if (intent.getAction().equals("org.rockbox.PlayPause"))
{
if (fb != null)
fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, null);
}
else if (intent.getAction().equals("org.rockbox.Prev"))
{
if (fb != null)
fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_PREVIOUS, null);
}
else if (intent.getAction().equals("org.rockbox.Next"))
{
if (fb != null)
fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_NEXT, null);
}
else if (intent.getAction().equals("org.rockbox.Stop"))
{
if (fb != null)
fb.onKeyUp(KeyEvent.KEYCODE_MEDIA_STOP, null);
}
}
/* (Re-)attach the media button receiver, in case it has been lost */
mMediaButtonReceiver.register();
putResult(RESULT_SERVICE_RUNNING);
rockbox_running = true;
if (resultReceiver != null)
resultReceiver.send(RESULT_SERVICE_RUNNING, null);
}
private void LOG(CharSequence text)
{
Log.d("Rockbox", (String) text);
}
private void LOG(CharSequence text, Throwable tr)
{
Log.d("Rockbox", (String) text, tr);
}
public void onStart(Intent intent, int startId) {
doStart(intent);
do_start(intent);
}
public int onStartCommand(Intent intent, int flags, int startId)
{
/* if null, then the service was most likely restarted by android
* after getting killed for memory pressure earlier */
if (intent == null)
intent = new Intent("org.rockbox.ServiceRestarted");
doStart(intent);
return START_STICKY;
do_start(intent);
return 1; /* old API compatibility: 1 == START_STICKY */
}
private void startService()
private void startservice()
{
final Object lock = new Object();
final int BUFFER = 8*1024;
Thread rb = new Thread(new Runnable()
{
public void run()
{
final int BUFFER = 8*1024;
String rockboxDirPath = "/data/data/org.rockbox/app_rockbox/rockbox";
String rockboxCreditsPath = "/data/data/org.rockbox/app_rockbox/rockbox/rocks/viewers";
String rockboxSdDirPath = "/sdcard/rockbox";
File rockboxDir = new File(rockboxDirPath);
/* the following block unzips libmisc.so, which contains the files
* we ship, such as themes. It's needed to put it into a .so file
* because there's no other way to ship files and have access
* to them from native code
*/
/* the following block unzips libmisc.so, which contains the files
* we ship, such as themes. It's needed to put it into a .so file
* because there's no other way to ship files and have access
* to them from native code
*/
File libMisc = new File("/data/data/org.rockbox/lib/libmisc.so");
/* use arbitrary file to determine whether extracting is needed */
File arbitraryFile = new File(rockboxCreditsPath, "credits.rock");
File rockboxInfoFile = new File(rockboxSdDirPath, "rockbox-info.txt");
/* unzip newer or doesnt exist */
boolean doExtract = !arbitraryFile.exists()
|| (libMisc.lastModified() > arbitraryFile.lastModified());
/* load library before unzipping which may take a while
* but at least tell if unzipping is going to be done before*/
synchronized (lock) {
Bundle bdata = new Bundle();
bdata.putBoolean("unzip", doExtract);
System.loadLibrary("rockbox");
putResult(RESULT_LIB_LOADED, bdata);
lock.notify();
}
if (doExtract)
File arbitraryFile = new File(rockboxDir, "viewers.config");
if (!arbitraryFile.exists() || (libMisc.lastModified() > arbitraryFile.lastModified()))
{
boolean extractToSd = false;
if(rockboxInfoFile.exists()) {
extractToSd = true;
Logger.d("extracting resources to SD card");
}
else {
Logger.d("extracting resources to internal memory");
}
try
{
Bundle progressData = new Bundle();
byte data[] = new byte[BUFFER];
ZipFile zipfile = new ZipFile(libMisc);
Enumeration<? extends ZipEntry> e = zipfile.entries();
progressData.putInt("max", zipfile.size());
try
{
Bundle progressData = new Bundle();
byte data[] = new byte[BUFFER];
ZipFile zipfile = new ZipFile(libMisc);
Enumeration<? extends ZipEntry> e = zipfile.entries();
progressData.putInt("max", zipfile.size());
while(e.hasMoreElements())
{
ZipEntry entry = (ZipEntry) e.nextElement();
File file;
/* strip off /.rockbox when extracting */
String fileName = entry.getName();
int slashIndex = fileName.indexOf('/', 1);
/* codecs are now stored as libs, only keep rocks on internal */
if(extractToSd == false
|| fileName.substring(slashIndex).startsWith("/rocks"))
{
file = new File(rockboxDirPath + fileName.substring(slashIndex));
}
else
{
file = new File(rockboxSdDirPath + fileName.substring(slashIndex));
}
while(e.hasMoreElements())
{
ZipEntry entry = (ZipEntry) e.nextElement();
File file;
/* strip off /.rockbox when extracting */
String fileName = entry.getName();
int slashIndex = fileName.indexOf('/', 1);
file = new File(rockboxDirPath + fileName.substring(slashIndex));
if (!entry.isDirectory())
{
if (!entry.isDirectory())
{
/* Create the parent folders if necessary */
File folder = new File(file.getParent());
if (!folder.exists())
@ -240,104 +251,106 @@ public class RockboxService extends Service
dest.flush();
dest.close();
is.close();
}
if (resultReceiver != null) {
progressData.putInt("value", progressData.getInt("value", 0) + 1);
resultReceiver.send(RESULT_LIB_LOAD_PROGRESS, progressData);
}
progressData.putInt("value", progressData.getInt("value", 0) + 1);
putResult(RESULT_LIB_LOAD_PROGRESS, progressData);
}
arbitraryFile.setLastModified(libMisc.lastModified());
} catch(Exception e) {
Logger.d("Exception when unzipping", e);
Bundle bundle = new Bundle();
e.printStackTrace();
bundle.putString("error", getString(R.string.error_extraction));
putResult(RESULT_ERROR_OCCURED, bundle);
}
} catch(Exception e) {
LOG("Exception when unzipping", e);
e.printStackTrace();
if (resultReceiver != null) {
Bundle bundle = new Bundle();
bundle.putString("error", getString(R.string.error_extraction));
resultReceiver.send(RESULT_ERROR_OCCURED, bundle);
}
}
}
synchronized (lock) {
System.loadLibrary("rockbox");
lock.notify();
}
/* Generate default config if none exists yet */
File rockboxConfig = new File(Environment.getExternalStorageDirectory(), "rockbox/config.cfg");
if (!rockboxConfig.exists()) {
File rbDir = new File(rockboxConfig.getParent());
if (!rbDir.exists())
rbDir.mkdirs();
OutputStreamWriter strm;
try {
strm = new OutputStreamWriter(new FileOutputStream(rockboxConfig));
strm.write("# config generated by RockboxService\n");
strm.write("start directory: " + Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "\n");
strm.write("lang: /.rockbox/langs/" + getString(R.string.rockbox_language_file) + "\n");
strm.close();
} catch(Exception e) {
Logger.d("Exception when writing default config", e);
}
}
/* Start native code */
putResult(RESULT_INVOKING_MAIN);
rockbox_running = true;
if (resultReceiver != null)
resultReceiver.send(RESULT_INVOKING_MAIN, null);
main();
putResult(RESULT_ROCKBOX_EXIT);
Logger.d("Stop service: main() returned");
stopSelf(); /* service is of no use anymore */
throw new IllegalStateException("native main() returned!");
}
}, "Rockbox thread");
rb.setDaemon(false);
/* wait at least until the library is loaded */
synchronized (lock)
{
rb.start();
while(true)
{
try {
lock.wait();
} catch (InterruptedException e) {
continue;
}
break;
}
}
rb.start();
}
private native void main();
@Override
public IBinder onBind(Intent intent)
public IBinder onBind(Intent intent)
{
// TODO Auto-generated method stub
return null;
}
void startForeground()
@SuppressWarnings("unused")
/*
* Sets up the battery monitor which receives the battery level
* about each 30 seconds
*/
private void initBatteryMonitor()
{
mFgRunner.startForeground();
itf = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
batt_monitor = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
/* we get literally spammed with battery statuses
* if we don't delay the re-attaching
*/
TimerTask tk = new TimerTask()
{
public void run()
{
registerReceiver(batt_monitor, itf);
}
};
Timer t = new Timer();
context.unregisterReceiver(this);
int rawlevel = intent.getIntExtra("level", -1);
int scale = intent.getIntExtra("scale", -1);
if (rawlevel >= 0 && scale > 0)
battery_level = (rawlevel * 100) / scale;
else
battery_level = -1;
/* query every 30s should be sufficient */
t.schedule(tk, 30000);
}
};
registerReceiver(batt_monitor, itf);
}
void stopForeground()
public void startForeground()
{
mFgRunner.stopForeground();
fg_runner.startForeground();
}
public void stopForeground()
{
fg_runner.stopForeground();
}
@Override
public void onDestroy()
public void onDestroy()
{
super.onDestroy();
/* Don't unregister so we can receive them (and startup the service)
* after idle power-off. Hopefully it's OK if mMediaButtonReceiver is
* garbage collected.
* mMediaButtonReceiver.unregister(); */
mMediaButtonReceiver.unregister();
mMediaButtonReceiver = null;
/* Make sure our notification is gone. */
stopForeground();
instance = null;
rockbox_running = false;
System.runFinalization();
/* exit() seems unclean but is needed in order to get the .so file garbage
* collected, otherwise Android caches this Service and librockbox.so
* The library must be reloaded to zero the bss and reset data
* segment */
System.exit(0);
}
}

View file

@ -0,0 +1,97 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2010 Thomas Martitz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
package org.rockbox;
import android.content.Context;
import android.os.Handler;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class RockboxTelephony
{
public RockboxTelephony(Context c)
{
final Handler handler = new Handler(c.getMainLooper());
final TelephonyManager tm = (TelephonyManager)
c.getSystemService(Context.TELEPHONY_SERVICE);
handler.post(new Runnable()
{
@Override
public void run()
{ /* need to instantiate from a thread that has a Looper */
tm.listen(new RockboxCallStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
}
});
}
private class RockboxCallStateListener extends PhoneStateListener
{
private int last_state;
public RockboxCallStateListener()
{
super();
/* set artificial initial state,
* we will get an initial event shortly after this,
* so to handle it correctly we need an invalid state set */
last_state = TelephonyManager.CALL_STATE_IDLE - 10;
}
private void handleState(int state)
{
if (state == last_state)
return;
switch (state)
{
case TelephonyManager.CALL_STATE_IDLE:
postCallHungUp();
break;
case TelephonyManager.CALL_STATE_RINGING:
postCallIncoming();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
/* for incoming calls we handled at RINGING already,
* if the previous state was IDLE then
* this is an outgoing call
*/
if (last_state == TelephonyManager.CALL_STATE_IDLE)
{ /* currently handled the same as incoming calls */
postCallIncoming();
}
break;
default:
return;
}
last_state = state;
}
@Override
public void onCallStateChanged(int state, String number)
{
super.onCallStateChanged(state, number);
handleState(state);
}
}
private native void postCallIncoming();
private native void postCallHungUp();
}

View file

@ -27,52 +27,42 @@ import android.content.DialogInterface;
public class RockboxYesno
{
private class Listener implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener
{
/* default to "No" if onClick isn't called at all */
private boolean result = false;
/* called when the user presses the Yes or the No button */
@Override
public void onClick(DialogInterface dialog, int which)
{
result = (which == DialogInterface.BUTTON_POSITIVE);
}
/* onDismiss is (hopefully) also called when the dialog is closed
* for any reason other than clicking yes or no. This should
* avoid the native code waiting for the result indefinitely in
* case the dialog just disappears */
@Override
public void onDismiss(DialogInterface dialog)
{
put_result(result);
}
}
@SuppressWarnings("unused")
private void yesno_display(final String text, final String yes, final String no)
{
final Activity c = RockboxService.getInstance().getActivity();
final Activity c = RockboxService.get_instance().get_activity();
c.runOnUiThread(new Runnable() {
public void run()
{
Listener l = new Listener();
new AlertDialog.Builder(c)
.setTitle(R.string.YesNoTitle)
.setTitle(R.string.KbdInputTitle)
.setIcon(R.drawable.icon)
.setCancelable(false)
.setMessage(text)
.setPositiveButton(yes, l)
.setNegativeButton(no, l)
.show()
.setOnDismissListener(l);
.setPositiveButton(yes, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
put_result(true);
}
})
.setNegativeButton(no, new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int whichButton)
{
put_result(false);
}
})
.show();
}
});
}
@SuppressWarnings("unused")
private boolean is_usable()
{
return RockboxService.getInstance().getActivity() != null;
return RockboxService.get_instance().get_activity() != null;
}
private native void put_result(boolean result);

View file

@ -1,74 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 Thomas Martitz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
package org.rockbox.monitors;
import java.util.Timer;
import java.util.TimerTask;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
public class BatteryMonitor extends BroadcastReceiver
{
private final IntentFilter mBattFilter;
private final Context mContext;
@SuppressWarnings("unused")
private int mBattLevel; /* read by native code */
/*
* We get literally spammed with battery status updates
* Therefore we actually unregister after each onReceive() and
* setup a timer to re-register in 30s */
public BatteryMonitor(Context c)
{
mBattFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
mContext = c;
Timer t = new Timer();
TimerTask task = new TimerTask()
{
public void run()
{
attach();
}
};
t.schedule(task, 5000, 30000);
attach();
}
@Override
public void onReceive(Context arg0, Intent intent)
{
int rawlevel = intent.getIntExtra("level", -1);
int scale = intent.getIntExtra("scale", -1);
if (rawlevel >= 0 && scale > 0)
mBattLevel = (rawlevel * 100) / scale;
else
mBattLevel = -1;
mContext.unregisterReceiver(this);
}
void attach()
{
mContext.registerReceiver(this, mBattFilter);
}
}

View file

@ -1,59 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 Thomas Martitz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
package org.rockbox.monitors;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
public class HeadphoneMonitor extends BroadcastReceiver
{
public HeadphoneMonitor(Context c)
{
IntentFilter hpFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
/* caution: hidden API; might break */
IntentFilter noisyFilter = new IntentFilter("android.media.AUDIO_BECOMING_NOISY");
c.registerReceiver(this, hpFilter);
c.registerReceiver(new NoisyMonitor(), noisyFilter);
}
@Override
public void onReceive(Context arg0, Intent intent)
{
int state = intent.getIntExtra("state", -1);
postHpStateChanged(state);
}
/* audio becoming noise acts as headphones extracted */
private class NoisyMonitor extends BroadcastReceiver
{
@Override
public void onReceive(Context arg0, Intent arg1)
{
postHpStateChanged(0);
}
}
private synchronized native void postHpStateChanged(int state);
}

View file

@ -1,97 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2010 Thomas Martitz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
package org.rockbox.monitors;
import android.content.Context;
import android.os.Handler;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class TelephonyMonitor
{
public TelephonyMonitor(Context c)
{
final Handler handler = new Handler(c.getMainLooper());
final TelephonyManager tm = (TelephonyManager)
c.getSystemService(Context.TELEPHONY_SERVICE);
handler.post(new Runnable()
{
@Override
public void run()
{ /* need to instantiate from a thread that has a Looper */
tm.listen(new RockboxCallStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
}
});
}
private class RockboxCallStateListener extends PhoneStateListener
{
private int last_state;
public RockboxCallStateListener()
{
super();
/* set artificial initial state,
* we will get an initial event shortly after this,
* so to handle it correctly we need an invalid state set */
last_state = TelephonyManager.CALL_STATE_IDLE - 10;
}
private void handleState(int state)
{
if (state == last_state)
return;
switch (state)
{
case TelephonyManager.CALL_STATE_IDLE:
postCallHungUp();
break;
case TelephonyManager.CALL_STATE_RINGING:
postCallIncoming();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
/* for incoming calls we handled at RINGING already,
* if the previous state was IDLE then
* this is an outgoing call
*/
if (last_state == TelephonyManager.CALL_STATE_IDLE)
{ /* currently handled the same as incoming calls */
postCallIncoming();
}
break;
default:
return;
}
last_state = state;
}
@Override
public void onCallStateChanged(int state, String number)
{
super.onCallStateChanged(state, number);
handleState(state);
}
}
private native void postCallIncoming();
private native void postCallHungUp();
}

View file

@ -22,18 +22,18 @@
package org.rockbox.widgets;
import org.rockbox.R;
import org.rockbox.RockboxService;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
public class RockboxWidgetConfigure extends Activity
{
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
@ -51,7 +51,6 @@ public class RockboxWidgetConfigure extends Activity
setResult(RESULT_CANCELED);
setContentView(R.layout.appwidget_configure);
((CheckBox)findViewById(R.id.enable_aa)).setChecked(true);
((CheckBox)findViewById(R.id.enable_prev)).setChecked(false);
((CheckBox)findViewById(R.id.enable_stop)).setChecked(true);
((CheckBox)findViewById(R.id.enable_playpause)).setChecked(true);
@ -75,7 +74,6 @@ public class RockboxWidgetConfigure extends Activity
final Context context = RockboxWidgetConfigure.this;
WidgetPref state = new WidgetPref();
state.enableAA = ((CheckBox)findViewById(R.id.enable_aa)).isChecked();
state.enablePrev = ((CheckBox)findViewById(R.id.enable_prev)).isChecked();
state.enableStop = ((CheckBox)findViewById(R.id.enable_stop)).isChecked();
state.enablePlayPause = ((CheckBox)findViewById(R.id.enable_playpause)).isChecked();
@ -83,12 +81,7 @@ public class RockboxWidgetConfigure extends Activity
saveWidgetPref(context, mAppWidgetId, state);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RockboxWidgetProvider.getInstance().updateAppWidget(context, appWidgetManager, mAppWidgetId, null);
/* Ask for track information so that new widgets display properly
* if rockbox was already playing */
context.startService(new Intent("org.rockbox.ResendTrackUpdateInfo",
Uri.EMPTY, context, RockboxService.class));
RockboxWidgetProvider.updateAppWidget(context, appWidgetManager, mAppWidgetId, null);
Intent result = new Intent();
result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
@ -99,7 +92,6 @@ public class RockboxWidgetConfigure extends Activity
static public class WidgetPref
{
public boolean enableAA = true;
public boolean enablePrev = true;
public boolean enableStop = true;
public boolean enablePlayPause = true;
@ -109,7 +101,6 @@ public class RockboxWidgetConfigure extends Activity
static void saveWidgetPref(Context context, int appWidgetId, WidgetPref state)
{
SharedPreferences.Editor prefs = context.getSharedPreferences("org.rockbox.RockboxWidgetConfigure", 0).edit();
prefs.putBoolean("albumart"+appWidgetId, state.enableAA);
prefs.putBoolean("prev"+appWidgetId, state.enablePrev);
prefs.putBoolean("stop"+appWidgetId, state.enableStop);
prefs.putBoolean("playpause"+appWidgetId, state.enablePlayPause);
@ -121,7 +112,6 @@ public class RockboxWidgetConfigure extends Activity
{
SharedPreferences prefs = context.getSharedPreferences("org.rockbox.RockboxWidgetConfigure", 0);
WidgetPref state = new WidgetPref();
state.enableAA = prefs.getBoolean("albumart"+appWidgetId, true);
state.enablePrev = prefs.getBoolean("prev"+appWidgetId, true);
state.enableStop = prefs.getBoolean("stop"+appWidgetId, true);
state.enablePlayPause = prefs.getBoolean("playpause"+appWidgetId, true);

View file

@ -21,10 +21,10 @@
package org.rockbox.widgets;
import java.io.File;
import org.rockbox.R;
import org.rockbox.RockboxActivity;
import org.rockbox.RockboxService;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
@ -32,20 +32,17 @@ import android.appwidget.AppWidgetProviderInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.view.KeyEvent;
import android.util.Log;
import android.view.View;
import android.view.KeyEvent;
import android.widget.RemoteViews;
import java.util.ArrayList;
public class RockboxWidgetProvider extends AppWidgetProvider
{
static RockboxWidgetProvider mInstance;
public RockboxWidgetProvider()
{
super();
mInstance = this;
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
@ -57,12 +54,6 @@ public class RockboxWidgetProvider extends AppWidgetProvider
}
}
public static RockboxWidgetProvider getInstance()
{
/* no new instance here, instanced by android */
return mInstance;
}
@Override
public void onDeleted(Context context, int[] appWidgetIds)
@ -83,9 +74,9 @@ public class RockboxWidgetProvider extends AppWidgetProvider
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (action.equals("org.rockbox.TrackUpdateInfo") ||
action.equals("org.rockbox.TrackFinish") ||
action.equals("org.rockbox.UpdateState"))
if (intent.getAction().equals("org.rockbox.TrackUpdateInfo") ||
intent.getAction().equals("org.rockbox.TrackFinish") ||
intent.getAction().equals("org.rockbox.UpdateState"))
{
AppWidgetManager gm = AppWidgetManager.getInstance(context);
int[] appWidgetIds = gm.getAppWidgetIds(new ComponentName(context, this.getClass()));
@ -101,7 +92,7 @@ public class RockboxWidgetProvider extends AppWidgetProvider
}
}
public void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Intent args)
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Intent args)
{
AppWidgetProviderInfo provider = appWidgetManager.getAppWidgetInfo(appWidgetId);
RemoteViews views = null;
@ -110,53 +101,45 @@ public class RockboxWidgetProvider extends AppWidgetProvider
Intent intent = new Intent(context, RockboxActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.infoDisplay, pendingIntent);
views.setOnClickPendingIntent(R.id.logo, pendingIntent);
RockboxWidgetConfigure.WidgetPref state = RockboxWidgetConfigure.loadWidgetPref(context, appWidgetId);
/* enable/disable PREV */
if (state.enablePrev)
{
views.setOnClickPendingIntent(R.id.prev,
newPendingIntent(context,
KeyEvent.KEYCODE_MEDIA_PREVIOUS));
intent = new Intent("org.rockbox.Prev", Uri.EMPTY, context, RockboxService.class);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.prev, pendingIntent);
}
else
views.setViewVisibility(R.id.prev, View.GONE);
/* enable/disable PLAY/PAUSE */
if (state.enablePlayPause)
{
views.setOnClickPendingIntent(R.id.playPause,
newPendingIntent(context,
KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE));
intent = new Intent("org.rockbox.PlayPause", Uri.EMPTY, context, RockboxService.class);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.playPause, pendingIntent);
}
else
views.setViewVisibility(R.id.playPause, View.GONE);
/* enable/disable NEXT */
if (state.enableNext)
{
views.setOnClickPendingIntent(R.id.next,
newPendingIntent(context,
KeyEvent.KEYCODE_MEDIA_NEXT));
intent = new Intent("org.rockbox.Next", Uri.EMPTY, context, RockboxService.class);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.next, pendingIntent);
}
else
views.setViewVisibility(R.id.next, View.GONE);
/* enable/disable STOP */
if (state.enableStop)
{
views.setOnClickPendingIntent(R.id.stop,
newPendingIntent(context,
KeyEvent.KEYCODE_MEDIA_STOP));
intent = new Intent("org.rockbox.Stop", Uri.EMPTY, context, RockboxService.class);
pendingIntent = PendingIntent.getService(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.stop, pendingIntent);
}
else
views.setViewVisibility(R.id.stop, View.GONE);
if (!state.enableAA)
views.setViewVisibility(R.id.logo, View.GONE);
if (args != null)
{
if (args.getAction().equals("org.rockbox.TrackUpdateInfo"))
@ -165,21 +148,12 @@ public class RockboxWidgetProvider extends AppWidgetProvider
CharSequence artist = args.getCharSequenceExtra("artist");
CharSequence album = args.getCharSequenceExtra("album");
views.setTextViewText(R.id.infoDisplay, title+"\n"+artist+"\n"+album);
CharSequence albumart = args.getCharSequenceExtra("albumart");
/* Uri.fromFile() is buggy in <2.2
* http://stackoverflow.com/questions/3004713/get-content-uri-from-file-path-in-android */
if (albumart != null)
views.setImageViewUri(R.id.logo, Uri.parse(
new File(albumart.toString()).toString()));
else
views.setImageViewResource(R.id.logo, R.drawable.rockbox);
}
else if (args.getAction().equals("org.rockbox.TrackFinish"))
{
// FIXME: looks like this event is always fired earlier than
// the actual track change (a few seconds)
views.setTextViewText(R.id.infoDisplay, context.getString(R.string.appwidget_infoDisplay));
views.setImageViewResource(R.id.logo, R.drawable.rockbox);
}
else if (args.getAction().equals("org.rockbox.UpdateState"))
{
@ -192,20 +166,6 @@ public class RockboxWidgetProvider extends AppWidgetProvider
}
appWidgetManager.updateAppWidget(appWidgetId, views);
}
public static PendingIntent newPendingIntent(Context context, int keycode)
{
/* Use keycode as request to code to prevent successive
* PendingIntents from overwritting one another.
* This seems hackish but at least it works.
* see: http://code.google.com/p/android/issues/detail?id=863
*/
Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON, Uri.EMPTY,
context, RockboxService.class);
intent.putExtra(Intent.EXTRA_KEY_EVENT,
new KeyEvent(KeyEvent.ACTION_UP, keycode));
return PendingIntent.getService(context, keycode, intent, 0);
}
}
}

View file

@ -1,27 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
package org.rockbox.widgets;
public class RockboxWidgetProvider3x3 extends RockboxWidgetProvider
{
}

View file

@ -7,7 +7,6 @@ alarm_menu.c
#endif
abrepeat.c
bookmark.c
core_keymap.c
debug_menu.c
filetypes.c
language.c
@ -20,13 +19,17 @@ menus/plugin_menu.c
#if CONFIG_TUNER
menus/radio_menu.c
#endif
#if CONFIG_CODEC == SWCODEC
#ifdef HAVE_WM8978
menus/audiohw_eq_menu.c
#endif
menus/eq_menu.c
buffering.c
voice_thread.c
rbcodec_helpers.c
replaygain.c
#else /* !SWCODEC */
mpeg.c
#endif
menus/main_menu.c
menus/playback_menu.c
menus/playlist_menu.c
@ -39,7 +42,7 @@ menus/sound_menu.c
menus/time_menu.c
#endif
misc.c
open_plugin.c
mp3data.c
onplay.c
playlist.c
playlist_catalog.c
@ -49,7 +52,6 @@ root_menu.c
screens.c
settings.c
settings_list.c
shortcuts.c
status.c
cuesheet.c
talk.c
@ -58,45 +60,42 @@ tree.c
tagtree.c
#endif
filetree.c
scrobbler.c
#ifdef IPOD_ACCESSORY_PROTOCOL
iap/iap-core.c
iap/iap-lingo0.c
#ifdef HAVE_LINE_REC
iap/iap-lingo1.c
#endif
iap/iap-lingo2.c
iap/iap-lingo3.c
iap/iap-lingo4.c
#if CONFIG_TUNER
iap/iap-lingo7.c
#endif
iap.c
#endif
screen_access.c
#ifdef HAVE_BUTTONBAR
gui/buttonbar.c
#endif
#ifdef HAVE_LCD_BITMAP
gui/icon.c
#endif
gui/list.c
gui/line.c
#ifdef HAVE_LCD_BITMAP
gui/bitmap/list.c
gui/bitmap/list-skinned.c
#else
gui/charcell/list.c
#endif
gui/option_select.c
#ifdef HAVE_PITCHCONTROL
#ifdef HAVE_PITCHSCREEN
gui/pitchscreen.c
#endif
#ifdef HAVE_QUICKSCREEN
gui/quickscreen.c
#endif
gui/folder_select.c
#if defined(HAVE_BACKLIGHT) || !defined(HAS_BUTTON_HOLD)
gui/mask_select.c
#endif
gui/wps.c
gui/scrollbar.c
gui/splash.c
gui/statusbar.c
#ifdef HAVE_LCD_BITMAP
gui/statusbar-skinned.c
#endif
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
hosted/android/yesno.c
hosted/android/notification.c
hosted/yesno.c
hosted/notification.c
#else
gui/yesno.c
#endif
@ -105,6 +104,9 @@ gui/viewport.c
gui/skin_engine/skin_backdrops.c
gui/skin_engine/skin_display.c
gui/skin_engine/skin_engine.c
#ifdef HAVE_LCD_BITMAP
gui/skin_engine/skin_fonts.c
#endif
gui/skin_engine/skin_parser.c
gui/skin_engine/skin_render.c
gui/skin_engine/skin_tokens.c
@ -116,10 +118,15 @@ gui/skin_engine/skin_touchsupport.c
gui/backdrop.c
#endif
#ifdef HAVE_LCD_CHARCELLS
player/icons.c
player/keyboard.c
#endif
#ifdef HAVE_LCD_BITMAP
recorder/bmp.c
recorder/icons.c
#if (CONFIG_PLATFORM&PLATFORM_ANDROID)
hosted/android/keyboard.c
hosted/keyboard.c
#else
recorder/keyboard.c
#endif
@ -139,7 +146,7 @@ recorder/albumart.c
#ifdef HAVE_LCD_COLOR
gui/color_picker.c
#endif
#endif
#ifdef HAVE_RECORDING
recorder/recording.c
#endif
@ -153,27 +160,71 @@ radio/radioart.c
#endif
#endif
#if CONFIG_CODEC == SWCODEC
#if INPUT_SRC_CAPS != 0
audio_path.c
#endif /* INPUT_SRC_CAPS != 0 */
audio_thread.c
fixedpoint.c
pcmbuf.c
codec_thread.c
playback.c
codecs.c
#ifndef HAVE_HARDWARE_BEEP
beep.c
dsp.c
#ifdef HAVE_PITCHSCREEN
tdspeed.c
#endif
#ifdef HAVE_RECORDING
enc_config.c
recorder/pcm_record.c
#endif
eq.c
#if defined(CPU_COLDFIRE)
dsp_cf.S
eq_cf.S
#elif defined(CPU_ARM)
dsp_arm.S
#if ARM_ARCH >= 6
dsp_arm_v6.S
#endif
eq_arm.S
#endif
#endif
#ifdef USB_ENABLE_HID
usb_keymaps.c
#endif
#ifndef USB_NONE
gui/usb_screen.c
#endif
metadata.c
metadata/id3tags.c
metadata/mp3.c
#if CONFIG_CODEC == SWCODEC
metadata/metadata_common.c
metadata/aiff.c
metadata/ape.c
metadata/asf.c
metadata/adx.c
metadata/flac.c
metadata/monkeys.c
metadata/mp4.c
metadata/mpc.c
metadata/ogg.c
metadata/sid.c
metadata/mod.c
metadata/spc.c
metadata/vorbis.c
metadata/wave.c
metadata/wavpack.c
metadata/a52.c
metadata/asap.c
metadata/rm.c
metadata/nsf.c
metadata/oma.c
metadata/smaf.c
metadata/au.c
metadata/vox.c
metadata/tta.c
#endif
#ifdef HAVE_TAGCACHE
tagcache.c
#endif
@ -187,6 +238,12 @@ keymaps/keymap-h1x0_h3x0.c
|| (CONFIG_KEYPAD == IPOD_3G_PAD) \
|| (CONFIG_KEYPAD == IPOD_1G2G_PAD))
keymaps/keymap-ipod.c
#elif CONFIG_KEYPAD == RECORDER_PAD
keymaps/keymap-recorder.c
#elif CONFIG_KEYPAD == ONDIO_PAD
keymaps/keymap-ondio.c
#elif CONFIG_KEYPAD == PLAYER_PAD
keymaps/keymap-player.c
#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
keymaps/keymap-x5.c
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
@ -197,6 +254,8 @@ keymaps/keymap-gigabeat.c
keymaps/keymap-gigabeat-s.c
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
keymaps/keymap-h10.c
#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
keymaps/keymap-ifp7xx.c
#elif CONFIG_KEYPAD == SANSA_E200_PAD
keymaps/keymap-e200.c
#elif CONFIG_KEYPAD == SANSA_C200_PAD
@ -205,6 +264,8 @@ keymaps/keymap-c200.c
keymaps/keymap-m200.c
#elif CONFIG_KEYPAD == SANSA_CLIP_PAD
keymaps/keymap-clip.c
#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
keymaps/keymap-av300.c
#elif CONFIG_KEYPAD == MROBE500_PAD
keymaps/keymap-mr500.c
#elif CONFIG_KEYPAD == MROBE100_PAD
@ -219,16 +280,18 @@ keymaps/keymap-meizu-m6sp.c
keymaps/keymap-creativezvm.c
#elif CONFIG_KEYPAD == CREATIVEZV_PAD
keymaps/keymap-creativezv.c
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
keymaps/keymap-zenxfi2.c
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD
keymaps/keymap-zenxfi3.c
#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
keymaps/keymap-sa9200.c
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
keymaps/keymap-hdd1630.c
#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
keymaps/keymap-hdd6330.c
#elif CONFIG_KEYPAD == IAUDIO67_PAD
keymaps/keymap-iaudio67.c
#elif CONFIG_KEYPAD == SANSA_C100_PAD
keymaps/keymap-c100.c
#elif CONFIG_KEYPAD == LOGIK_DAX_PAD
keymaps/keymap-logikdax.c
#elif CONFIG_KEYPAD == SANSA_FUZE_PAD
keymaps/keymap-fuze.c
#elif CONFIG_KEYPAD == ONDAVX747_PAD
@ -237,8 +300,7 @@ keymaps/keymap-ondavx747.c
keymaps/keymap-ondavx777.c
#elif CONFIG_KEYPAD == ONDAVX767_PAD
keymaps/keymap-ondavx767.c
#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) \
|| (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)
#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
keymaps/keymap-yh8xx_yh9xx.c
#elif CONFIG_KEYPAD == MINI2440_PAD
keymaps/keymap-mini2440.c
@ -252,50 +314,4 @@ keymaps/keymap-mpio-hd300.c
keymaps/keymap-android.c
#elif CONFIG_KEYPAD == SDL_PAD
keymaps/keymap-sdl.c
#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
keymaps/keymap-fuzeplus.c
#elif CONFIG_KEYPAD == RK27XX_GENERIC_PAD
keymaps/keymap-rk27xx-generic.c
#elif CONFIG_KEYPAD == HM60X_PAD
keymaps/keymap-hm60x.c
#elif CONFIG_KEYPAD == HM801_PAD
keymaps/keymap-hm801.c
#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
keymaps/keymap-sansa-connect.c
#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD
keymaps/keymap-ypr0.c
#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD
keymaps/keymap-zen.c
#elif CONFIG_KEYPAD == MA_PAD
keymaps/keymap-ma.c
#elif CONFIG_KEYPAD == SONY_NWZ_PAD
keymaps/keymap-nwz.c
#elif CONFIG_KEYPAD == SONY_NWZA860_PAD
keymaps/keymap-nwza860.c
#elif CONFIG_KEYPAD == IHIFI_PAD
keymaps/keymap-ihifi.c
#elif CONFIG_KEYPAD == IHIFI_770_PAD
keymaps/keymap-ihifi770.c
#elif CONFIG_KEYPAD == IHIFI_800_PAD
keymaps/keymap-ihifi800.c
#elif CONFIG_KEYPAD == SAMSUNG_YPR1_PAD
keymaps/keymap-ypr1.c
#elif CONFIG_KEYPAD == DX50_PAD
keymaps/keymap-dx50.c
#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
keymaps/keymap-agptekrocker.c
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
keymaps/keymap-xduoox3.c
#elif CONFIG_KEYPAD == XDUOO_X3II_PAD
keymaps/keymap-xduoox3ii.c
#elif CONFIG_KEYPAD == XDUOO_X20_PAD
keymaps/keymap-xduoox20.c
#elif CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD
keymaps/keymap-fiiom3klinux.c
#elif CONFIG_KEYPAD == FIIO_M3K_PAD
keymaps/keymap-fiiom3k.c
#elif CONFIG_KEYPAD == EROSQ_PAD
keymaps/keymap-erosq.c
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
keymaps/keymap-shanlingq1.c
#endif

View file

@ -27,7 +27,6 @@
unsigned int ab_A_marker IDATA_ATTR = AB_MARKER_NONE;
unsigned int ab_B_marker IDATA_ATTR = AB_MARKER_NONE;
static inline bool ab_A_marker_set(void)
{
return ab_A_marker != AB_MARKER_NONE;
@ -38,7 +37,7 @@ static inline bool ab_B_marker_set(void)
return ab_B_marker != AB_MARKER_NONE;
}
#if (CONFIG_CODEC == SWCODEC)
void ab_end_of_track_report(void)
{
if ( ab_A_marker_set() && ! ab_B_marker_set() )
@ -46,6 +45,38 @@ void ab_end_of_track_report(void)
ab_jump_to_A_marker();
}
}
#else
static int ab_audio_event_handler(unsigned short event, unsigned long data)
{
int rc = AUDIO_EVENT_RC_IGNORED;
if ( ab_repeat_mode_enabled() )
{
switch(event)
{
case AUDIO_EVENT_POS_REPORT:
{
if ( ! (audio_status() & AUDIO_STATUS_PAUSE) &&
ab_reached_B_marker(data) )
{
ab_jump_to_A_marker();
rc = AUDIO_EVENT_RC_HANDLED;
}
break;
}
case AUDIO_EVENT_END_OF_TRACK:
{
if ( ab_A_marker_set() && ! ab_B_marker_set() )
{
ab_jump_to_A_marker();
rc = AUDIO_EVENT_RC_HANDLED;
}
break;
}
}
}
return rc;
}
#endif
void ab_repeat_init(void)
{
@ -53,6 +84,10 @@ void ab_repeat_init(void)
if ( ! ab_initialized )
{
ab_initialized = true;
#if (CONFIG_CODEC != SWCODEC)
audio_register_event_handler(ab_audio_event_handler,
AUDIO_EVENT_POS_REPORT | AUDIO_EVENT_END_OF_TRACK );
#endif
}
}
@ -79,7 +114,16 @@ reasonable amount of time for the typical user to react */
void ab_jump_to_A_marker(void)
{
#if (CONFIG_CODEC != SWCODEC)
bool paused = (audio_status() & AUDIO_STATUS_PAUSE) != 0;
if ( ! paused )
audio_pause();
#endif
audio_ff_rewind(ab_A_marker);
#if (CONFIG_CODEC != SWCODEC)
if ( ! paused )
audio_resume();
#endif
}
void ab_reset_markers(void)
@ -114,16 +158,67 @@ void ab_set_B_marker(unsigned int song_position)
ab_A_marker = AB_MARKER_NONE;
}
bool ab_get_A_marker(unsigned *song_position)
#ifdef HAVE_LCD_BITMAP
static int ab_calc_mark_x_pos(int mark, int capacity,
int offset, int size)
{
*song_position = ab_A_marker;
return ab_A_marker_set();
return offset + ( (size * mark) / capacity );
}
bool ab_get_B_marker(unsigned *song_position)
static void ab_draw_vertical_line_mark(struct screen * screen,
int x, int y, int h)
{
*song_position = ab_B_marker;
return ab_B_marker_set();
screen->set_drawmode(DRMODE_COMPLEMENT);
screen->vline(x, y, y+h-1);
}
#define DIRECTION_RIGHT 1
#define DIRECTION_LEFT -1
static void ab_draw_arrow_mark(struct screen * screen,
int x, int y, int h, int direction)
{
/* draw lines in decreasing size until a height of zero is reached */
screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
while( h > 0 )
{
screen->vline(x, y, y+h-1);
h -= 2;
y++;
x += direction;
screen->set_drawmode(DRMODE_COMPLEMENT);
}
}
void ab_draw_markers(struct screen * screen, int capacity,
int x, int y, int w, int h)
{
int xa = ab_calc_mark_x_pos(ab_A_marker, capacity, x, w);
int xb = ab_calc_mark_x_pos(ab_B_marker, capacity, x, w);
/* if both markers are set, determine if they're far enough apart
to draw arrows */
if ( ab_A_marker_set() && ab_B_marker_set() )
{
int arrow_width = (h+1) / 2;
if ( (xb-xa) < (arrow_width*2) )
{
ab_draw_vertical_line_mark(screen, xa, y, h);
ab_draw_vertical_line_mark(screen, xb, y, h);
return;
}
}
if (ab_A_marker_set())
{
ab_draw_arrow_mark(screen, xa, y, h, DIRECTION_RIGHT);
}
if (ab_B_marker_set())
{
ab_draw_arrow_mark(screen, xb, y, h, DIRECTION_LEFT);
}
}
#endif /* HAVE_LCD_BITMAP */
#endif /* AB_REPEAT_ENABLE */

View file

@ -20,38 +20,9 @@
****************************************************************************/
#ifndef _ABREPEAT_H_
#define _ABREPEAT_H_
#ifdef AB_REPEAT_ENABLE
#include <stdbool.h>
#ifndef AB_REPEAT_ENABLE /* Dummy functions */
static inline bool ab_repeat_mode_enabled(void)
{
return false;
}
static inline bool ab_bool_dummy_marker(unsigned int song_position)
{
(void) song_position;
return false;
}
static inline void ab_void_dummy_marker(unsigned int song_position)
{
(void) song_position;
}
static inline void ab_dummy_voidfn(void){}
#define ab_repeat_init ab_dummy_voidfn
#define ab_before_A_marker ab_bool_dummy_marker
#define ab_after_A_marker ab_bool_dummy_marker
#define ab_jump_to_A_marker ab_dummy_voidfn
#define ab_reset_markers ab_dummy_voidfn
#define ab_set_A_marker ab_void_dummy_marker
#define ab_set_B_marker ab_void_dummy_marker
#define ab_get_A_marker ab_bool_dummy_marker
#define ab_get_B_marker ab_bool_dummy_marker
#define ab_end_of_track_report ab_dummy_voidfn
#define ab_reached_B_marker ab_bool_dummy_marker
#define ab_position_report ab_void_dummy_marker
#else /*def AB_REPEAT_ENABLE*/
#include "audio.h"
#include "kernel.h" /* needed for HZ */
@ -66,11 +37,14 @@ void ab_jump_to_A_marker(void);
void ab_reset_markers(void);
void ab_set_A_marker(unsigned int song_position);
void ab_set_B_marker(unsigned int song_position);
/* These return whether the marker are actually set.
* The actual positions are returned via output parameter */
bool ab_get_A_marker(unsigned int *song_position);
bool ab_get_B_marker(unsigned int *song_position);
#if (CONFIG_CODEC == SWCODEC)
void ab_end_of_track_report(void);
#endif
#ifdef HAVE_LCD_BITMAP
#include "screen_access.h"
void ab_draw_markers(struct screen * screen, int capacity,
int x, int y, int w, int h);
#endif
/* These functions really need to be inlined for speed */
extern unsigned int ab_A_marker;
@ -86,9 +60,16 @@ static inline bool ab_reached_B_marker(unsigned int song_position)
/* following is the size of the window in which we'll detect that the B marker
was hit; it must be larger than the frequency (in milliseconds) at which this
function is called otherwise detection of the B marker will be unreliable */
#if (CONFIG_CODEC == SWCODEC)
/* On swcodec, the worst case seems to be 9600kHz with 1024 samples between
* calls, meaning ~9 calls per second, look within 1/5 of a second */
#define B_MARKER_DETECT_WINDOW 200
#else
/* we assume that this function will be called on each system tick and derive
the window size from this with a generous margin of error (note: the number
of ticks per second is given by HZ) */
#define B_MARKER_DETECT_WINDOW ((1000/HZ)*10)
#endif
if (ab_B_marker != AB_MARKER_NONE)
{
if ( (song_position >= ab_B_marker)
@ -98,6 +79,7 @@ function is called otherwise detection of the B marker will be unreliable */
return false;
}
#if (CONFIG_CODEC == SWCODEC)
static inline void ab_position_report(unsigned long position)
{
if (ab_repeat_mode_enabled())
@ -109,6 +91,7 @@ static inline void ab_position_report(unsigned long position)
}
}
}
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -28,99 +28,50 @@
#define TIMEOUT_NOBLOCK 0
#define CONTEXT_STOPSEARCHING 0xFFFFFFFF
#define CONTEXT_REMOTE 0x80000000 /* | this against another context to get remote buttons for that context */
#define CONTEXT_CUSTOM 0x40000000 /* | this against anything to get your context number */
#define CONTEXT_CUSTOM2 0x20000000 /* as above */
#define CONTEXT_PLUGIN 0x10000000 /* for plugins using get_custom_action */
#define CONTEXT_REMAPPED 0x08000000 /* marker for key remap context table */
#define CORE_CONTEXT_REMAP(context) (CONTEXT_REMAPPED | context)
#define CONTEXT_LOCKED 0x04000000 /* flag to use alternate keymap when screen is locked */
#define LAST_ITEM_IN_LIST { CONTEXT_STOPSEARCHING, BUTTON_NONE, BUTTON_NONE }
#define LAST_ITEM_IN_LIST__NEXTLIST(a) { a, BUTTON_NONE, BUTTON_NONE }
#if !defined(HAS_BUTTON_HOLD)
#ifndef HAS_BUTTON_HOLD
#define ALLOW_SOFTLOCK 0x08000000 /* will be stripped.. never needed except in calls to get_action() */
#else
#define ALLOW_SOFTLOCK 0
#endif
#if defined(HAVE_BACKLIGHT) || !defined(HAS_BUTTON_HOLD)
/* Selective action selection flags */
#define SEL_ACTION_NONE 0
#define SEL_ACTION_VOL 0x001U
#define SEL_ACTION_PLAY 0x002U
#define SEL_ACTION_SEEK 0x004U
#define SEL_ACTION_SKIP 0x008U
#define SEL_ACTION_NOUNMAPPED 0x010U/* disable backlight on unmapped buttons */
#define SEL_ACTION_ALLNONOTIFY 0x020U/* disable switch for all softlock notifications */
#define SEL_ACTION_ALWAYSAUTOLOCK 0x040U/* always prime autolock, requires autolock enabled */
#define SEL_ACTION_NOTOUCH 0x080U/* disable touch screen/pad on screen lock */
#define SEL_ACTION_AUTOLOCK 0x100U/* autolock on backlight off */
#define SEL_ACTION_NOEXT 0x200U/* disable selective backlight while charge*/
#define SEL_ACTION_NONOTIFY 0x200U/* don't notify user softlock is active */
/* Flags below are internal to selective functions */
#define SEL_ACTION_ALOCK_OK 0x400U/*autolock only active after key lock once*/
#define SEL_ACTION_FFKEYPRESS 0x400U/* backlight Filter First Keypress active*/
#define SEL_ACTION_ENABLED 0x800U
/* Selective Actions flags */
#if !defined(HAS_BUTTON_HOLD)
/* returns true if keys_locked and screen_has_lock */
bool is_keys_locked(void);
/* Enable selected actions to bypass a locked state
* mask is combination of Selective action selection flags */
void set_selective_softlock_actions(bool selective, unsigned int mask);
/* search the standard and wps contexts for ACTION_STD_KEYLOCK,
* load it into unlock_combo if we find it,
* also arm autolock if enabled. */
void action_autosoftlock_init(void);
#endif /* !defined(HAS_BUTTON_HOLD) */
#if defined(HAVE_BACKLIGHT)
/* Enable selected actions to leave the backlight off
* mask is combination of Selective action selection flags */
void set_selective_backlight_actions(bool selective, unsigned int mask,
bool filter_fkp);
#endif
#endif /* defined(HAVE_BACKLIGHT) || !defined(HAS_BUTTON_HOLD) */
enum {
CONTEXT_STD = 0,
/* These CONTEXT_ values were here before me,
their values may have significance, so dont touch! */
there values may have significance, so dont touch! */
CONTEXT_WPS = 1,
CONTEXT_TREE = 2,
CONTEXT_TREE = 2,
CONTEXT_RECORD = 3,
CONTEXT_MAINMENU = 4, /* uses CONTEXT_TREE and ACTION_TREE_* */
CONTEXT_ID3DB = 5,
/* Add new contexts here, no need to explicitly define a value for them */
/* Add new contexts here, no need to explicitly define a value for them */
CONTEXT_LIST,
CONTEXT_SETTINGS, /* regular setting screens (and debug screens) */
/* bellow are setting screens which may need to redefine the standard
/* bellow are setting screens which may need to redefine the standard
setting screen keys, targets should return the CONTEXT_SETTINGS
keymap unless they are not adequate for the screen
NOTE: uses ACTION_STD_[NEXT|PREV] so make sure they are there also
NOTE: uses ACTION_STD_[NEXT|PREV] so make sure they are there also
and (possibly) ACTION_SETTINGS_[INC|DEC] */
CONTEXT_SETTINGS_EQ,
CONTEXT_SETTINGS_COLOURCHOOSER,
CONTEXT_SETTINGS_TIME,
CONTEXT_SETTINGS_EQ,
CONTEXT_SETTINGS_COLOURCHOOSER,
CONTEXT_SETTINGS_TIME,
CONTEXT_SETTINGS_RECTRIGGER,
/* The following contexts should use ACTION_STD_[NEXT|PREV]
and (possibly) ACTION_SETTINGS_[INC|DEC]
and (possibly) ACTION_SETTINGS_[INC|DEC]
Also add any extra actions they need */
CONTEXT_BOOKMARKSCREEN, /* uses ACTION_BMS_ defines */
CONTEXT_ALARMSCREEN, /* uses ACTION_AS_ defines */
CONTEXT_ALARMSCREEN, /* uses ACTION_AS_ defines */
CONTEXT_QUICKSCREEN, /* uses ACTION_QS_ defines below */
CONTEXT_PITCHSCREEN, /* uses ACTION_PS_ defines below */
CONTEXT_YESNOSCREEN, /*NOTE: make sure your target has this and ACTION_YESNO_ACCEPT */
CONTEXT_RECSCREEN,
CONTEXT_KEYBOARD,
@ -131,25 +82,23 @@ enum {
CONTEXT_USB_HID_MODE_PRESENTATION,
CONTEXT_USB_HID_MODE_BROWSER,
CONTEXT_USB_HID_MODE_MOUSE,
LAST_CONTEXT_PLACEHOLDER,
};
enum {
ACTION_NONE = BUTTON_NONE,
ACTION_UNKNOWN,
ACTION_REDRAW, /* returned if keys are locked and we splash()'ed */
ACTION_TOUCHSCREEN,
ACTION_TOUCHSCREEN_MODE, /* toggle the touchscreen mode */
ACTION_TOUCHSCREEN_IGNORE, /* used for the 'none' action in skins */
/* standard actions, use these first */
ACTION_STD_PREV,
ACTION_STD_PREV,
ACTION_STD_PREVREPEAT,
ACTION_STD_NEXT,
ACTION_STD_NEXTREPEAT,
ACTION_STD_OK,
ACTION_STD_CANCEL,
ACTION_STD_CONTEXT,
@ -158,9 +107,10 @@ enum {
ACTION_STD_KEYLOCK,
ACTION_STD_REC,
ACTION_STD_HOTKEY,
ACTION_F3, /* just so everything works again, possibly change me */
/* code context actions */
/* WPS codes */
ACTION_WPS_BROWSE,
ACTION_WPS_PLAY,
@ -178,11 +128,9 @@ enum {
ACTION_WPS_QUICKSCREEN,/* optional */
ACTION_WPS_MENU, /*this should be the same as ACTION_STD_MENU */
ACTION_WPS_VIEW_PLAYLIST,
ACTION_WPS_LIST_BOOKMARKS,/* optional */
ACTION_WPS_CREATE_BOOKMARK,/* optional */
ACTION_WPS_REC,
#if 0
ACTION_WPSAB_SINGLE, /* This needs to be #defined in
ACTION_WPSAB_SINGLE, /* This needs to be #defined in
the config-<target>.h to one of the ACTION_WPS_ actions
so it can be used */
#endif
@ -190,23 +138,23 @@ enum {
ACTION_WPS_ABSETB_NEXTDIR, /* you shouldnt want to change dir in ab-mode */
ACTION_WPS_ABRESET,
ACTION_WPS_HOTKEY,
/* list and tree page up/down */
/* list and tree page up/down */
ACTION_LISTTREE_PGUP,/* optional */
ACTION_LISTTREE_PGDOWN,/* optional */
#ifdef HAVE_VOLUME_IN_LIST
ACTION_LIST_VOLUP,
ACTION_LIST_VOLDOWN,
#endif
/* tree */
/* tree */
ACTION_TREE_ROOT_INIT,
ACTION_TREE_PGLEFT,/* optional */
ACTION_TREE_PGRIGHT,/* optional */
ACTION_TREE_STOP,
ACTION_TREE_WPS,
ACTION_TREE_HOTKEY,
/* radio */
ACTION_FM_MENU,
ACTION_FM_PRESET,
@ -226,7 +174,7 @@ enum {
ACTION_REC_NEWFILE,
ACTION_REC_F2,
ACTION_REC_F3,
/* main menu */
/* These are not strictly actions, but must be here
so they dont conflict with real actions in the menu code */
@ -235,11 +183,11 @@ enum {
ACTION_EXIT_AFTER_THIS_MENUITEM, /* if a menu returns this the menu will exit
once the subitem returns */
ACTION_ENTER_MENUITEM,
/* id3db */
/* list */
/* settings */
ACTION_SETTINGS_INC,
ACTION_SETTINGS_INCREPEAT,
@ -247,19 +195,17 @@ enum {
ACTION_SETTINGS_DEC,
ACTION_SETTINGS_DECREPEAT,
ACTION_SETTINGS_DECBIGSTEP,
ACTION_SETTINGS_SET, /* Used by touchscreen targets */
ACTION_SETTINGS_RESET,
/* bookmark screen */
ACTION_BMS_DELETE,
/* quickscreen */
ACTION_QS_LEFT,
ACTION_QS_RIGHT,
ACTION_QS_DOWN,
ACTION_QS_TOP,
ACTION_QS_VOLUP,
ACTION_QS_VOLDOWN,
/* pitchscreen */
/* obviously ignore if you dont have thise screen */
ACTION_PS_INC_SMALL,
@ -275,10 +221,10 @@ enum {
ACTION_PS_EXIT, /* _STD_* isnt going to work here */
ACTION_PS_SLOWER,
ACTION_PS_FASTER,
/* yesno screen */
ACTION_YESNO_ACCEPT,
/* keyboard screen */
ACTION_KBD_LEFT,
ACTION_KBD_RIGHT,
@ -293,7 +239,7 @@ enum {
ACTION_KBD_DOWN,
ACTION_KBD_MORSE_INPUT,
ACTION_KBD_MORSE_SELECT,
#ifdef HAVE_TOUCHSCREEN
/* the following are helper actions for touchscreen targets,
* These are for actions which are not doable or required if buttons are
@ -301,11 +247,7 @@ enum {
ACTION_TOUCH_SHUFFLE,
ACTION_TOUCH_REPMODE,
ACTION_TOUCH_MUTE,
ACTION_TOUCH_SCROLLBAR,
ACTION_TOUCH_VOLUME,
ACTION_TOUCH_SOFTLOCK,
ACTION_TOUCH_SETTING,
#endif
#endif
/* USB HID codes */
ACTION_USB_HID_FIRST, /* Place holder */
@ -379,60 +321,11 @@ enum {
LAST_ACTION_PLACEHOLDER, /* custom actions should be this + something */
};
/* act_cur holds action state during get_action() call */
typedef struct
{
int action;
int button;
int context;
int timeout;
const struct button_mapping *items;
const struct button_mapping* (*get_context_map)(int);
bool is_prebutton;
} action_cur_t;
/* act_last holds action state between get_action() calls */
typedef struct
{
int action;
long tick;
int button;
int context;
intptr_t data;
#if defined(HAVE_BACKLIGHT)
unsigned int backlight_mask;
long bl_filter_tick;
#endif
#if !defined(HAS_BUTTON_HOLD)
long sl_filter_tick;
unsigned int softlock_mask;
int unlock_combo;
bool keys_locked;
bool screen_has_lock;
#endif
bool repeated;
bool wait_for_release;
#ifndef DISABLE_ACTION_REMAP
int key_remap;
#endif
#ifdef HAVE_TOUCHSCREEN
bool ts_short_press;
int ts_data;
#endif
} action_last_t;
struct button_mapping {
int action_code;
int button_code;
int pre_button_code;
};
/* use if you want to supply your own button mappings, PLUGINS ONLY */
/* get_context_map is a function which returns a button_mapping* depedning on the given context */
/* custom button_mappings may "chain" to inbuilt CONTEXT's */
@ -446,13 +339,11 @@ bool action_userabort(int timeout);
/* no other code should need this apart from action.c */
const struct button_mapping* get_context_mapping(int context);
#ifndef HAS_BUTTON_HOLD
bool is_keys_locked(void);
#endif
/* load a key map to allow buttons for actions to be remapped see: core_keymap */
int action_set_keymap(struct button_mapping* core_keymap, int count);
/* load keymap in a handle: takes ownership of the handle on success */
int action_set_keymap_handle(int handle, int count);
/* returns the status code variable from action.c for the button just pressed
/* returns the status code variable from action.c for the button just pressed
If button != NULL it will be set to the actual button code */
#define ACTION_REMOTE 0x1 /* remote was pressed */
#define ACTION_REPEAT 0x2 /* action was repeated (NOT button) */
@ -479,27 +370,15 @@ int action_get_touchscreen_press(short *x, short *y);
* the press was within the viewport,
* ACTION_UNKNOWN (and x1, y1 untouched) if the press was outside
* BUTTON_NONE else
*
*
**/
int action_get_touchscreen_press_in_vp(short *x1, short *y1, struct viewport *vp);
#endif
/*******************************************************
* action_wait_for_release will not allow
* get_action(|_custom)() to return
* any ACTION_* values until the current buttons
* have been released.
* SYS_* and BUTTON_NONE will pass through.
* but, any actions relying on _RELEASE won't be seen.
*
* Note this doesn't currently work for
* touchscreen targets if called when the
* screen isn't currently touched because,
* if the touch coordinates change they can send
* normal (non-BUTTON_REPEAT) events repeatedly,
* this cannot be distinguished
* from normal button events.
*/
/* Don't let get_action*() return any ACTION_* values until the current buttons
* have been released. SYS_* and BUTTON_NONE will go through.
* Any actions relying on _RELEASE won't get seen.
*/
void action_wait_for_release(void);
#endif /* __ACTION_H__ */

View file

@ -38,56 +38,161 @@
#include "splash.h"
#include "viewport.h"
int alarm_screen(void)
static void speak_time(int hours, int minutes, bool speak_hours, bool enqueue)
{
bool usb, update;
struct tm *now = get_time();
struct tm atm;
memcpy(&atm, now, sizeof(struct tm));
rtc_get_alarm(&atm.tm_hour, &atm.tm_min);
if (global_settings.talk_menu){
if(speak_hours) {
talk_value(hours, UNIT_HOUR, enqueue);
talk_value(minutes, UNIT_MIN, true);
} else {
talk_value(minutes, UNIT_MIN, enqueue);
}
}
}
bool alarm_screen(void)
{
int h, m;
bool done = false;
struct tm *tm;
int togo;
int button;
int i;
bool update = true;
bool hour_wrapped = false;
struct viewport vp[NB_SCREENS];
rtc_get_alarm(&h, &m);
/* After a battery change the RTC values are out of range */
if (!valid_time(&atm))
memcpy(&atm, now, sizeof(struct tm));
atm.tm_sec = 0;
usb = set_time_screen(str(LANG_ALARM_MOD_TIME), &atm, false);
update = valid_time(&atm); /* set_time returns invalid time if canceled */
if (!usb && update)
if (m > 60 || h > 24) {
m = 0;
h = 12;
} else {
m = m / 5 * 5; /* 5 min accuracy should be enough */
}
FOR_NB_SCREENS(i)
{
viewport_set_defaults(&vp[i], i);
}
now = get_time();
int nmins = now->tm_min + (now->tm_hour * 60);
int amins = atm.tm_min + (atm.tm_hour * 60);
int mins_togo = (amins - nmins + 1440) % 1440;
while(!done) {
if(update)
{
FOR_NB_SCREENS(i)
{
screens[i].set_viewport(&vp[i]);
screens[i].clear_viewport();
screens[i].puts(0, 4, str(LANG_ALARM_MOD_KEYS));
}
/* Talk when entering the wakeup screen */
speak_time(h, m, true, true);
update = false;
}
FOR_NB_SCREENS(i)
{
screens[i].set_viewport(&vp[i]);
screens[i].putsf(0, 1, str(LANG_ALARM_MOD_TIME));
screens[i].putsf(0, 2, "%02d:%02d", h, m);
screens[i].update_viewport();
screens[i].set_viewport(NULL);
}
button = get_action(CONTEXT_SETTINGS,HZ);
switch(button) {
case ACTION_STD_OK:
/* prevent that an alarm occurs in the shutdown procedure */
/* accept alarms only if they are in 2 minutes or more */
if (mins_togo > 1) {
tm = get_time();
togo = (m + h * 60 - tm->tm_min - tm->tm_hour * 60 + 1440) % 1440;
if (togo > 1) {
rtc_init();
rtc_set_alarm(atm.tm_hour,atm.tm_min);
rtc_set_alarm(h,m);
rtc_enable_alarm(true);
if (global_settings.talk_menu)
{
talk_id(LANG_ALARM_MOD_TIME_TO_GO, true);
talk_value(mins_togo / 60, UNIT_HOUR, true);
talk_value(mins_togo % 60, UNIT_MIN, true);
talk_value(togo / 60, UNIT_HOUR, true);
talk_value(togo % 60, UNIT_MIN, true);
talk_force_enqueue_next();
}
splashf(HZ*2, str(LANG_ALARM_MOD_TIME_TO_GO),
mins_togo / 60, mins_togo % 60);
togo / 60, togo % 60);
done = true;
} else {
splash(HZ, ID2P(LANG_ALARM_MOD_ERROR));
update = false;
update = true;
}
}
break;
if (usb || !update)
{
if (!usb)
/* inc(m) */
case ACTION_SETTINGS_INC:
case ACTION_SETTINGS_INCREPEAT:
m += 5;
if (m == 60) {
h += 1;
m = 0;
hour_wrapped = true;
}
if (h == 24)
h = 0;
speak_time(h, m, hour_wrapped, false);
break;
/* dec(m) */
case ACTION_SETTINGS_DEC:
case ACTION_SETTINGS_DECREPEAT:
m -= 5;
if (m == -5) {
h -= 1;
m = 55;
hour_wrapped = true;
}
if (h == -1)
h = 23;
speak_time(h, m, hour_wrapped, false);
break;
/* inc(h) */
case ACTION_STD_NEXT:
case ACTION_STD_NEXTREPEAT:
h = (h+1) % 24;
if (global_settings.talk_menu)
talk_value(h, UNIT_HOUR, false);
break;
/* dec(h) */
case ACTION_STD_PREV:
case ACTION_STD_PREVREPEAT:
h = (h+23) % 24;
if (global_settings.talk_menu)
talk_value(h, UNIT_HOUR, false);
break;
case ACTION_STD_CANCEL:
rtc_enable_alarm(false);
splash(HZ*2, ID2P(LANG_ALARM_MOD_DISABLE));
rtc_enable_alarm(false);
return 1;
done = true;
break;
case ACTION_NONE:
hour_wrapped = false;
break;
default:
if(default_event_handler(button) == SYS_USB_CONNECTED)
{
rtc_enable_alarm(false);
return true;
}
break;
}
}
return 0;
return false;
}

View file

@ -21,6 +21,6 @@
#ifndef _ALARM_MENU_H
#define _ALARM_MENU_H
int alarm_screen(void);
bool alarm_screen(void);
#endif

View file

@ -31,36 +31,13 @@
/** Playback events **/
enum {
/* Playback is starting from a stopped state
data = NULL */
PLAYBACK_EVENT_START_PLAYBACK = (EVENT_CLASS_PLAYBACK|1),
/* Audio has begun buffering for decoding track (or is already completed)
data = &(struct track_event){} */
PLAYBACK_EVENT_TRACK_BUFFER,
/* Handles for current user track are ready (other than audio or codec)
data = &(struct track_event){} */
PLAYBACK_EVENT_CUR_TRACK_READY,
/* Current user track finished
data = &(struct track_event){} */
PLAYBACK_EVENT_TRACK_FINISH,
/* A new current user track has begun
data = &(struct track_event){} */
PLAYBACK_EVENT_TRACK_CHANGE,
/* A manual skip is about to be processed
data = NULL */
PLAYBACK_EVENT_TRACK_SKIP,
/* Next track medadata was just loaded
data = &(struct track_event){} */
PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE,
};
/** VOICE events **/
enum {
/* Voice is playing
data = &(bool){true|false} */
VOICE_EVENT_IS_PLAYING = (EVENT_CLASS_VOICE|1),
};
/** Buffering events **/
enum {
BUFFER_EVENT_BUFFER_LOW = (EVENT_CLASS_BUFFERING|1),
@ -68,7 +45,6 @@ enum {
BUFFER_EVENT_CLOSED,
BUFFER_EVENT_MOVED,
BUFFER_EVENT_FINISHED,
BUFFER_EVENT_BUFFER_RESET
};
/** Generic GUI class events **/
@ -76,9 +52,6 @@ enum {
GUI_EVENT_STATUSBAR_TOGGLE = (EVENT_CLASS_GUI|1),
GUI_EVENT_ACTIONUPDATE,
GUI_EVENT_THEME_CHANGED,
/* Called when the UI viewport is cleared in the skin engine to
* notify the current screen that it needs to do an update */
GUI_EVENT_NEED_UI_UPDATE,
};
/** Recording events **/

View file

@ -8,6 +8,9 @@
#
INCLUDES += -I$(APPSDIR) $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))
ifdef APP_TYPE
INCLUDES += -I$(APPSDIR)/hosted
endif
SRC += $(call preprocess, $(APPSDIR)/SOURCES)
# apps/features.txt is a file that (is preprocessed and) lists named features
@ -24,7 +27,7 @@ $(BUILDDIR)/apps/features: $(APPSDIR)/features.txt $(BUILDDIR)/firmware/common/
$(call PRINTS,PP $(<F))
$(SILENT)$(CC) $(PPCFLAGS) \
-E -P -imacros "config.h" -imacros "button.h" -x c $< | \
grep -v "^#" | grep -v "^ *$$" > $(BUILDDIR)/apps/features; \
grep -v "^\#" | grep -v "^ *$$" > $(BUILDDIR)/apps/features; \
$(BUILDDIR)/apps/genlang-features: $(BUILDDIR)/apps/features
$(call PRINTS,GEN $(subst $(BUILDDIR)/,,$@))tr \\n : < $< > $@

View file

@ -34,9 +34,6 @@
#if CONFIG_TUNER
#include "radio.h"
#endif
#if defined(IPOD_ACCESSORY_PROTOCOL) && defined(HAVE_LINE_REC)
#include "iap.h"
#endif
/* Some audio sources may require a boosted CPU */
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
@ -45,8 +42,7 @@
#endif
#endif
#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) \
|| (defined(SONY_NWZ_LINUX) && !defined(SIMULATOR)))
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
#ifdef AUDIO_CPU_BOOST
static void audio_cpu_boost(bool state)
@ -99,13 +95,6 @@ void audio_set_input_source(int source, unsigned flags)
radio_start();
#endif
#if defined(IPOD_ACCESSORY_PROTOCOL) && defined(HAVE_LINE_REC)
static bool last_rec_onoff = false;
bool onoff = (source == AUDIO_SRC_LINEIN) ? true : false;
if (last_rec_onoff != onoff)
last_rec_onoff = iap_record(onoff);
#endif
/* set hardware inputs */
audio_input_mux(source, flags);
} /* audio_set_source */
@ -165,25 +154,3 @@ int audio_get_spdif_sample_rate(void)
#endif /* HAVE_SPDIF_IN */
#endif /* PLATFORM_NATIVE */
#ifdef HAVE_SPEAKER
void audio_enable_speaker(int mode)
{
#if defined(HAVE_HEADPHONE_DETECTION) || defined(HAVE_LINEOUT_DETECTION)
/* if needed, query jack state */
if(mode == 2)
{
#ifdef HAVE_HEADPHONE_DETECTION
if (headphones_inserted())
mode = 0;
#endif
#ifdef HAVE_LINEOUT_DETECTION
if (lineout_inserted())
mode = 0;
#endif
}
#endif
/* treat any nonzero value as enable */
audiohw_enable_speaker(mode);
}
#endif

View file

@ -1,188 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2005-2007 Miika Pekkarinen
* Copyright (C) 2007-2008 Nicolas Pennequin
* Copyright (C) 2011-2013 Michael Sevakis
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "system.h"
#include "kernel.h"
#include "logf.h"
#include "usb.h"
#include "pcm.h"
#include "sound.h"
#include "pcmbuf.h"
#include "appevents.h"
#include "audio_thread.h"
#ifdef AUDIO_HAVE_RECORDING
#include "pcm_record.h"
#endif
#include "codec_thread.h"
#include "voice_thread.h"
#include "talk.h"
#include "settings.h"
/* Macros to enable logf for queues
logging on SYS_TIMEOUT can be disabled */
#ifdef SIMULATOR
/* Define this for logf output of all queuing except SYS_TIMEOUT */
#define AUDIO_LOGQUEUES
/* Define this to logf SYS_TIMEOUT messages */
/*#define AUDIO_LOGQUEUES_SYS_TIMEOUT*/
#endif
#ifdef AUDIO_LOGQUEUES
#define LOGFQUEUE logf
#else
#define LOGFQUEUE(...)
#endif
bool audio_is_initialized = false;
/* Event queues */
struct event_queue audio_queue SHAREDBSS_ATTR;
static struct queue_sender_list audio_queue_sender_list SHAREDBSS_ATTR;
/* Audio thread */
static long audio_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)];
static const char audio_thread_name[] = "audio";
unsigned int audio_thread_id = 0;
static void NORETURN_ATTR audio_thread(void)
{
struct queue_event ev;
ev.id = Q_NULL; /* something not in switch below */
pcm_postinit();
while (1)
{
switch (ev.id)
{
/* Starts the playback engine branch */
case Q_AUDIO_PLAY:
LOGFQUEUE("audio < Q_AUDIO_PLAY");
audio_playback_handler(&ev);
continue;
/* Playback has to handle these, even if not playing */
case Q_AUDIO_REMAKE_AUDIO_BUFFER:
#ifdef HAVE_DISK_STORAGE
case Q_AUDIO_UPDATE_WATERMARK:
#endif
audio_playback_handler(&ev);
break;
#ifdef AUDIO_HAVE_RECORDING
/* Starts the recording engine branch */
case Q_AUDIO_INIT_RECORDING:
LOGFQUEUE("audio < Q_AUDIO_INIT_RECORDING");
audio_recording_handler(&ev);
continue;
#endif
/* All return upon USB */
case SYS_USB_CONNECTED:
LOGFQUEUE("audio < SYS_USB_CONNECTED");
voice_stop();
usb_acknowledge(SYS_USB_CONNECTED_ACK);
usb_wait_for_disconnect(&audio_queue);
break;
}
queue_wait(&audio_queue, &ev);
}
}
void audio_voice_event(unsigned short id, void *data)
{
(void)id;
/* Make audio play softly while voice is speaking */
pcmbuf_soft_mode(*(bool *)data);
}
void audio_queue_post(long id, intptr_t data)
{
queue_post(&audio_queue, id, data);
}
intptr_t audio_queue_send(long id, intptr_t data)
{
return queue_send(&audio_queue, id, data);
}
/* Return the playback and recording status */
int audio_status(void)
{
return playback_status()
#ifdef AUDIO_HAVE_RECORDING
| pcm_rec_status()
#endif
;
}
/* Clear all accumulated audio errors for playback and recording */
void audio_error_clear(void)
{
#ifdef AUDIO_HAVE_RECORDING
pcm_rec_error_clear();
#endif
}
/** -- Startup -- **/
/* Initialize the audio system - called from init() in main.c */
void INIT_ATTR audio_init(void)
{
/* Can never do this twice */
if (audio_is_initialized)
{
logf("audio: already initialized");
return;
}
logf("audio: initializing");
/* Initialize queues before giving control elsewhere in case it likes
to send messages. Thread creation will be delayed however so nothing
starts running until ready if something yields such as talk_init. */
queue_init(&audio_queue, true);
codec_thread_init();
/* This thread does buffer, so match its priority */
audio_thread_id = create_thread(audio_thread, audio_stack,
sizeof(audio_stack), 0, audio_thread_name
IF_PRIO(, MIN(PRIORITY_BUFFERING, PRIORITY_USER_INTERFACE))
IF_COP(, CPU));
queue_enable_queue_send(&audio_queue, &audio_queue_sender_list,
audio_thread_id);
playback_init();
#ifdef AUDIO_HAVE_RECORDING
recording_init();
#endif
add_event(VOICE_EVENT_IS_PLAYING, audio_voice_event);
/* Probably safe to say */
audio_is_initialized = true;
sound_settings_apply();
}

View file

@ -1,109 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2005-2007 Miika Pekkarinen
* Copyright (C) 2007-2008 Nicolas Pennequin
* Copyright (C) 2011-2013 Michael Sevakis
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef AUDIO_THREAD_H
#define AUDIO_THREAD_H
/* Define one constant that includes recording related functionality */
#if defined(HAVE_RECORDING) && !defined(SIMULATOR)
#define AUDIO_HAVE_RECORDING
#endif
enum
{
Q_NULL = 0, /* reserved */
/* -> audio */
Q_AUDIO_PLAY,
Q_AUDIO_STOP,
Q_AUDIO_PAUSE,
Q_AUDIO_SKIP,
Q_AUDIO_PRE_FF_REWIND,
Q_AUDIO_FF_REWIND,
Q_AUDIO_FLUSH,
Q_AUDIO_DIR_SKIP,
/* pcmbuf -> audio */
Q_AUDIO_TRACK_CHANGED,
/* audio -> audio */
Q_AUDIO_FILL_BUFFER, /* continue buffering next track */
/* buffering -> audio */
Q_AUDIO_BUFFERING, /* some buffer event */
Q_AUDIO_FINISH_LOAD_TRACK, /* metadata is buffered */
Q_AUDIO_HANDLE_FINISHED, /* some other type is buffered */
/* codec -> audio (*) */
Q_AUDIO_CODEC_SEEK_COMPLETE,
Q_AUDIO_CODEC_COMPLETE,
/* audio -> codec */
Q_CODEC_LOAD,
Q_CODEC_RUN,
Q_CODEC_PAUSE,
Q_CODEC_SEEK,
Q_CODEC_STOP,
Q_CODEC_UNLOAD,
/* -> codec */
Q_CODEC_DO_CALLBACK,
/* -> recording */
#ifdef HAVE_RECORDING
Q_AUDIO_INIT_RECORDING,
Q_AUDIO_CLOSE_RECORDING,
Q_AUDIO_RECORDING_OPTIONS,
Q_AUDIO_RECORD,
Q_AUDIO_RECORD_STOP,
Q_AUDIO_RECORD_PAUSE,
Q_AUDIO_RECORD_RESUME,
Q_AUDIO_RECORD_FLUSH,
#endif
/*- settings -*/
#ifdef HAVE_DISK_STORAGE
/* -> audio */
Q_AUDIO_UPDATE_WATERMARK, /* buffering watermark needs updating */
#endif
/* -> audio */
Q_AUDIO_REMAKE_AUDIO_BUFFER, /* buffer needs to be reinitialized */
};
/* (*) If you change these, you must check audio_clear_track_notifications
in playback.c for correctness */
void audio_init(void);
void playback_init(void);
unsigned int playback_status(void);
void audio_playback_handler(struct queue_event *ev);
#ifdef AUDIO_HAVE_RECORDING
void audio_recording_handler(struct queue_event *ev);
#endif
/** --- audio_queue helpers --- **/
void audio_queue_post(long id, intptr_t data);
intptr_t audio_queue_send(long id, intptr_t data);
#endif /* AUDIO_THREAD_H */

View file

@ -1,103 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (c) 2011 Michael Sevakis
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "system.h"
#include "settings.h"
#include "pcm.h"
#include "pcm_mixer.h"
#include "misc.h"
#include "fixedpoint.h"
/** Beep generation, CPU optimized **/
#include "asm/beep.c"
static uint32_t beep_phase; /* Phase of square wave generator */
static uint32_t beep_step; /* Step of square wave generator on each sample */
#ifdef BEEP_GENERIC
static int16_t beep_amplitude; /* Amplitude of square wave generator */
#else
/* Optimized routines do XOR with phase sign bit in both channels at once */
static uint32_t beep_amplitude; /* Amplitude of square wave generator */
#endif
static int beep_count; /* Number of samples remaining to generate */
#define BEEP_COUNT(fs, duration) ((fs) / 1000 * (duration))
/* Reserve enough static space for keyclick to fit in worst case */
#define BEEP_BUF_COUNT BEEP_COUNT(PLAY_SAMPR_MAX, KEYCLICK_DURATION)
static int16_t beep_buf[BEEP_BUF_COUNT*2] IBSS_ATTR __attribute__((aligned(4)));
/* Callback to generate the beep frames - also don't want inlining of
call below in beep_play */
static void __attribute__((noinline))
beep_get_more(const void **start, size_t *size)
{
int count = beep_count;
if (count > 0)
{
count = MIN(count, BEEP_BUF_COUNT);
beep_count -= count;
*start = beep_buf;
*size = count * 2 * sizeof (int16_t);
beep_generate((void *)beep_buf, count, &beep_phase,
beep_step, beep_amplitude);
}
}
/* Generates a constant square wave sound with a given frequency in Hertz for
a duration in milliseconds */
void beep_play(unsigned int frequency, unsigned int duration,
unsigned int amplitude)
{
mixer_channel_stop(PCM_MIXER_CHAN_BEEP);
if (frequency == 0 || duration == 0 || amplitude == 0)
return;
if (amplitude > INT16_MAX)
amplitude = INT16_MAX;
/* Setup the parameters for the square wave generator */
uint32_t fout = mixer_get_frequency();
beep_phase = 0;
beep_step = fp_div(frequency, fout, 32);
beep_count = BEEP_COUNT(fout, duration);
#ifdef BEEP_GENERIC
beep_amplitude = amplitude;
#else
/* Optimized routines do XOR with phase sign bit in both channels at once */
beep_amplitude = amplitude | (amplitude << 16); /* Word:|AMP16|AMP16| */
#endif
/* If it fits - avoid cb overhead */
const void *start;
size_t size;
/* Generate first frame here */
beep_get_more(&start, &size);
mixer_channel_set_amplitude(PCM_MIXER_CHAN_BEEP, MIX_AMP_UNITY);
mixer_channel_play_data(PCM_MIXER_CHAN_BEEP,
beep_count ? beep_get_more : NULL,
start, size);
}

View file

@ -25,28 +25,27 @@ ifneq ($(strip $(BMP2RB_REMOTENATIVE)),)
BMP += $(call preprocess, $(BITMAPDIR)/remote_native/SOURCES)
endif
BMPOBJ = $(call full_path_subst,$(ROOTDIR)/%.bmp,$(BUILDDIR)/%.o,$(BMP))
BMPOBJ = $(BMP:$(ROOTDIR)/%.bmp=$(BUILDDIR)/%.o)
BMPHFILES = $(BMPINCDIR)/usblogo.h $(BMPINCDIR)/remote_usblogo.h \
$(BMPINCDIR)/default_icons.h $(BMPINCDIR)/remote_default_icons.h \
$(BMPINCDIR)/rockboxlogo.h $(BMPINCDIR)/remote_rockboxlogo.h \
$(BMPINCDIR)/rockboxicon.h $(BMPINCDIR)/toolsicon.h
$(BMPINCDIR)/rockboxlogo.h $(BMPINCDIR)/remote_rockboxlogo.h
$(BMPHFILES): $(BMPOBJ)
# pattern rules to create .c files from .bmp, one for each subdir:
$(BUILDDIR)/apps/bitmaps/mono/%.c: $(ROOTDIR)/apps/bitmaps/mono/%.bmp $(TOOLSDIR)/bmp2rb
$(SILENT)mkdir -p $(dir $@) $(BMPINCDIR)
$(call PRINTS,BMP2RB $(<F))$(BMP2RB_MONO) -b -h $(BMPINCDIR) $< > $@
$(call PRINTS,BMP2RB $(<F))$(BMP2RB_MONO) -h $(BMPINCDIR) $< > $@
$(BUILDDIR)/apps/bitmaps/native/%.c: $(ROOTDIR)/apps/bitmaps/native/%.bmp $(TOOLSDIR)/bmp2rb
$(SILENT)mkdir -p $(dir $@) $(BMPINCDIR)
$(call PRINTS,BMP2RB $(<F))$(BMP2RB_NATIVE) -b -h $(BMPINCDIR) $< > $@
$(call PRINTS,BMP2RB $(<F))$(BMP2RB_NATIVE) -h $(BMPINCDIR) $< > $@
$(BUILDDIR)/apps/bitmaps/remote_mono/%.c: $(ROOTDIR)/apps/bitmaps/remote_mono/%.bmp $(TOOLSDIR)/bmp2rb
$(SILENT)mkdir -p $(dir $@) $(BMPINCDIR)
$(call PRINTS,BMP2RB $(<F))$(BMP2RB_REMOTEMONO) -b -h $(BMPINCDIR) $< > $@
$(call PRINTS,BMP2RB $(<F))$(BMP2RB_REMOTEMONO) -h $(BMPINCDIR) $< > $@
$(BUILDDIR)/apps/bitmaps/remote_native/%.c: $(ROOTDIR)/apps/bitmaps/remote_native/%.bmp $(TOOLSDIR)/bmp2rb
$(SILENT)mkdir -p $(dir $@) $(BMPINCDIR)
$(call PRINTS,BMP2RB $(<F))$(BMP2RB_REMOTENATIVE) -b -h $(BMPINCDIR) $< > $@
$(call PRINTS,BMP2RB $(<F))$(BMP2RB_REMOTENATIVE) -h $(BMPINCDIR) $< > $@

View file

@ -1,5 +1,3 @@
default_icons.bmp
#if (CONFIG_PLATFORM & PLATFORM_HOSTED) && defined(__APPLE__)
osx_dummy.bmp
#endif

View file

@ -1,3 +1,5 @@
#ifdef HAVE_LCD_BITMAP
/* Rockbox logo */
#if (LCD_DEPTH == 1)
#if (LCD_WIDTH == 160)
@ -7,56 +9,34 @@ rockboxlogo.128x42x1.bmp
#else
rockboxlogo.112x30x1.bmp
#endif
#elif (LCD_WIDTH == 96) && (LCD_DEPTH >= 16)
rockboxlogo.96x30x16.bmp
#elif (LCD_WIDTH == 128) && (LCD_DEPTH == 2)
rockboxlogo.128x42x2.bmp
#elif (LCD_WIDTH == 128) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH == 128) && (LCD_DEPTH == 16)
rockboxlogo.128x40x16.bmp
#elif (LCD_WIDTH == 132) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH == 132) && (LCD_DEPTH == 16)
rockboxlogo.132x40x16.bmp
#elif (LCD_WIDTH == 138) && (LCD_DEPTH >= 2)
#elif (LCD_WIDTH == 138) && (LCD_DEPTH == 2)
rockboxlogo.138x46x2.bmp
#elif (LCD_WIDTH == 160) && (LCD_DEPTH == 2)
rockboxlogo.160x53x2.bmp
#elif (LCD_WIDTH == 320) && (LCD_DEPTH == 2)
rockboxlogo.160x53x2.bmp
#elif (LCD_WIDTH == 160) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH == 160) && (LCD_DEPTH == 16)
rockboxlogo.160x50x16.bmp
#elif (LCD_WIDTH == 176) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH == 176) && (LCD_DEPTH == 16)
rockboxlogo.176x54x16.bmp
#elif (LCD_WIDTH == 220) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH == 220) && (LCD_DEPTH == 16)
rockboxlogo.220x68x16.bmp
#elif (LCD_WIDTH == 240) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH == 240) && (LCD_DEPTH == 16)
rockboxlogo.240x74x16.bmp
#elif (LCD_WIDTH >= 320) && (LCD_WIDTH < 480) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH >= 320) && (LCD_WIDTH < 480) && (LCD_DEPTH == 16)
rockboxlogo.320x98x16.bmp
#elif (LCD_WIDTH >= 480) && (LCD_WIDTH < 640) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH >= 480) && (LCD_WIDTH < 640) && (LCD_DEPTH == 16)
rockboxlogo.480x149x16.bmp
#elif (LCD_WIDTH >= 640) && (LCD_DEPTH >= 16)
#elif (LCD_WIDTH >= 640) && (LCD_DEPTH == 16)
rockboxlogo.640x198x16.bmp
#endif
/* The Sony NWZ linux bootloader needs icons to display a menu */
#if defined(BOOTLOADER)
#if defined(SONY_NWZ_LINUX)
rockboxicon.130x130x16.bmp
toolsicon.130x130x16.bmp
#elif defined(AGPTEK_ROCKER)
hibyicon.70x70x16.bmp
rockboxicon.70x70x16.bmp
toolsicon.70x70x16.bmp
#elif (defined(XDUOO_X3II) || defined(XDUOO_X20) || defined(EROS_Q))
hibyicon.130x130x16.bmp
rockboxicon.130x130x16.bmp
toolsicon.130x130x16.bmp
#elif defined(FIIO_M3K_LINUX)
fiioicon.130x130x16.bmp
rockboxicon.130x130x16.bmp
toolsicon.130x130x16.bmp
#endif
#endif
#ifndef BOOTLOADER /* We don't need these for the bootloader */
/* USB logo */
@ -65,8 +45,6 @@ toolsicon.130x130x16.bmp
usblogo.176x48x16.bmp
#elif LCD_WIDTH >= 128
usblogo.128x37x16.bmp
#elif LCD_WIDTH >= 88
usblogo.88x24x16.bmp
#endif
#elif LCD_DEPTH > 1 /* greyscale */
#ifdef IPOD_1G2G /* use firewire logo */
@ -82,4 +60,15 @@ usblogo.104x27x1.bmp
#endif
#endif
/* List Icons */
#if LCD_DEPTH == 16
default_icons.6x8x16.bmp
#elif LCD_DEPTH > 1 /* greyscale */
default_icons.6x8x2.bmp
#else
default_icons.6x8x1.bmp
#endif
#endif /* BOOTLOADER */
#endif /* HAVE_LCD_BITMAP */

Some files were not shown because too many files have changed in this diff Show more