summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/abrepeat.h33
-rw-r--r--apps/action.c142
-rw-r--r--apps/action.h11
-rw-r--r--apps/apps.make2
-rw-r--r--apps/bookmark.c1205
-rw-r--r--apps/bookmark.h8
-rw-r--r--apps/buffering.c4
-rw-r--r--apps/codecs.c5
-rw-r--r--apps/core_keymap.c133
-rw-r--r--apps/core_keymap.h7
-rw-r--r--apps/cuesheet.c36
-rw-r--r--apps/debug_menu.c134
-rw-r--r--apps/enc_config.c10
-rw-r--r--apps/features.txt4
-rw-r--r--apps/filetree.c152
-rw-r--r--apps/filetree.h3
-rw-r--r--apps/filetypes.c294
-rw-r--r--apps/filetypes.h7
-rw-r--r--apps/gui/bitmap/list-skinned.c3
-rw-r--r--apps/gui/bitmap/list.c18
-rw-r--r--apps/gui/color_picker.c26
-rw-r--r--apps/gui/folder_select.c8
-rw-r--r--apps/gui/icon.c56
-rw-r--r--apps/gui/line.c3
-rw-r--r--apps/gui/list.c188
-rw-r--r--apps/gui/list.h48
-rw-r--r--apps/gui/option_select.c133
-rw-r--r--apps/gui/option_select.h4
-rw-r--r--apps/gui/quickscreen.c98
-rw-r--r--apps/gui/quickscreen.h10
-rw-r--r--apps/gui/skin_engine/skin_backdrops.c24
-rw-r--r--apps/gui/skin_engine/skin_display.c244
-rw-r--r--apps/gui/skin_engine/skin_display.h9
-rw-r--r--apps/gui/skin_engine/skin_engine.c61
-rw-r--r--apps/gui/skin_engine/skin_engine.h24
-rw-r--r--apps/gui/skin_engine/skin_parser.c217
-rw-r--r--apps/gui/skin_engine/skin_render.c44
-rw-r--r--apps/gui/skin_engine/skin_tokens.c55
-rw-r--r--apps/gui/skin_engine/skin_touchsupport.c17
-rw-r--r--apps/gui/skin_engine/wps_internals.h55
-rw-r--r--apps/gui/splash.c176
-rw-r--r--apps/gui/splash.h11
-rw-r--r--apps/gui/statusbar-skinned.c18
-rw-r--r--apps/gui/statusbar-skinned.h5
-rw-r--r--apps/gui/usb_screen.c18
-rw-r--r--apps/gui/viewport.c40
-rw-r--r--apps/gui/viewport.h1
-rw-r--r--apps/gui/wps.c578
-rw-r--r--apps/gui/wps.h37
-rw-r--r--apps/gui/yesno.c123
-rw-r--r--apps/gui/yesno.h11
-rw-r--r--apps/hosted/android/keyboard.c2
-rw-r--r--apps/hosted/android/notification.c1
-rw-r--r--apps/hosted/android/yesno.c11
-rw-r--r--apps/iap/iap-core.c4
-rw-r--r--apps/iap/iap-lingo2.c11
-rw-r--r--apps/iap/iap-lingo4.c21
-rw-r--r--apps/keymaps/keymap-agptekrocker.c21
-rw-r--r--apps/keymaps/keymap-clip.c14
-rw-r--r--apps/keymaps/keymap-erosq.c3
-rw-r--r--apps/keymaps/keymap-fiiom3k.c20
-rw-r--r--apps/keymaps/keymap-fiiom3klinux.c2
-rw-r--r--apps/keymaps/keymap-fuzeplus.c5
-rw-r--r--apps/keymaps/keymap-ipod.c68
-rw-r--r--apps/keymaps/keymap-ma.c2
-rw-r--r--apps/keymaps/keymap-nwz.c5
-rw-r--r--apps/keymaps/keymap-nwza860.c3
-rw-r--r--apps/keymaps/keymap-ondavx777.c2
-rw-r--r--apps/keymaps/keymap-rk27xx-generic.c2
-rw-r--r--apps/keymaps/keymap-shanlingq1.c2
-rw-r--r--apps/keymaps/keymap-touchscreen.c2
-rw-r--r--apps/keymaps/keymap-xduoox20.c2
-rw-r--r--apps/keymaps/keymap-xduoox3.c6
-rw-r--r--apps/keymaps/keymap-xduoox3ii.c2
-rw-r--r--apps/keymaps/keymap-ypr0.c2
-rw-r--r--apps/keymaps/keymap-ypr1.c2
-rw-r--r--apps/keymaps/keymap-zen.c3
-rw-r--r--apps/keymaps/keymap-zenxfi2.c2
-rw-r--r--apps/lang/chinese-simp.lang2
-rw-r--r--apps/lang/chinese-trad.lang2
-rw-r--r--apps/lang/english-us.lang412
-rw-r--r--apps/lang/english.lang371
-rw-r--r--apps/lang/italiano.lang545
-rw-r--r--apps/lang/nederlands.lang368
-rw-r--r--apps/lang/polski.lang363
-rw-r--r--apps/lang/srpski.lang594
-rw-r--r--apps/language.c13
-rw-r--r--apps/language.h2
-rw-r--r--apps/logfdisp.c15
-rw-r--r--apps/main.c67
-rw-r--r--apps/menu.c65
-rw-r--r--apps/menu.h53
-rw-r--r--apps/menus/audiohw_eq_menu.c156
-rw-r--r--apps/menus/display_menu.c67
-rw-r--r--apps/menus/eq_menu.c57
-rw-r--r--apps/menus/main_menu.c54
-rw-r--r--apps/menus/playback_menu.c75
-rw-r--r--apps/menus/playlist_menu.c55
-rw-r--r--apps/menus/plugin_menu.c24
-rw-r--r--apps/menus/radio_menu.c27
-rw-r--r--apps/menus/recording_menu.c84
-rw-r--r--apps/menus/settings_menu.c39
-rw-r--r--apps/menus/sound_menu.c18
-rw-r--r--apps/menus/theme_menu.c93
-rw-r--r--apps/menus/time_menu.c14
-rw-r--r--apps/misc.c477
-rw-r--r--apps/misc.h48
-rw-r--r--apps/onplay.c776
-rw-r--r--apps/onplay.h36
-rw-r--r--apps/open_plugin.c237
-rw-r--r--apps/open_plugin.h10
-rw-r--r--apps/playback.c368
-rw-r--r--apps/playback.h2
-rw-r--r--apps/playlist.c4982
-rw-r--r--apps/playlist.h91
-rw-r--r--apps/playlist_catalog.c337
-rw-r--r--apps/playlist_catalog.h15
-rw-r--r--apps/playlist_viewer.c423
-rw-r--r--apps/playlist_viewer.h3
-rw-r--r--apps/plugin.c126
-rw-r--r--apps/plugin.h117
-rw-r--r--apps/plugins/2048.c14
-rw-r--r--apps/plugins/CATEGORIES3
-rw-r--r--apps/plugins/SOURCES6
-rw-r--r--apps/plugins/SUBDIRS4
-rw-r--r--apps/plugins/SUBDIRS.app_build1
-rw-r--r--apps/plugins/alarmclock.c6
-rw-r--r--apps/plugins/announce_status.c109
-rw-r--r--apps/plugins/battery_bench.c68
-rw-r--r--apps/plugins/bitmaps/native/SOURCES42
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.112x30x1.bmpbin0 -> 542 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.128x40x16.bmpbin0 -> 15414 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.128x42x1.bmpbin0 -> 736 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.128x42x2.bmpbin0 -> 2808 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.132x40x16.bmpbin0 -> 15894 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.138x46x2.bmpbin0 -> 3392 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.160x50x16.bmpbin0 -> 24054 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.160x53x1.bmpbin0 -> 1122 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.160x53x2.bmpbin0 -> 4312 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.176x54x16.bmpbin0 -> 28566 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.220x68x16.bmpbin0 -> 44934 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.240x74x16.bmpbin0 -> 53334 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.320x98x16.bmpbin0 -> 94136 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.480x149x16.bmpbin0 -> 214614 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.640x198x16.bmpbin0 -> 380214 bytes
-rw-r--r--apps/plugins/bitmaps/native/creditslogo.96x30x16.bmpbin0 -> 8694 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/SOURCES7
-rw-r--r--apps/plugins/bitmaps/remote_native/remote_creditslogo.128x42x1.bmpbin0 -> 736 bytes
-rw-r--r--apps/plugins/bitmaps/remote_native/remote_creditslogo.128x42x2.bmpbin0 -> 2808 bytes
-rw-r--r--apps/plugins/bounce.c23
-rw-r--r--apps/plugins/brickmania.c25
-rw-r--r--apps/plugins/bubbles.c10
-rw-r--r--apps/plugins/calculator.c4
-rw-r--r--apps/plugins/calendar.c15
-rw-r--r--apps/plugins/chessbox/chessbox_pgn.c4
-rw-r--r--apps/plugins/chessbox/chessbox_pgn.h2
-rw-r--r--apps/plugins/chopper.c10
-rw-r--r--apps/plugins/clix.c8
-rw-r--r--apps/plugins/clock/clock.c10
-rw-r--r--apps/plugins/clock/clock_menu.c24
-rw-r--r--apps/plugins/codebuster.c7
-rw-r--r--apps/plugins/credits.c79
-rw-r--r--apps/plugins/cube.c12
-rw-r--r--apps/plugins/demystify.c32
-rw-r--r--apps/plugins/dice.c9
-rw-r--r--apps/plugins/doom/d_deh.c3
-rw-r--r--apps/plugins/doom/i_video.c3
-rw-r--r--apps/plugins/doom/rockdoom.c14
-rw-r--r--apps/plugins/fft/fft.c42
-rw-r--r--apps/plugins/fire.c15
-rw-r--r--apps/plugins/fireworks.c29
-rw-r--r--apps/plugins/flipit.c4
-rw-r--r--apps/plugins/fractals/fractal.h2
-rw-r--r--apps/plugins/imageviewer/image_decoder.c5
-rw-r--r--apps/plugins/imageviewer/imageviewer.c42
-rw-r--r--apps/plugins/imageviewer/imageviewer.h14
-rw-r--r--apps/plugins/imageviewer/imageviewer_button.h6
-rw-r--r--apps/plugins/imageviewer/jpeg/yuv2rgb.c2
-rw-r--r--apps/plugins/imageviewer/ppm/ppm_decoder.c2
-rw-r--r--apps/plugins/invadrox.c2
-rw-r--r--apps/plugins/jackpot.c9
-rw-r--r--apps/plugins/jewels.c6
-rw-r--r--apps/plugins/keybox.c3
-rw-r--r--apps/plugins/keyremap.c165
-rw-r--r--apps/plugins/lamp.c22
-rw-r--r--apps/plugins/lastfm_scrobbler.c583
-rw-r--r--apps/plugins/lastfm_scrobbler_viewer.c1033
-rw-r--r--apps/plugins/lib/SOURCES6
-rw-r--r--apps/plugins/lib/bmp_smooth_scale.c2
-rw-r--r--apps/plugins/lib/helper.c48
-rw-r--r--apps/plugins/lib/helper.h20
-rw-r--r--apps/plugins/lib/highscore.c9
-rw-r--r--apps/plugins/lib/id3.c (renamed from lib/x1000-installer/test_lib/core_alloc.h)40
-rw-r--r--apps/plugins/lib/id3.h (renamed from lib/x1000-installer/test/test.h)23
-rw-r--r--apps/plugins/lib/mul_id3.c174
-rw-r--r--apps/plugins/lib/mul_id3.h27
-rw-r--r--apps/plugins/lib/osd.c8
-rw-r--r--apps/plugins/lib/overlay.c5
-rw-r--r--apps/plugins/lib/playback_control.c20
-rw-r--r--apps/plugins/lib/pluginlib_bmp.c2
-rw-r--r--apps/plugins/lib/printcell_helper.c299
-rw-r--r--apps/plugins/lib/printcell_helper.h68
-rw-r--r--apps/plugins/lib/wrappers.h1
-rw-r--r--apps/plugins/lib/xlcd_scroll.c4
-rw-r--r--apps/plugins/logo.c14
-rw-r--r--apps/plugins/lrcplayer.c36
-rw-r--r--apps/plugins/lua/include_lua/playlist.lua2
-rw-r--r--apps/plugins/lua/rocklib.c15
-rw-r--r--apps/plugins/lua/rocklib_events.c6
-rw-r--r--apps/plugins/lua/rocklib_img.c2
-rw-r--r--apps/plugins/main_menu_config.c2
-rw-r--r--apps/plugins/matrix.c9
-rw-r--r--apps/plugins/maze.c20
-rw-r--r--apps/plugins/mazezam.c9
-rw-r--r--apps/plugins/metronome.c6
-rw-r--r--apps/plugins/mikmod/mikmod.c21
-rw-r--r--apps/plugins/mosaique.c11
-rw-r--r--apps/plugins/mpegplayer/libmpeg2/idct_arm.S6
-rw-r--r--apps/plugins/mpegplayer/libmpeg2/idct_armv6.S7
-rw-r--r--apps/plugins/mpegplayer/mpeg_misc.h24
-rw-r--r--apps/plugins/mpegplayer/mpeg_settings.c22
-rw-r--r--apps/plugins/mpegplayer/mpegplayer.c5
-rw-r--r--apps/plugins/open_plugins.c73
-rw-r--r--apps/plugins/oscilloscope.c16
-rw-r--r--apps/plugins/otp.c17
-rwxr-xr-xapps/plugins/pacbox/pacbox.c18
-rw-r--r--apps/plugins/pdbox/PDa/src/m_glob.c2
-rw-r--r--apps/plugins/pdbox/PDa/src/m_obj.c3
-rw-r--r--apps/plugins/pdbox/pdbox.c2
-rw-r--r--apps/plugins/pegbox.c4
-rw-r--r--apps/plugins/periodic_table.c1
-rw-r--r--apps/plugins/pictureflow/pictureflow.c596
-rw-r--r--apps/plugins/pitch_detector.c11
-rw-r--r--apps/plugins/plasma.c17
-rw-r--r--apps/plugins/playing_time.c387
-rw-r--r--apps/plugins/pong.c7
-rw-r--r--apps/plugins/properties.c293
-rw-r--r--apps/plugins/puzzles/rockbox.c15
-rw-r--r--apps/plugins/random_folder_advance_config.c3
-rw-r--r--apps/plugins/rb_info.c40
-rw-r--r--apps/plugins/resistor.c18
-rw-r--r--apps/plugins/reversi/reversi-gui.c4
-rw-r--r--apps/plugins/robotfindskitten.c6
-rw-r--r--apps/plugins/rockblox.c14
-rw-r--r--apps/plugins/rockblox1d.c7
-rw-r--r--apps/plugins/rockboy/menu.c22
-rw-r--r--apps/plugins/rockboy/rockboy.c5
-rw-r--r--apps/plugins/rocklife.c12
-rw-r--r--apps/plugins/rockpaint.c24
-rw-r--r--apps/plugins/sdl/SDL_mixer/timidity/playmidi.c2
-rw-r--r--apps/plugins/sdl/main.c7
-rw-r--r--apps/plugins/sdl/src/audio/rockbox/SDL_rockboxaudio.c38
-rw-r--r--apps/plugins/shopper.c3
-rw-r--r--apps/plugins/shortcuts/shortcuts_view.c67
-rw-r--r--apps/plugins/sliding_puzzle.c4
-rw-r--r--apps/plugins/snake.c4
-rw-r--r--apps/plugins/snake2.c6
-rw-r--r--apps/plugins/snow.c8
-rw-r--r--apps/plugins/sokoban.c2
-rw-r--r--apps/plugins/solitaire.c4
-rw-r--r--apps/plugins/spacerocks.c19
-rw-r--r--apps/plugins/speedread.c24
-rw-r--r--apps/plugins/star.c4
-rw-r--r--apps/plugins/starfield.c18
-rw-r--r--apps/plugins/stats.c10
-rw-r--r--apps/plugins/sudoku/sudoku.c4
-rw-r--r--apps/plugins/superdom.c3
-rw-r--r--apps/plugins/tagcache/SOURCES2
-rw-r--r--apps/plugins/tagcache/tagcache.c1021
-rw-r--r--apps/plugins/tagcache/tagcache.h25
-rw-r--r--apps/plugins/tagcache/tagcache.make30
-rw-r--r--apps/plugins/test_codec.c2
-rw-r--r--apps/plugins/test_disk.c6
-rw-r--r--apps/plugins/test_fps.c8
-rw-r--r--apps/plugins/test_gfx.c8
-rw-r--r--apps/plugins/test_grey.c8
-rw-r--r--apps/plugins/test_sampr.c2
-rw-r--r--apps/plugins/test_usb.c13
-rw-r--r--apps/plugins/test_viewports.c4
-rw-r--r--apps/plugins/text_editor.c3
-rw-r--r--apps/plugins/text_viewer/tv_menu.c92
-rw-r--r--apps/plugins/theme_remove.c2
-rw-r--r--apps/plugins/vbrfix.c4
-rw-r--r--apps/plugins/viewers.config1
-rw-r--r--apps/plugins/vu_meter.c19
-rw-r--r--apps/plugins/wormlet.c21
-rw-r--r--apps/plugins/xobox.c11
-rw-r--r--apps/plugins/xworld/engine.c2
-rw-r--r--apps/plugins/xworld/sys.c24
-rw-r--r--apps/plugins/zxbox/spmain.c12
-rw-r--r--apps/radio/presets.c28
-rw-r--r--apps/radio/radio.c5
-rw-r--r--apps/radio/radio_skin.c16
-rw-r--r--apps/radio/radioart.c4
-rw-r--r--apps/rbcodec_helpers.c7
-rw-r--r--apps/recorder/albumart.c106
-rw-r--r--apps/recorder/albumart.h6
-rw-r--r--apps/recorder/jpeg_idct_arm.S12
-rw-r--r--apps/recorder/keyboard.c12
-rw-r--r--apps/recorder/pcm_record.c13
-rw-r--r--apps/recorder/recording.c11
-rw-r--r--apps/recorder/resize.c2
-rw-r--r--apps/root_menu.c119
-rw-r--r--apps/screen_access.c2
-rw-r--r--apps/screen_access.h1
-rw-r--r--apps/screens.c184
-rw-r--r--apps/screens.h11
-rw-r--r--apps/settings.c717
-rw-r--r--apps/settings.h28
-rw-r--r--apps/settings_list.c271
-rw-r--r--apps/settings_list.h21
-rw-r--r--apps/shortcuts.c56
-rw-r--r--apps/status.h2
-rw-r--r--apps/tagcache.c1350
-rw-r--r--apps/tagcache.h82
-rw-r--r--apps/tagnavi.config9
-rw-r--r--apps/tagtree.c677
-rw-r--r--apps/tagtree.h9
-rw-r--r--apps/talk.c363
-rw-r--r--apps/talk.h7
-rw-r--r--apps/tree.c414
-rw-r--r--apps/tree.h32
-rw-r--r--apps/voice_thread.c2
-rw-r--r--bootloader/x1000/boot.c2
-rw-r--r--bootloader/x1000/main.c14
-rw-r--r--bootloader/x1000/recovery.c1
-rw-r--r--bootloader/x1000/utils.c107
-rw-r--r--bootloader/x1000/x1000bootloader.h6
-rw-r--r--docs/CREDITS6
-rw-r--r--docs/LICENSES22
-rw-r--r--docs/PLUGIN_API10
-rw-r--r--firmware/SOURCES80
-rw-r--r--firmware/asm/arm/corelock.c4
-rw-r--r--firmware/asm/arm/lcd-as-memframe.S4
-rw-r--r--firmware/asm/arm/memcpy.S20
-rw-r--r--firmware/asm/arm/memmove.S20
-rw-r--r--firmware/asm/arm/memset.S26
-rw-r--r--firmware/asm/arm/memset16.S20
-rw-r--r--firmware/asm/arm/thread.c6
-rw-r--r--firmware/backlight.c86
-rw-r--r--firmware/buflib_malloc.c263
-rw-r--r--firmware/buflib_mempool.c (renamed from firmware/buflib.c)534
-rw-r--r--firmware/chunk_alloc.c319
-rw-r--r--firmware/common/diacritic.c3
-rw-r--r--firmware/common/dircache.c78
-rw-r--r--firmware/common/disk.c203
-rw-r--r--firmware/common/file_internal.c1
-rw-r--r--firmware/common/linked_list.c53
-rw-r--r--firmware/common/multiboot.c6
-rw-r--r--firmware/common/pathfuncs.c32
-rw-r--r--firmware/common/rectangle.c141
-rw-r--r--firmware/common/strlcat.c19
-rw-r--r--firmware/common/strlcpy.c64
-rw-r--r--firmware/common/strmemccpy.c38
-rw-r--r--firmware/common/strnatcmp.c16
-rw-r--r--firmware/common/strptokspn.c77
-rw-r--r--firmware/common/structec.c193
-rw-r--r--firmware/common/unicode.c35
-rw-r--r--firmware/common/zip.c25
-rw-r--r--firmware/core_alloc.c60
-rw-r--r--firmware/drivers/ata.c45
-rw-r--r--firmware/drivers/audio/eros_qn_codec.c23
-rw-r--r--firmware/drivers/button.c210
-rw-r--r--firmware/drivers/fat.c2
-rw-r--r--firmware/drivers/lcd-16bit-common.c675
-rw-r--r--firmware/drivers/lcd-16bit-vert.c214
-rw-r--r--firmware/drivers/lcd-16bit.c213
-rw-r--r--firmware/drivers/lcd-1bit-vert.c393
-rw-r--r--firmware/drivers/lcd-24bit.c436
-rw-r--r--firmware/drivers/lcd-2bit-horz.c441
-rw-r--r--firmware/drivers/lcd-2bit-vert.c447
-rw-r--r--firmware/drivers/lcd-2bit-vi.c449
-rw-r--r--firmware/drivers/lcd-bitmap-common.c344
-rw-r--r--firmware/drivers/lcd-color-common.c188
-rw-r--r--firmware/drivers/lcd-scroll.c14
-rw-r--r--firmware/drivers/rtc/rtc_pcf50605.c7
-rw-r--r--firmware/drivers/tuner/si4700.c2
-rw-r--r--firmware/drivers/usb-designware.c2
-rw-r--r--firmware/events.c97
-rw-r--r--firmware/export/ata.h3
-rw-r--r--firmware/export/audio.h1
-rw-r--r--firmware/export/backlight.h6
-rw-r--r--firmware/export/config.h57
-rw-r--r--firmware/export/config/fiiom3k.h1
-rw-r--r--firmware/export/config/ipod6g.h8
-rw-r--r--firmware/export/config/mrobe500.h5
-rw-r--r--firmware/export/config/sansaclipplus.h1
-rw-r--r--firmware/export/config/sansaconnect.h3
-rw-r--r--firmware/export/disk.h3
-rw-r--r--firmware/export/eros_qn_codec.h2
-rw-r--r--firmware/export/font.h4
-rw-r--r--firmware/export/i2c-coldfire.h2
-rw-r--r--firmware/export/i2c-rk27xx.h2
-rw-r--r--firmware/export/i2c-s5l8700.h2
-rw-r--r--firmware/export/i2c-s5l8702.h2
-rw-r--r--firmware/export/i2c.h4
-rw-r--r--firmware/export/jz4740.h3
-rw-r--r--firmware/export/lcd.h4
-rw-r--r--firmware/export/mv.h9
-rw-r--r--firmware/export/pathfuncs.h2
-rw-r--r--firmware/export/pcm_sampr.h6
-rw-r--r--firmware/export/powermgmt.h8
-rw-r--r--firmware/export/rectangle.h75
-rw-r--r--firmware/export/system.h6
-rw-r--r--firmware/font.c164
-rw-r--r--firmware/general.c4
-rw-r--r--firmware/include/buflib.h595
-rw-r--r--firmware/include/buflib_malloc.h65
-rw-r--r--firmware/include/buflib_mempool.h97
-rw-r--r--firmware/include/chunk_alloc.h71
-rw-r--r--firmware/include/core_alloc.h48
-rw-r--r--firmware/include/dircache_redirect.h6
-rw-r--r--firmware/include/fs_defines.h12
-rw-r--r--firmware/include/linked_list.h38
-rw-r--r--firmware/include/rbendian.h237
-rw-r--r--firmware/include/string-extra.h1
-rw-r--r--firmware/include/strmemccpy.h (renamed from firmware/export/structec.h)21
-rw-r--r--firmware/include/strptokspn_r.h (renamed from lib/x1000-installer/test_lib/pathfuncs.h)21
-rw-r--r--firmware/kernel/include/tick.h2
-rw-r--r--firmware/kernel/thread.c2
-rw-r--r--firmware/libc/include/string.h4
-rw-r--r--firmware/libc/memccpy.c119
-rw-r--r--firmware/libc/strcspn.c45
-rw-r--r--firmware/libc/strtok.c63
-rw-r--r--firmware/linuxboot.c9
-rw-r--r--firmware/panic.c6
-rw-r--r--firmware/pcm.c4
-rw-r--r--firmware/powermgmt.c23
-rw-r--r--firmware/rolo.c2
-rw-r--r--firmware/scroll_engine.c36
-rw-r--r--firmware/target/arm/ata-as-arm.S32
-rw-r--r--firmware/target/arm/ata-nand-telechips.c2
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/system-gigabeat-s.c2
-rw-r--r--firmware/target/arm/imx31/i2c-imx31.c2
-rw-r--r--firmware/target/arm/imx31/i2c-imx31.h2
-rw-r--r--firmware/target/arm/ipod/button-target.h9
-rw-r--r--firmware/target/arm/ipod/video/lcd-as-video.S26
-rw-r--r--firmware/target/arm/pcm-telechips.c6
-rw-r--r--firmware/target/arm/pp/pcm-pp.c8
-rw-r--r--firmware/target/arm/s3c2440/i2c-s3c2440.h2
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/button-target.h9
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/button-target.h9
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c2
-rw-r--r--firmware/target/arm/tms320dm320/i2c-dm320.h2
-rw-r--r--firmware/target/arm/tms320dm320/mrobe-500/lcd-mr500.c4
-rw-r--r--firmware/target/hosted/filesystem-app.c9
-rw-r--r--firmware/target/hosted/sdl/lcd-sdl.c6
-rw-r--r--firmware/target/hosted/sdl/thread-sdl.c2
-rw-r--r--firmware/target/mips/exception-mips.S181
-rw-r--r--firmware/target/mips/ingenic_jz47xx/app.lds34
-rw-r--r--firmware/target/mips/ingenic_jz47xx/boot.lds6
-rw-r--r--firmware/target/mips/ingenic_jz47xx/crt0.S184
-rw-r--r--firmware/target/mips/ingenic_jz47xx/debug-jz4760.c8
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4740.c76
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4760.c48
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-target.h1
-rw-r--r--firmware/target/mips/ingenic_x1000/app.lds50
-rw-r--r--firmware/target/mips/ingenic_x1000/boot-x1000.c17
-rw-r--r--firmware/target/mips/ingenic_x1000/boot-x1000.h4
-rw-r--r--firmware/target/mips/ingenic_x1000/clk-x1000.h13
-rw-r--r--firmware/target/mips/ingenic_x1000/crt0.S158
-rw-r--r--firmware/target/mips/ingenic_x1000/dma-x1000.h2
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c38
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c8
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/gpio-target.h26
-rw-r--r--firmware/target/mips/ingenic_x1000/gpio-x1000.c10
-rw-r--r--firmware/target/mips/ingenic_x1000/gpio-x1000.h11
-rw-r--r--firmware/target/mips/ingenic_x1000/i2c-x1000.h2
-rw-r--r--firmware/target/mips/ingenic_x1000/installer-x1000.c25
-rw-r--r--firmware/target/mips/ingenic_x1000/installer-x1000.h1
-rw-r--r--firmware/target/mips/ingenic_x1000/lcd-x1000.c3
-rw-r--r--firmware/target/mips/ingenic_x1000/nand-x1000.c241
-rw-r--r--firmware/target/mips/ingenic_x1000/nand-x1000.h109
-rw-r--r--firmware/target/mips/ingenic_x1000/pcm-x1000.c19
-rw-r--r--firmware/target/mips/ingenic_x1000/spl-nand-x1000.c4
-rw-r--r--firmware/target/mips/ingenic_x1000/spl-start.S2
-rw-r--r--firmware/target/mips/ingenic_x1000/spl-x1000.c7
-rw-r--r--firmware/target/mips/ingenic_x1000/spl.lds3
-rw-r--r--firmware/target/mips/ingenic_x1000/system-target.h3
-rw-r--r--firmware/target/mips/ingenic_x1000/system-x1000.c48
-rw-r--r--firmware/target/mips/mmu-mips.h6
-rw-r--r--firmware/target/mips/system-mips.c175
-rw-r--r--firmware/target/mips/system-mips.h (renamed from lib/x1000-installer/include/xf_error.h)35
-rw-r--r--firmware/usb.c44
-rw-r--r--firmware/usbstack/usb_core.c50
-rw-r--r--firmware/usbstack/usb_storage.c6
-rw-r--r--lib/arm_support/support-arm.S2
-rw-r--r--lib/microtar/src/microtar.c13
-rw-r--r--lib/rbcodec/SOURCES1
-rw-r--r--lib/rbcodec/codecs/SOURCES2
-rw-r--r--lib/rbcodec/codecs/aac.c58
-rw-r--r--lib/rbcodec/codecs/alac.c73
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/C64.c198
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/CIA.c93
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/CPU.c423
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/MEM.c132
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/SID.c276
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/SID.h824
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/VIC.c64
-rw-r--r--lib/rbcodec/codecs/cRSID/C64/libcRSIDc64.h172
-rw-r--r--lib/rbcodec/codecs/cRSID/README.rockbox19
-rw-r--r--lib/rbcodec/codecs/cRSID/README.txt39
-rw-r--r--lib/rbcodec/codecs/cRSID/SOURCES1
-rw-r--r--lib/rbcodec/codecs/cRSID/cRSID.make (renamed from lib/x1000-installer/x1000-installer.make)17
-rw-r--r--lib/rbcodec/codecs/cRSID/host/audio.c62
-rw-r--r--lib/rbcodec/codecs/cRSID/host/file.c60
-rw-r--r--lib/rbcodec/codecs/cRSID/libcRSID.c134
-rw-r--r--lib/rbcodec/codecs/cRSID/libcRSID.h59
-rw-r--r--lib/rbcodec/codecs/codecs.h32
-rw-r--r--lib/rbcodec/codecs/codecs.make5
-rw-r--r--lib/rbcodec/codecs/demac/libdemac/udiv32_arm.S2
-rw-r--r--lib/rbcodec/codecs/demac/libdemac/vector_math16_armv6.h26
-rw-r--r--lib/rbcodec/codecs/libfaad/common.h16
-rw-r--r--lib/rbcodec/codecs/libffmpegFLAC/decoder.c19
-rw-r--r--lib/rbcodec/codecs/libgme/blip_buffer.c2
-rw-r--r--lib/rbcodec/codecs/libm4a/demux.c149
-rw-r--r--lib/rbcodec/codecs/libm4a/m4a.c75
-rw-r--r--lib/rbcodec/codecs/libm4a/m4a.h17
-rw-r--r--lib/rbcodec/codecs/libmusepack/mpc_decoder.c2
-rw-r--r--lib/rbcodec/codecs/libopus/ogg/framing.c5
-rw-r--r--lib/rbcodec/codecs/libtta/filter_arm.S4
-rw-r--r--lib/rbcodec/codecs/mpa.c168
-rw-r--r--lib/rbcodec/codecs/sid.c1308
-rw-r--r--lib/rbcodec/dsp/dsp_arm.S6
-rw-r--r--lib/rbcodec/dsp/dsp_arm_v6.S5
-rw-r--r--lib/rbcodec/dsp/dsp_core.c47
-rw-r--r--lib/rbcodec/dsp/dsp_core.h7
-rw-r--r--lib/rbcodec/dsp/dsp_misc.c12
-rw-r--r--lib/rbcodec/dsp/dsp_proc_entry.h4
-rw-r--r--lib/rbcodec/dsp/dsp_sample_input.c107
-rw-r--r--lib/rbcodec/dsp/dsp_sample_io.c117
-rw-r--r--lib/rbcodec/dsp/dsp_sample_io.h5
-rw-r--r--lib/rbcodec/dsp/dsp_sample_output.c2
-rw-r--r--lib/rbcodec/dsp/eq.c2
-rw-r--r--lib/rbcodec/dsp/pbe.c2
-rw-r--r--lib/rbcodec/dsp/resample.c14
-rw-r--r--lib/rbcodec/dsp/resample.h26
-rw-r--r--lib/rbcodec/dsp/surround.c57
-rw-r--r--lib/rbcodec/dsp/surround.h2
-rw-r--r--lib/rbcodec/dsp/tdspeed.c11
-rw-r--r--lib/rbcodec/dsp/tdspeed.h1
-rw-r--r--lib/rbcodec/metadata/ape.c36
-rw-r--r--lib/rbcodec/metadata/metadata.h3
-rw-r--r--lib/rbcodec/metadata/metadata_common.c27
-rw-r--r--lib/rbcodec/metadata/mp4.c44
-rw-r--r--lib/rbcodec/metadata/replaygain.c2
-rw-r--r--lib/rbcodec/metadata/sid.c2
-rw-r--r--lib/rbcodec/metadata/vorbis.c1
-rw-r--r--lib/rbcodec/platform.h11
-rw-r--r--lib/rbcodec/test/SOURCES4
-rw-r--r--lib/rbcodec/test/rbcodecconfig.h2
-rw-r--r--lib/skin_parser/skin_parser.h15
-rw-r--r--lib/tlsf/Changelog39
-rw-r--r--lib/tlsf/README2
-rw-r--r--lib/tlsf/libtlsf.make2
-rw-r--r--lib/tlsf/src/tlsf.c299
-rw-r--r--lib/tlsf/src/tlsf.h4
-rw-r--r--lib/unwarminder/safe_read.S4
-rw-r--r--lib/x1000-installer/.gitignore5
-rw-r--r--lib/x1000-installer/Makefile82
-rw-r--r--lib/x1000-installer/SOURCES6
-rw-r--r--lib/x1000-installer/include/xf_flashmap.h91
-rw-r--r--lib/x1000-installer/include/xf_nandio.h130
-rw-r--r--lib/x1000-installer/include/xf_package.h65
-rw-r--r--lib/x1000-installer/include/xf_stream.h64
-rw-r--r--lib/x1000-installer/include/xf_update.h53
-rw-r--r--lib/x1000-installer/src/xf_error.c42
-rw-r--r--lib/x1000-installer/src/xf_flashmap.c327
-rw-r--r--lib/x1000-installer/src/xf_nandio.c295
-rw-r--r--lib/x1000-installer/src/xf_package.c264
-rw-r--r--lib/x1000-installer/src/xf_stream.c211
-rw-r--r--lib/x1000-installer/src/xf_update.c149
-rw-r--r--lib/x1000-installer/test/data/lines_shuffled.txt108
-rw-r--r--lib/x1000-installer/test/data/lines_sorted.txt36
-rw-r--r--lib/x1000-installer/test/main.c86
-rw-r--r--lib/x1000-installer/test/test_flashmap.c140
-rw-r--r--lib/x1000-installer/test/test_stream.c108
-rw-r--r--lib/x1000-installer/test_lib/core_alloc.c72
-rw-r--r--lib/x1000-installer/test_lib/fakenand.c270
-rw-r--r--lib/x1000-installer/test_lib/file.c11
-rw-r--r--lib/x1000-installer/test_lib/file.h18
-rw-r--r--lib/x1000-installer/test_lib/md5.c245
-rw-r--r--lib/x1000-installer/test_lib/md5.h18
-rw-r--r--lib/x1000-installer/test_lib/nand-x1000.h112
-rw-r--r--lib/x1000-installer/test_lib/pathfuncs.c130
-rw-r--r--lib/x1000-installer/test_lib/strlcpy.c50
-rw-r--r--lib/x1000-installer/test_lib/strlcpy.h4
-rw-r--r--lib/x1000-installer/test_lib/system.h10
-rw-r--r--manual/Makefile2
-rw-r--r--manual/appendix/config_file_options.tex9
-rw-r--r--manual/appendix/file_formats.tex5
-rw-r--r--manual/configure_rockbox/playback_options.tex13
-rw-r--r--manual/configure_rockbox/playlist_options.tex6
-rwxr-xr-xmanual/configure_rockbox/system_options.tex35
-rw-r--r--manual/main_menu/main.tex10
-rw-r--r--manual/platform/keymap-fiiom3k.tex4
-rw-r--r--manual/platform/keymap-sansaclip.tex10
-rw-r--r--manual/plugins/2048.tex3
-rw-r--r--manual/plugins/alarmclock.tex6
-rw-r--r--manual/plugins/bounce.tex6
-rw-r--r--manual/plugins/bubbles.tex6
-rw-r--r--manual/plugins/calendar.tex6
-rw-r--r--manual/plugins/chessbox.tex2
-rw-r--r--manual/plugins/clix.tex3
-rw-r--r--manual/plugins/clock.tex6
-rw-r--r--manual/plugins/codebuster.tex3
-rw-r--r--manual/plugins/cube.tex4
-rw-r--r--manual/plugins/demystify.tex6
-rw-r--r--manual/plugins/dice.tex3
-rw-r--r--manual/plugins/fire.tex3
-rw-r--r--manual/plugins/flipit.tex2
-rw-r--r--manual/plugins/fractals.tex2
-rw-r--r--manual/plugins/imageviewer.tex4
-rw-r--r--manual/plugins/jackpot.tex3
-rw-r--r--manual/plugins/jewels.tex4
-rw-r--r--manual/plugins/lamp.tex3
-rw-r--r--manual/plugins/logo.tex6
-rw-r--r--manual/plugins/maze.tex16
-rw-r--r--manual/plugins/mazezam.tex8
-rw-r--r--manual/plugins/metronome.tex3
-rw-r--r--manual/plugins/mosaic.tex7
-rw-r--r--manual/plugins/oscilloscope.tex4
-rw-r--r--manual/plugins/pegbox.tex2
-rw-r--r--manual/plugins/periodic_table.tex3
-rw-r--r--manual/plugins/pictureflow.tex35
-rw-r--r--manual/plugins/plasma.tex5
-rw-r--r--manual/plugins/robotfindskitten.tex3
-rw-r--r--manual/plugins/rockblox.tex2
-rw-r--r--manual/plugins/rockblox1d.tex3
-rw-r--r--manual/plugins/rocklife.tex3
-rw-r--r--manual/plugins/sliding.tex2
-rw-r--r--manual/plugins/snake.tex1
-rw-r--r--manual/plugins/snake2.tex2
-rw-r--r--manual/plugins/snow.tex5
-rw-r--r--manual/plugins/sokoban.tex2
-rw-r--r--manual/plugins/solitaire.tex2
-rw-r--r--manual/plugins/spacerocks.tex8
-rw-r--r--manual/plugins/star.tex2
-rw-r--r--manual/plugins/starfield.tex6
-rw-r--r--manual/plugins/stats.tex5
-rw-r--r--manual/plugins/wormlet.tex4
-rw-r--r--manual/plugins/xobox.tex2
-rw-r--r--manual/rockbox_interface/browsing_and_playing.tex45
-rw-r--r--manual/rockbox_interface/hotkeys.tex11
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-112x64x1.pngbin790 -> 0 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-128x128x16.pngbin9366 -> 13375 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-128x128x2.pngbin1300 -> 5669 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-128x64x1-clip.pngbin783 -> 3338 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-128x64x1-xduoox3.pngbin872 -> 3320 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-128x96x16.pngbin5868 -> 9895 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-128x96x2.pngbin792 -> 4558 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-132x80x16.pngbin5865 -> 8318 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-138x110x2.pngbin1083 -> 5160 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-160x128x1.pngbin849 -> 4686 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-160x128x16.pngbin10832 -> 15520 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-160x128x2.pngbin1290 -> 5912 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-176x132x16.pngbin12159 -> 17959 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-176x220x16.pngbin14674 -> 22168 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-220x176x16.pngbin15717 -> 23683 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-240x320x16.pngbin26450 -> 45124 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-320x240x16.pngbin25275 -> 42386 bytes
-rw-r--r--manual/rockbox_interface/images/ss-context-menu-96x96x16-sansaclipzip.pngbin6943 -> 3231 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-112x64x1.pngbin424 -> 0 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-128x128x16.pngbin8714 -> 11006 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-128x128x2.pngbin940 -> 4125 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-128x64x1-clip.pngbin690 -> 2928 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-128x64x1-xduoox3.pngbin535 -> 2953 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-128x96x16.pngbin5463 -> 8093 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-128x96x2.pngbin742 -> 3242 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-132x80x16.pngbin5545 -> 7637 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-138x110x2.pngbin980 -> 4091 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-160x128x1.pngbin754 -> 3512 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-160x128x16.pngbin10062 -> 13092 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-160x128x2-h100.pngbin1060 -> 4269 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-160x128x2.pngbin1101 -> 4378 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-176x132x16.pngbin11681 -> 15333 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-176x220x16.pngbin13762 -> 18358 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-220x176x16.pngbin14692 -> 20471 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-240x320x16.pngbin25203 -> 38942 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-320x240x16.pngbin23840 -> 38510 bytes
-rw-r--r--manual/rockbox_interface/images/ss-playlist-menu-96x96x16-sansaclipzip.pngbin6322 -> 7185 bytes
-rw-r--r--manual/rockbox_interface/tagcache.tex9
-rw-r--r--manual/rockbox_interface/wps.tex10
-rw-r--r--manual/working_with_playlists/main.tex103
-rw-r--r--tools/bmp2rb.c18
-rw-r--r--tools/checkwps/SOURCES1
-rwxr-xr-xtools/configure18
-rw-r--r--tools/database/SOURCES2
-rw-r--r--tools/database/database.c14
-rw-r--r--tools/functions.make12
-rwxr-xr-xtools/genlang4
-rw-r--r--tools/makesrc.inc2
-rwxr-xr-xtools/rockboxdev.sh164
-rw-r--r--tools/toolchain-patches/crosstool-ng-1.13.2.diff13
-rw-r--r--tools/toolchain-patches/glibc-220-make44.patch224
-rw-r--r--tools/toolchain-patches/glibc-225-make44.patch228
-rw-r--r--tools/voicefont.c29
-rw-r--r--utils/atj2137/atjboottool/Makefile2
-rw-r--r--utils/atj2137/atjboottool/atj_tables.c18
-rw-r--r--utils/atj2137/atjboottool/atj_tables.h20
-rw-r--r--utils/atj2137/atjboottool/atjboottool.c37
-rw-r--r--utils/atj2137/atjboottool/fw.c115
-rw-r--r--utils/atj2137/atjboottool/fw.h2
-rw-r--r--utils/atj2137/atjboottool/fwu.c628
-rw-r--r--utils/hwstub/include/hwstub.hpp8
-rw-r--r--utils/hwstub/include/hwstub_usb.hpp5
-rw-r--r--utils/hwstub/lib/hwstub_uri.cpp60
-rw-r--r--utils/hwstub/lib/hwstub_usb.cpp26
-rw-r--r--utils/hwstub/stub/asm/mips/system.S27
-rw-r--r--utils/hwstub/stub/atj213x/Makefile2
-rw-r--r--utils/hwstub/stub/atj213x/crt0.S63
-rw-r--r--utils/hwstub/stub/atj213x/hwstub.lds5
-rw-r--r--utils/hwstub/stub/hwstub.make2
-rw-r--r--utils/ipodpatcher/Makefile3
-rw-r--r--utils/rbutilqt/CMakeLists.txt66
-rw-r--r--utils/rbutilqt/base/ziputil.cpp6
-rw-r--r--utils/rbutilqt/base/ziputil.h6
-rw-r--r--utils/rbutilqt/rbutil.ini2
-rw-r--r--utils/regtools/desc/regs-atj213x-v1.xml1102
-rw-r--r--utils/regtools/desc/regs-atj213x.xml4811
-rw-r--r--wps/WPSLIST2
-rw-r--r--wps/cabbiev2.112x64x1.wps2
-rw-r--r--wps/cabbiev2.128x128x16.wps4
-rw-r--r--wps/cabbiev2.128x128x2.wps4
-rw-r--r--wps/cabbiev2.128x160x16.wps4
-rw-r--r--wps/cabbiev2.128x64x1.wps2
-rw-r--r--wps/cabbiev2.128x96x16.wps4
-rw-r--r--wps/cabbiev2.128x96x2.wps2
-rw-r--r--wps/cabbiev2.132x80x16.wps4
-rw-r--r--wps/cabbiev2.138x110x2.wps4
-rw-r--r--wps/cabbiev2.160x128x1.wps2
-rw-r--r--wps/cabbiev2.160x128x16.wps4
-rw-r--r--wps/cabbiev2.160x128x2.wps4
-rw-r--r--wps/cabbiev2.176x132x16.wps4
-rw-r--r--wps/cabbiev2.176x220x16.wps4
-rw-r--r--wps/cabbiev2.220x176x16.wps4
-rw-r--r--wps/cabbiev2.240x320x16.mini2440.wps4
-rw-r--r--wps/cabbiev2.240x320x16.wps16
-rw-r--r--wps/cabbiev2.240x400x16.wps4
-rw-r--r--wps/cabbiev2.320x240x16.mrobe500.wps2
-rw-r--r--wps/cabbiev2.320x240x16.wps4
-rw-r--r--wps/cabbiev2.320x480x16.wps4
-rw-r--r--wps/cabbiev2.360x400x16.wps8
-rw-r--r--wps/cabbiev2.400x240x16.wps4
-rw-r--r--wps/cabbiev2.480x800x16.wps4
-rw-r--r--wps/cabbiev2.800x480x16.wps4
-rw-r--r--wps/cabbiev2.96x96x16.wps6
747 files changed, 32822 insertions, 22417 deletions
diff --git a/apps/abrepeat.h b/apps/abrepeat.h
index f7ee65247c..4d2c4ea001 100644
--- a/apps/abrepeat.h
+++ b/apps/abrepeat.h
@@ -20,9 +20,38 @@
****************************************************************************/
#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 */
diff --git a/apps/action.c b/apps/action.c
index 9ef10936f2..208fea4a97 100644
--- a/apps/action.c
+++ b/apps/action.c
@@ -34,6 +34,7 @@
#include "button.h"
#include "action.h"
#include "kernel.h"
+#include "core_alloc.h"
#include "splash.h"
#include "settings.h"
@@ -70,7 +71,7 @@ static action_last_t action_last =
.wait_for_release = false,
#ifndef DISABLE_ACTION_REMAP
- .core_keymap = NULL,
+ .key_remap = 0,
#endif
#ifdef HAVE_TOUCHSCREEN
@@ -124,7 +125,7 @@ static bool is_action_filtered(int action, unsigned int mask, int context)
{
case ACTION_NONE:
break;
-/*Actions that are not mapped will not turn on the backlight option NOUNMAPPED*/
+ /* Actions that are not mapped will not turn on the backlight */
case ACTION_UNKNOWN:
match = has_flag(mask, SEL_ACTION_NOUNMAPPED);
break;
@@ -132,15 +133,15 @@ static bool is_action_filtered(int action, unsigned int mask, int context)
case ACTION_FM_PLAY:
match = has_flag(mask, SEL_ACTION_PLAY);
break;
- //case ACTION_STD_PREVREPEAT: // seek not exempted outside of WPS
- //case ACTION_STD_NEXTREPEAT:
+ /* case ACTION_STD_PREVREPEAT:*/ /* seek not exempted outside of WPS */
+ /* case ACTION_STD_NEXTREPEAT: */
case ACTION_WPS_SEEKBACK:
case ACTION_WPS_SEEKFWD:
case ACTION_WPS_STOPSEEK:
match = has_flag(mask, SEL_ACTION_SEEK);
break;
- //case ACTION_STD_PREV: // skip/scrollwheel not exempted outside of WPS
- //case ACTION_STD_NEXT:
+ /* case ACTION_STD_PREV: */ /* skip/scrollwheel not */
+ /* case ACTION_STD_NEXT: */ /* exempted outside of WPS */
case ACTION_WPS_SKIPNEXT:
case ACTION_WPS_SKIPPREV:
case ACTION_FM_NEXT_PRESET:
@@ -148,8 +149,8 @@ static bool is_action_filtered(int action, unsigned int mask, int context)
match = has_flag(mask, SEL_ACTION_SKIP);
break;
#ifdef HAVE_VOLUME_IN_LIST
- case ACTION_LIST_VOLUP: // volume exempted outside of WPS if the device supports it
- case ACTION_LIST_VOLDOWN:
+ case ACTION_LIST_VOLUP: /* volume exempted outside of WPS */
+ case ACTION_LIST_VOLDOWN: /* ( if the device supports it )*/
#endif
case ACTION_WPS_VOLUP:
case ACTION_WPS_VOLDOWN:
@@ -587,13 +588,14 @@ static inline int get_next_context(const struct button_mapping *items, int i)
* for a more in-depth explanation
* places action into current_action
*/
+
static inline void action_code_lookup(action_last_t *last, action_cur_t *cur)
{
int action, i;
int context = cur->context;
cur->is_prebutton = false;
-#ifdef HAVE_LOCKED_ACTIONS
+#if !defined(HAS_BUTTON_HOLD) && !defined(BOOTLOADER)
/* This only applies to the first context, to allow locked contexts to
* specify a fall through to their non-locked version */
if (is_keys_locked())
@@ -601,17 +603,14 @@ static inline void action_code_lookup(action_last_t *last, action_cur_t *cur)
#endif
#ifndef DISABLE_ACTION_REMAP
- bool check_remap = (last->core_keymap != NULL);
/* attempt to look up the button in user supplied remap */
- if(check_remap && (context & CONTEXT_PLUGIN) == 0)
+ if(last->key_remap && (context & CONTEXT_PLUGIN) == 0)
{
-#if 0 /*Disable the REMOTE context for remap for now (BUTTON_REMOTE != 0)*/
if ((cur->button & BUTTON_REMOTE) != 0)
{
context |= CONTEXT_REMOTE;
}
-#endif
- cur->items = last->core_keymap;
+ cur->items = core_get_data(last->key_remap);
i = 0;
action = ACTION_UNKNOWN;
/* check the lut at the beginning for the desired context */
@@ -1001,7 +1000,8 @@ static inline int do_backlight(action_last_t *last, action_cur_t *cur, int actio
&& power_input_present());
#endif
/* skip if backlight on | incorrect context | SEL_ACTION_NOEXT + ext pwr */
- if ((cur->context == CONTEXT_FM || cur->context == CONTEXT_WPS) && bl_is_off)
+ if (bl_is_off && (cur->context == CONTEXT_FM || cur->context == CONTEXT_WPS ||
+ cur->context == CONTEXT_MAINMENU))
{
filtered = is_action_filtered(action, last->backlight_mask, cur->context);
bl_activate = !is_action_discarded(cur, filtered, &last->bl_filter_tick);
@@ -1193,66 +1193,88 @@ int get_action(int context, int timeout)
int action_set_keymap(struct button_mapping* core_keymap, int count)
{
+#ifdef DISABLE_ACTION_REMAP
+ (void)core_keymap;
+ (void)count;
+ return -1;
+#else
+ if (count <= 0 || core_keymap == NULL)
+ return action_set_keymap_handle(0, 0);
+
+ size_t keyremap_buf_size = count * sizeof(struct button_mapping);
+ int handle = core_alloc(keyremap_buf_size);
+ if (handle < 0)
+ return -6;
+ memcpy(core_get_data(handle), core_keymap, keyremap_buf_size);
+ return action_set_keymap_handle(handle, count);
+#endif
+}
+
+int action_set_keymap_handle(int handle, int count)
+{
#ifdef DISABLE_ACTION_REMAP
- count = -1;
+ (void)core_keymap;
+ (void)count;
+ return -1;
#else
- if (count > 0 && core_keymap != NULL) /* saf-tey checks :) */
+ /* free an existing remap */
+ action_last.key_remap = core_free(action_last.key_remap);
+
+ /* if clearing the remap, we're done */
+ if (count <= 0 || handle <= 0)
+ return 0;
+
+ /* validate the keymap */
+ struct button_mapping* core_keymap = core_get_data(handle);
+ struct button_mapping* entry = &core_keymap[count - 1];
+ if (entry->action_code != (int) CONTEXT_STOPSEARCHING ||
+ entry->button_code != BUTTON_NONE) /* check for sentinel at end*/
{
- int i = 0;
- struct button_mapping* entry = &core_keymap[count - 1];
- if (entry->action_code != (int) CONTEXT_STOPSEARCHING ||
- entry->button_code != BUTTON_NONE) /* check for sentinel at end*/
- {
- count = -1;
- }
+ /* missing sentinel entry */
+ return -1;
+ }
- while (count > 0 && /* check the lut at the beginning for invalid offsets */
- (entry = &core_keymap[i])->action_code != (int) CONTEXT_STOPSEARCHING)
- {
-
- if ((entry->action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED)
- {
- int firstbtn = entry->button_code;
- int endpos = firstbtn + entry->pre_button_code;
- if (firstbtn > count || firstbtn < i || endpos > count)
- {
- /* offset out of bounds */
- count = -2;
- break;
- }
+ /* check the lut at the beginning for invalid offsets */
+ for (int i = 0; i < count; ++i)
+ {
+ entry = &core_keymap[i];
+ if (entry->action_code == (int)CONTEXT_STOPSEARCHING)
+ break;
- if (core_keymap[endpos].button_code != BUTTON_NONE)
- {
- /* stop sentinel is not at end of action lut*/
- count = -3;
- }
- }
- else /* something other than a context remap in the lut */
+ if ((entry->action_code & CONTEXT_REMAPPED) == CONTEXT_REMAPPED)
+ {
+ int firstbtn = entry->button_code;
+ int endpos = firstbtn + entry->pre_button_code;
+ if (firstbtn > count || firstbtn < i || endpos > count)
{
- count = -4;
- break;
+ /* offset out of bounds */
+ return -2;
}
- i++;
-
- if (i >= count) /* no sentinel in the lut */
+ if (core_keymap[endpos].button_code != BUTTON_NONE)
{
- count = -5;
- break;
+ /* stop sentinel is not at end of action lut */
+ return -3;
}
}
+ else
+ {
+ /* something other than a context remap in the lut */
+ return -4;
+ }
- if (count <= 0)
- core_keymap = NULL;
- }
- else
-#endif
- {
- core_keymap = NULL;
+ if (i+1 >= count)
+ {
+ /* no sentinel in the lut */
+ return -5;
+ }
}
- action_last.core_keymap = core_keymap;
+
+ /* success */
+ action_last.key_remap = handle;
return count;
+#endif
}
int get_custom_action(int context,int timeout,
diff --git a/apps/action.h b/apps/action.h
index 35f08a3dbd..6e1278b33c 100644
--- a/apps/action.h
+++ b/apps/action.h
@@ -35,9 +35,8 @@
#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)
-#ifdef HAVE_LOCKED_ACTIONS
#define CONTEXT_LOCKED 0x04000000 /* flag to use alternate keymap when screen is locked */
-#endif
+
#define LAST_ITEM_IN_LIST { CONTEXT_STOPSEARCHING, BUTTON_NONE, BUTTON_NONE }
#define LAST_ITEM_IN_LIST__NEXTLIST(a) { a, BUTTON_NONE, BUTTON_NONE }
@@ -95,7 +94,7 @@ void set_selective_backlight_actions(bool selective, unsigned int mask,
enum {
CONTEXT_STD = 0,
/* These CONTEXT_ values were here before me,
- there values may have significance, so dont touch! */
+ their values may have significance, so dont touch! */
CONTEXT_WPS = 1,
CONTEXT_TREE = 2,
CONTEXT_RECORD = 3,
@@ -419,7 +418,7 @@ typedef struct
bool wait_for_release;
#ifndef DISABLE_ACTION_REMAP
- struct button_mapping* core_keymap;
+ int key_remap;
#endif
#ifdef HAVE_TOUCHSCREEN
@@ -449,7 +448,9 @@ bool action_userabort(int timeout);
const struct button_mapping* get_context_mapping(int context);
/* load a key map to allow buttons for actions to be remapped see: core_keymap */
-int action_set_keymap(struct button_mapping* core_button_map, int count);
+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
If button != NULL it will be set to the actual button code */
diff --git a/apps/apps.make b/apps/apps.make
index 6afcd12b5c..47b015bc92 100644
--- a/apps/apps.make
+++ b/apps/apps.make
@@ -24,7 +24,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 : < $< > $@
diff --git a/apps/bookmark.c b/apps/bookmark.c
index 70dbd8075d..2411ddb0ee 100644
--- a/apps/bookmark.c
+++ b/apps/bookmark.c
@@ -43,6 +43,9 @@
#include "file.h"
#include "pathfuncs.h"
+/*#define LOGF_ENABLE*/
+#include "logf.h"
+
#define MAX_BOOKMARKS 10
#define MAX_BOOKMARK_SIZE 350
#define RECENT_BOOKMARK_FILE ROCKBOX_DIR "/most-recent.bmark"
@@ -66,286 +69,289 @@ struct bookmark_list
#define BM_SPEED 0x02
/* bookmark values */
-static struct {
+struct resume_info{
+ const struct mp3entry *id3;
int resume_index;
unsigned long resume_offset;
int resume_seed;
- long resume_time;
+ long resume_elapsed;
int repeat_mode;
bool shuffle;
/* optional values */
int pitch;
int speed;
-} bm;
-
-static bool add_bookmark(const char* bookmark_file_name, const char* bookmark,
- bool most_recent);
-static char* create_bookmark(void);
-static bool delete_bookmark(const char* bookmark_file_name, int bookmark_id);
-static void say_bookmark(const char* bookmark,
- int bookmark_id, bool show_playlist_name);
-static bool play_bookmark(const char* bookmark);
-static bool generate_bookmark_file_name(const char *in);
-static bool parse_bookmark(const char *bookmark, const bool get_filenames, const bool strip_dir);
-static int buffer_bookmarks(struct bookmark_list* bookmarks, int first_line);
-static const char* get_bookmark_info(int list_index,
- void* data,
- char *buffer,
- size_t buffer_len);
-static int select_bookmark(const char* bookmark_file_name, bool show_dont_resume, char** selected_bookmark);
-static bool write_bookmark(bool create_bookmark_file, const char *bookmark);
-static int get_bookmark_count(const char* bookmark_file_name);
+};
-#define TEMP_BUF_SIZE (MAX_PATH + 1)
+/* Temp buffer used for reading, create_bookmark and filename creation */
+#define TEMP_BUF_SIZE (MAX(MAX_BOOKMARK_SIZE, MAX_PATH + 1))
static char global_temp_buffer[TEMP_BUF_SIZE];
-/* File name created by generate_bookmark_file_name */
-static char global_bookmark_file_name[MAX_PATH];
-static char global_read_buffer[MAX_BOOKMARK_SIZE];
-/* Bookmark created by create_bookmark*/
-static char global_bookmark[MAX_BOOKMARK_SIZE];
-/* Filename from parsed bookmark (can be made local where needed) */
-static char global_filename[MAX_PATH];
-/* ----------------------------------------------------------------------- */
-/* This is an interface function from the context menu. */
-/* Returns true on successful bookmark creation. */
-/* ----------------------------------------------------------------------- */
-bool bookmark_create_menu(void)
+static inline void get_hash(const char *key, uint32_t *hash, int len)
{
- return write_bookmark(true, create_bookmark());
+ *hash = crc_32(key, len, *hash); /* this is probably sufficient */
}
-/* ----------------------------------------------------------------------- */
-/* This function acts as the load interface from the context menu. */
-/* This function determines the bookmark file name and then loads that file*/
-/* for the user. The user can then select or delete previous bookmarks. */
-/* This function returns BOOKMARK_SUCCESS on the selection of a track to */
-/* resume, BOOKMARK_FAIL if the menu is exited without a selection and */
-/* BOOKMARK_USB_CONNECTED if the menu is forced to exit due to a USB */
-/* connection. */
-/* ----------------------------------------------------------------------- */
-int bookmark_load_menu(void)
+static const char* skip_tokens(const char* s, int ntokens)
{
- char* bookmark;
- int ret = BOOKMARK_FAIL;
-
- push_current_activity(ACTIVITY_BOOKMARKSLIST);
-
- char* name = playlist_get_name(NULL, global_temp_buffer,
- sizeof(global_temp_buffer));
- if (generate_bookmark_file_name(name))
+ for (int i = 0; i < ntokens; i++)
{
- ret = select_bookmark(global_bookmark_file_name, false, &bookmark);
- if (bookmark != NULL)
+ while (*s && *s != ';')
{
- ret = play_bookmark(bookmark) ? BOOKMARK_SUCCESS : BOOKMARK_FAIL;
+ s++;
+ }
+
+ if (*s)
+ {
+ s++;
}
}
+ return s;
+}
- pop_current_activity();
+static int int_token(const char **s)
+{
+ int ret = atoi(*s);
+ *s = skip_tokens(*s, 1);
return ret;
}
-/* ----------------------------------------------------------------------- */
-/* Gives the user a list of the Most Recent Bookmarks. This is an */
-/* interface function */
-/* Returns true on the successful selection of a recent bookmark. */
-/* ----------------------------------------------------------------------- */
-bool bookmark_mrb_load()
+static long long_token(const char **s)
{
- char* bookmark;
- bool ret = false;
+ /* Should be atol, but we don't have it. */
+ return int_token(s);
+}
- push_current_activity(ACTIVITY_BOOKMARKSLIST);
- select_bookmark(RECENT_BOOKMARK_FILE, false, &bookmark);
- if (bookmark != NULL)
+/*-------------------------------------------------------------------------*/
+/* Get the name of the playlist and the name of the track from a bookmark. */
+/* Returns true iff both were extracted. */
+/*-------------------------------------------------------------------------*/
+static bool bookmark_get_playlist_and_track_hash(const char *bookmark,
+ uint32_t *pl_hash,
+ uint32_t *track_hash)
+{
+ *pl_hash = 0;
+ *track_hash = 0;
+ int pl_len;
+ const char *pl_start, *pl_end, *track;
+
+ logf("%s", __func__);
+
+ pl_start = strchr(bookmark,'/');
+ if (!(pl_start))
+ return false;
+
+ pl_end = skip_tokens(pl_start, 1) - 1;
+ pl_len = pl_end - pl_start;
+
+ track = pl_end + 1;
+ get_hash(pl_start, pl_hash, pl_len);
+
+ if (global_settings.usemrb == BOOKMARK_ONE_PER_TRACK)
{
- ret = play_bookmark(bookmark);
+ get_hash(track, track_hash, strlen(track));
}
- pop_current_activity();
- return ret;
+
+ return true;
}
/* ----------------------------------------------------------------------- */
-/* This function handles an autobookmark creation. This is an interface */
-/* function. */
-/* Returns true on successful bookmark creation. */
+/* This function takes a bookmark and parses it. This function also */
+/* validates the bookmark. Valid filenamebuf indicates whether */
+/* the filename tokens are to be extracted. */
+/* Returns true on successful bookmark parse. */
/* ----------------------------------------------------------------------- */
-bool bookmark_autobookmark(bool prompt_ok)
+static bool parse_bookmark(char *filenamebuf,
+ size_t filenamebufsz,
+ const char *bookmark,
+ struct resume_info *resume_info,
+ const bool strip_dir)
{
- char* bookmark;
- bool update;
-
- if (!bookmark_is_bookmarkable_state())
- return false;
+ const char* s = bookmark;
+ const char* end;
- audio_pause(); /* first pause playback */
- update = (global_settings.autoupdatebookmark && bookmark_exists());
- bookmark = create_bookmark();
+#define GET_INT_TOKEN(var) var = int_token(&s)
+#define GET_LONG_TOKEN(var) var = long_token(&s)
+#define GET_BOOL_TOKEN(var) var = (int_token(&s) != 0)
- if (update)
- return write_bookmark(true, bookmark);
+ /* if new format bookmark, extract the optional content flags,
+ otherwise treat as an original format bookmark */
+ int opt_flags = 0;
+ int opt_pitch = 0;
+ int opt_speed = 0;
+ int old_format = ((strchr(s, '>') == s) ? 0 : 1);
+ if (old_format == 0) /* this is a new format bookmark */
+ {
+ s++;
+ GET_INT_TOKEN(opt_flags);
+ opt_pitch = (opt_flags & BM_PITCH) ? 1:0;
+ opt_speed = (opt_flags & BM_SPEED) ? 1:0;
+ }
- switch (global_settings.autocreatebookmark)
+ /* extract all original bookmark tokens */
+ if (resume_info)
{
- case BOOKMARK_YES:
- return write_bookmark(true, bookmark);
+ GET_INT_TOKEN(resume_info->resume_index);
+ GET_LONG_TOKEN(resume_info->resume_offset);
+ GET_INT_TOKEN(resume_info->resume_seed);
- case BOOKMARK_NO:
- return false;
+ s = skip_tokens(s, old_format); /* skip deprecated token */
- case BOOKMARK_RECENT_ONLY_YES:
- return write_bookmark(false, bookmark);
- }
- const char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY)};
- const struct text_message message={lines, 1};
+ GET_LONG_TOKEN(resume_info->resume_elapsed);
+ GET_INT_TOKEN(resume_info->repeat_mode);
+ GET_BOOL_TOKEN(resume_info->shuffle);
- if(prompt_ok && gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES)
+ /* extract all optional bookmark tokens */
+ if (opt_pitch != 0)
+ GET_INT_TOKEN(resume_info->pitch);
+ if (opt_speed != 0)
+ GET_INT_TOKEN(resume_info->speed);
+ }
+ else /* no resume info we just want the file name strings */
{
- if (global_settings.autocreatebookmark == BOOKMARK_RECENT_ONLY_ASK)
- return write_bookmark(false, bookmark);
- else
- return write_bookmark(true, bookmark);
+ #define DEFAULT_BM_TOKENS 6
+ int skipct = DEFAULT_BM_TOKENS + old_format + opt_pitch + opt_speed;
+ s = skip_tokens(s, skipct);
+ #undef DEFAULT_BM_TOKENS
}
- return false;
-}
-/* ----------------------------------------------------------------------- */
-/* This function takes the current current resume information and writes */
-/* that to the beginning of the bookmark file. */
-/* This file will contain N number of bookmarks in the following format: */
-/* resume_index*resume_offset*resume_seed*resume_first_index* */
-/* resume_file*milliseconds*MP3 Title* */
-/* Returns true on successful bookmark write. */
-/* Returns false if any part of the bookmarking process fails. It is */
-/* possible that a bookmark is successfully added to the most recent */
-/* bookmark list but fails to be added to the bookmark file or vice versa. */
-/* ------------------------------------------------------------------------*/
-static bool write_bookmark(bool create_bookmark_file, const char *bookmark)
-{
- bool ret=true;
-
- if (!bookmark)
+ if (*s == 0)
{
- ret = false; /* something didn't happen correctly, do nothing */
+ return false;
}
- else
- {
- if (global_settings.usemrb)
- ret = add_bookmark(RECENT_BOOKMARK_FILE, bookmark, true);
+ end = strchr(s, ';');
- /* writing the bookmark */
- if (create_bookmark_file)
+ /* extract file names */
+ if(filenamebuf)
+ {
+ size_t len = (end == NULL) ? strlen(s) : (size_t) (end - s);
+ len = MIN(TEMP_BUF_SIZE - 1, len);
+ strmemccpy(global_temp_buffer, s, len + 1);
+
+ if (end != NULL)
{
- char* name = playlist_get_name(NULL, global_temp_buffer,
- sizeof(global_temp_buffer));
- if (generate_bookmark_file_name(name))
- {
- ret = ret & add_bookmark(global_bookmark_file_name, bookmark, false);
- }
- else
+ end++;
+ if (strip_dir)
{
- ret = false; /* generating bookmark file failed */
+ s = strrchr(end, '/');
+ if (s)
+ {
+ end = s;
+ end++;
+ }
}
+ strmemccpy(filenamebuf, end, filenamebufsz);
}
- }
-
- splash(HZ, ret ? ID2P(LANG_BOOKMARK_CREATE_SUCCESS)
- : ID2P(LANG_BOOKMARK_CREATE_FAILURE));
+ }
- return ret;
+ return true;
}
-/* Get the name of the playlist and the name of the track from a bookmark. */
-/* Returns true iff both were extracted. */
-static bool get_playlist_and_track(const char *bookmark, char **pl_start,
- char **pl_end, char **track)
+/* ------------------------------------------------------------------------- */
+/* This function takes a filename and appends .tmp. This function also opens */
+/* the resulting file based on oflags, filename will be in buf on return */
+/* Returns file descriptor */
+/* --------------------------------------------------------------------------*/
+static int open_temp_bookmark(char *buf,
+ size_t bufsz,
+ int oflags,
+ const char* filename)
{
- *pl_start = strchr(bookmark,'/');
- if (!(*pl_start))
- return false;
- *pl_end = strrchr(bookmark,';');
- *track = *pl_end + 1;
- return true;
+ if(filename[0] == '/')
+ filename++;
+ /* Opening up a temp bookmark file */
+ int fd = open_pathfmt(buf, bufsz, oflags, "/%s.tmp", filename);
+#ifdef LOGF_ENABLE
+ if (oflags & O_PATH)
+ logf("tempfile path %s", buf);
+ else
+ logf("opening tempfile %s", buf);
+#endif
+ return fd;
}
/* ----------------------------------------------------------------------- */
/* This function adds a bookmark to a file. */
/* Returns true on successful bookmark add. */
/* ------------------------------------------------------------------------*/
-static bool add_bookmark(const char* bookmark_file_name, const char* bookmark,
+static bool add_bookmark(const char* bookmark_file_name,
+ const char* bookmark,
bool most_recent)
{
- int temp_bookmark_file = 0;
- int bookmark_file = 0;
- int bookmark_count = 0;
- char *pl_start = NULL, *bm_pl_start;
- char *pl_end = NULL, *bm_pl_end;
- int pl_len = 0, bm_pl_len;
- char *track = NULL, *bm_track;
- bool comp_playlist = false;
- bool comp_track = false;
- bool equal;
+ char fnamebuf[MAX_PATH];
+ int temp_bookmark_file = 0;
+ int bookmark_file = 0;
+ int bookmark_count = 0;
+ bool comp_playlist = false;
+ bool comp_track = false;
+ bool equal;
+ uint32_t pl_hash, pl_track_hash;
+ uint32_t bm_pl_hash, bm_pl_track_hash;
/* Opening up a temp bookmark file */
- snprintf(global_temp_buffer, sizeof(global_temp_buffer),
- "%s.tmp", bookmark_file_name);
- temp_bookmark_file = open(global_temp_buffer,
- O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (temp_bookmark_file < 0)
- return false; /* can't open the temp file */
+ temp_bookmark_file = open_temp_bookmark(fnamebuf,
+ sizeof(fnamebuf),
+ O_WRONLY | O_CREAT | O_TRUNC,
+ bookmark_file_name);
+
+ if (temp_bookmark_file < 0 || !bookmark)
+ return false; /* can't open the temp file or no bookmark */
if (most_recent && ((global_settings.usemrb == BOOKMARK_ONE_PER_PLAYLIST)
|| (global_settings.usemrb == BOOKMARK_ONE_PER_TRACK)))
{
- if (get_playlist_and_track(bookmark, &pl_start, &pl_end, &track))
+
+ if (bookmark_get_playlist_and_track_hash(bookmark, &pl_hash, &pl_track_hash))
{
comp_playlist = true;
- pl_len = pl_end - pl_start;
- if (global_settings.usemrb == BOOKMARK_ONE_PER_TRACK)
- comp_track = true;
+ comp_track = (global_settings.usemrb == BOOKMARK_ONE_PER_TRACK);
}
}
+ logf("adding bookmark to %s [%s]", fnamebuf, bookmark);
/* Writing the new bookmark to the begining of the temp file */
write(temp_bookmark_file, bookmark, strlen(bookmark));
write(temp_bookmark_file, "\n", 1);
bookmark_count++;
+ /* WARNING underlying buffer to *bookmrk gets overwritten after this point! */
+
/* Reading in the previous bookmarks and writing them to the temp file */
+ logf("opening old bookmark %s", bookmark_file_name);
bookmark_file = open(bookmark_file_name, O_RDONLY);
if (bookmark_file >= 0)
{
- while (read_line(bookmark_file, global_read_buffer,
- sizeof(global_read_buffer)) > 0)
+ while (read_line(bookmark_file, global_temp_buffer,
+ sizeof(global_temp_buffer)) > 0)
{
/* The MRB has a max of MAX_BOOKMARKS in it */
/* This keeps it from getting too large */
if (most_recent && (bookmark_count >= MAX_BOOKMARKS))
break;
- if (!parse_bookmark(global_read_buffer, false, false))
+ if (!parse_bookmark(NULL, 0, global_temp_buffer, NULL, false))
break;
equal = false;
if (comp_playlist)
{
- if (get_playlist_and_track(global_read_buffer, &bm_pl_start,
- &bm_pl_end, &bm_track))
+ if (bookmark_get_playlist_and_track_hash(global_temp_buffer,
+ &bm_pl_hash, &bm_pl_track_hash))
{
- bm_pl_len = bm_pl_end - bm_pl_start;
- equal = (pl_len == bm_pl_len) && !strncmp(pl_start, bm_pl_start, pl_len);
+ equal = (pl_hash == bm_pl_hash);
if (equal && comp_track)
- equal = !strcmp(track, bm_track);
+ {
+ equal = (pl_track_hash == bm_pl_track_hash);
+ }
}
}
if (!equal)
{
bookmark_count++;
- write(temp_bookmark_file, global_read_buffer,
- strlen(global_read_buffer));
+ /*logf("copying old bookmark [%s]", global_temp_buffer);*/
+ write(temp_bookmark_file, global_temp_buffer,
+ strlen(global_temp_buffer));
write(temp_bookmark_file, "\n", 1);
}
}
@@ -354,180 +360,237 @@ static bool add_bookmark(const char* bookmark_file_name, const char* bookmark,
close(temp_bookmark_file);
remove(bookmark_file_name);
- rename(global_temp_buffer, bookmark_file_name);
+ rename(fnamebuf, bookmark_file_name);
return true;
}
+/* ----------------------------------------------------------------------- */
+/* This function is used by multiple functions and is used to generate a */
+/* bookmark named based off of the input. */
+/* Changing this function could result in how the bookmarks are stored. */
+/* it would be here that the centralized/decentralized bookmark code */
+/* could be placed. */
+/* Returns true if the file name is generated, false if it was too long */
+/* ----------------------------------------------------------------------- */
+static bool generate_bookmark_file_name(char *filenamebuf,
+ size_t filenamebufsz,
+ const char *bmarknamein,
+ size_t bmarknamelen)
+{
+ /* if this is a root dir MP3, rename the bookmark file root_dir.bmark */
+ /* otherwise, name it based on the bmarknamein variable */
+ if (!strncmp("/", bmarknamein, bmarknamelen))
+ strmemccpy(filenamebuf, "/root_dir.bmark", filenamebufsz);
+ else
+ {
+ size_t buflen, len;
+ /* strmemccpy considers the NULL so bmarknamelen is one off */
+ buflen = MIN(filenamebufsz -1 , bmarknamelen);
+ if (buflen >= filenamebufsz)
+ return false;
+
+ strmemccpy(filenamebuf, bmarknamein, buflen + 1);
+
+ len = strlen(filenamebuf);
+
+#ifdef HAVE_MULTIVOLUME
+ /* The "root" of an extra volume need special handling too. */
+ const char *filename;
+ path_strip_volume(filenamebuf, &filename, true);
+ bool volume_root = *filename == '\0';
+#endif
+ if(filenamebuf[len-1] == '/') {
+ filenamebuf[len-1] = '\0';
+ }
+
+ const char *name = ".bmark";
+#ifdef HAVE_MULTIVOLUME
+ if (volume_root)
+ name = "/volume_dir.bmark";
+#endif
+ len = strlcat(filenamebuf, name, filenamebufsz);
+
+ if(len >= filenamebufsz)
+ return false;
+ }
+ logf ("generated name '%s' from '%.*s'",
+ filenamebuf, (int)bmarknamelen, bmarknamein);
+ return true;
+}
+
/* GCC 7 and up complain about the snprintf in create_bookmark() when
compiled with -D_FORTIFY_SOURCE or -Wformat-truncation
This is a false positive, so disable it here only */
-#if __GNUC__ >= 7
+/* SHOULD NO LONGER BE NEEDED --Bilgus 11-2022 */
+#if 0 /* __GNUC__ >= 7 */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-truncation"
#endif
/* ----------------------------------------------------------------------- */
/* This function takes the system resume data and formats it into a valid */
/* bookmark. */
-/* Returns not NULL on successful bookmark format. */
+/* playlist name and name len are passed back through the name/namelen */
+/* Return is not NULL on successful bookmark format. */
/* ----------------------------------------------------------------------- */
-static char* create_bookmark()
+static char* create_bookmark(char **name,
+ size_t *namelen,
+ struct resume_info *resume_info)
{
- int resume_index = 0;
- char *file;
-
- if (!bookmark_is_bookmarkable_state())
- return NULL; /* something didn't happen correctly, do nothing */
+ const char *file;
+ char *buf = global_temp_buffer;
+ size_t bufsz = sizeof(global_temp_buffer);
- /* grab the currently playing track */
- struct mp3entry *id3 = audio_current_track();
- if(!id3)
+ if(!resume_info->id3)
return NULL;
- /* Get some basic resume information */
- /* queue_resume and queue_resume_index are not used and can be ignored.*/
- playlist_get_resume_info(&resume_index);
-
- /* Get the currently playing file minus the path */
- /* This is used when displaying the available bookmarks */
- file = strrchr(id3->path,'/');
- if(NULL == file)
- return NULL;
-
- /* create the bookmark */
- playlist_get_name(NULL, global_temp_buffer, sizeof(global_temp_buffer));
- if (global_temp_buffer[strlen(global_temp_buffer) - 1] != '/')
- file = id3->path;
- else file++;
- snprintf(global_bookmark, sizeof(global_bookmark),
- /* new optional bookmark token descriptors should be inserted
- just before the "%s;%s" in this line... */
+ size_t bmarksz= snprintf(buf, bufsz,
+ /* new optional bookmark token descriptors should
+ be inserted just after ';"' in this line... */
#if defined(HAVE_PITCHCONTROL)
- ">%d;%d;%ld;%d;%ld;%d;%d;%ld;%ld;%s;%s",
+ ">%d;%d;%ld;%d;%ld;%d;%d;%ld;%ld;",
#else
- ">%d;%d;%ld;%d;%ld;%d;%d;%s;%s",
+ ">%d;%d;%ld;%d;%ld;%d;%d;",
#endif
- /* ... their flags should go here ... */
+ /* ... their flags should go here ... */
#if defined(HAVE_PITCHCONTROL)
- BM_PITCH | BM_SPEED,
+ BM_PITCH | BM_SPEED,
#else
- 0,
+ 0,
#endif
- resume_index,
- id3->offset,
- playlist_get_seed(NULL),
- id3->elapsed,
- global_settings.repeat_mode,
- global_settings.playlist_shuffle,
- /* ...and their values should go here */
+ resume_info->resume_index,
+ resume_info->id3->offset,
+ resume_info->resume_seed,
+ resume_info->id3->elapsed,
+ resume_info->repeat_mode,
+ resume_info->shuffle,
+ /* ...and their values should go here */
#if defined(HAVE_PITCHCONTROL)
- (long)sound_get_pitch(),
- (long)dsp_get_timestretch(),
+ (long)resume_info->pitch,
+ (long)resume_info->speed
#endif
- /* more mandatory tokens */
- global_temp_buffer,
- file);
+ ); /*sprintf*/
+/* mandatory tokens */
+ if (bmarksz >= bufsz) /* include NULL*/
+ return NULL;
+ buf += bmarksz;
+ bufsz -= bmarksz;
+
+ /* create the bookmark */
+ playlist_get_name(NULL, buf, bufsz);
+ bmarksz = strlen(buf);
+
+ if (bmarksz == 0 || (bmarksz + 1) >= bufsz) /* include the separator & NULL*/
+ return NULL;
+
+ *name = buf; /* return the playlist name through the *pointer */
+ *namelen = bmarksz; /* return the name length through the pointer */
+
+ /* Get the currently playing file minus the path */
+ /* This is used when displaying the available bookmarks */
+ file = strrchr(resume_info->id3->path,'/');
+ if(NULL == file)
+ return NULL;
+
+ if (buf[bmarksz - 1] != '/')
+ file = resume_info->id3->path;
+ else file++;
+
+ buf += bmarksz;
+ bufsz -= (bmarksz + 1);
+ buf[0] = ';';
+ buf[1] = '\0';
+
+ strlcat(buf, file, bufsz);
+ logf("%s [%s]", __func__, global_temp_buffer);
/* checking to see if the bookmark is valid */
- if (parse_bookmark(global_bookmark, false, false))
- return global_bookmark;
+ if (parse_bookmark(NULL, 0, global_temp_buffer, NULL, false))
+ return global_temp_buffer;
else
return NULL;
}
-#if __GNUC__ >= 7
+#if 0/* __GNUC__ >= 7*/
#pragma GCC diagnostic pop /* -Wformat-truncation */
#endif
/* ----------------------------------------------------------------------- */
-/* This function will determine if an autoload is necessary. This is an */
-/* interface function. */
-/* Returns true on bookmark load or bookmark selection. */
-/* ------------------------------------------------------------------------*/
-bool bookmark_autoload(const char* file)
+/* This function gets some basic resume information for the current song */
+/* from rockbox, */
+/* ----------------------------------------------------------------------- */
+static void get_track_resume_info(struct resume_info *resume_info)
{
- char* bookmark;
-
- if(global_settings.autoloadbookmark == BOOKMARK_NO)
- return false;
-
- /*Checking to see if a bookmark file exists.*/
- if(!generate_bookmark_file_name(file))
- {
- return false;
- }
-
- if(!file_exists(global_bookmark_file_name))
- return false;
-
- if(global_settings.autoloadbookmark == BOOKMARK_YES)
- {
- return bookmark_load(global_bookmark_file_name, true);
- }
+ if (global_settings.playlist_shuffle)
+ playlist_get_resume_info(&(resume_info->resume_index));
else
- {
- int ret = select_bookmark(global_bookmark_file_name, true, &bookmark);
-
- if (bookmark != NULL)
- {
- if (!play_bookmark(bookmark))
- {
- /* Selected bookmark not found. */
- splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
- }
+ resume_info->resume_index = playlist_get_display_index() - 1;
- /* Act as if autoload was done even if it failed, since the
- * user did make an active selection.
- */
- return true;
- }
-
- return ret != BOOKMARK_SUCCESS;
- }
+ resume_info->resume_seed = playlist_get_seed(NULL);
+ resume_info->id3 = audio_current_track();
+ resume_info->repeat_mode = global_settings.repeat_mode;
+ resume_info->shuffle = global_settings.playlist_shuffle;
+#if defined(HAVE_PITCHCONTROL)
+ resume_info->pitch = sound_get_pitch();
+ resume_info->speed = dsp_get_timestretch();
+#endif
}
/* ----------------------------------------------------------------------- */
-/* This function loads the bookmark information into the resume memory. */
-/* This is an interface function. */
-/* Returns true on successful bookmark load. */
+/* This function takes the current current resume information and writes */
+/* that to the beginning of the bookmark file. */
+/* This file will contain N number of bookmarks in the following format: */
+/* resume_index*resume_offset*resume_seed*resume_first_index* */
+/* resume_file*milliseconds*MP3 Title* */
+/* Returns true on successful bookmark write. */
+/* Returns false if any part of the bookmarking process fails. It is */
+/* possible that a bookmark is successfully added to the most recent */
+/* bookmark list but fails to be added to the bookmark file or vice versa. */
/* ------------------------------------------------------------------------*/
-bool bookmark_load(const char* file, bool autoload)
+static bool write_bookmark(bool create_bookmark_file)
{
- int fd;
- char* bookmark = NULL;
+ logf("%s", __func__);
+ char bm_filename[MAX_PATH];
+ bool ret=true;
- if(autoload)
+ char *name = NULL;
+ size_t namelen = 0;
+ char* bm;
+ struct resume_info resume_info;
+
+ if (bookmark_is_bookmarkable_state())
{
- fd = open(file, O_RDONLY);
- if(fd >= 0)
+ get_track_resume_info(&resume_info);
+ /* writing the most recent bookmark */
+ if (global_settings.usemrb)
{
- if(read_line(fd, global_read_buffer, sizeof(global_read_buffer)) > 0)
- bookmark=global_read_buffer;
- close(fd);
+ /* since we use the same buffer bookmark needs created each time */
+ bm = create_bookmark(&name, &namelen, &resume_info);
+ ret = add_bookmark(RECENT_BOOKMARK_FILE, bm, true);
}
- }
- else
- {
- /* This is not an auto-load, so list the bookmarks */
- select_bookmark(file, false, &bookmark);
- }
- if (bookmark != NULL)
- {
- if (!play_bookmark(bookmark))
+ /* writing the directory bookmark */
+ if (create_bookmark_file)
{
- /* Selected bookmark not found. */
- if (!autoload)
+ bm = create_bookmark(&name, &namelen, &resume_info);
+ if (generate_bookmark_file_name(bm_filename,
+ sizeof(bm_filename), name, namelen))
{
- splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
+ ret &= add_bookmark(bm_filename, bm, false);
+ }
+ else
+ {
+ ret = false; /* generating bookmark file failed */
}
-
- return false;
}
}
+ else
+ ret = false;
- return true;
-}
+ splash(HZ, ret ? ID2P(LANG_BOOKMARK_CREATE_SUCCESS)
+ : ID2P(LANG_BOOKMARK_CREATE_FAILURE));
+ return ret;
+}
static int get_bookmark_count(const char* bookmark_file_name)
{
@@ -537,7 +600,7 @@ static int get_bookmark_count(const char* bookmark_file_name)
if(file < 0)
return -1;
- while(read_line(file, global_read_buffer, sizeof(global_read_buffer)) > 0)
+ while(read_line(file, global_temp_buffer, sizeof(global_temp_buffer)) > 0)
{
read_count++;
}
@@ -568,13 +631,13 @@ static int buffer_bookmarks(struct bookmark_list* bookmarks, int first_line)
bookmarks->count = 0;
bookmarks->reload = false;
- while(read_line(file, global_read_buffer, sizeof(global_read_buffer)) > 0)
+ while(read_line(file, global_temp_buffer, sizeof(global_temp_buffer)) > 0)
{
read_count++;
if (read_count >= first_line)
{
- dest -= strlen(global_read_buffer) + 1;
+ dest -= strlen(global_temp_buffer) + 1;
if (dest < ((char*) bookmarks) + sizeof(*bookmarks)
+ (sizeof(char*) * (bookmarks->count + 1)))
@@ -582,7 +645,7 @@ static int buffer_bookmarks(struct bookmark_list* bookmarks, int first_line)
break;
}
- strcpy(dest, global_read_buffer);
+ strcpy(dest, global_temp_buffer);
bookmarks->items[bookmarks->count] = dest;
bookmarks->count++;
}
@@ -597,6 +660,8 @@ static const char* get_bookmark_info(int list_index,
char *buffer,
size_t buffer_len)
{
+ char fnamebuf[MAX_PATH];
+ struct resume_info resume_info;
struct bookmark_list* bookmarks = (struct bookmark_list*) data;
int index = list_index / 2;
@@ -652,7 +717,8 @@ static const char* get_bookmark_info(int list_index,
}
}
- if (!parse_bookmark(bookmarks->items[index - bookmarks->start], true, true))
+ if (!parse_bookmark(fnamebuf, sizeof(fnamebuf),
+ bookmarks->items[index - bookmarks->start], &resume_info, true))
{
return list_index % 2 == 0 ? (char*) str(LANG_BOOKMARK_INVALID) : " ";
}
@@ -686,25 +752,73 @@ static const char* get_bookmark_info(int list_index,
}
else
{
- name = global_filename;
+ name = fnamebuf;
format = "%s";
}
- strrsplt(global_filename, '.');
- snprintf(buffer, buffer_len, format, name, global_filename);
+ strrsplt(fnamebuf, '.');
+ snprintf(buffer, buffer_len, format, name, fnamebuf);
return buffer;
}
else
{
char time_buf[32];
- format_time(time_buf, sizeof(time_buf), bm.resume_time);
- snprintf(buffer, buffer_len, "%s, %d%s", time_buf, bm.resume_index + 1,
- bm.shuffle ? (char*) str(LANG_BOOKMARK_SHUFFLE) : "");
+ format_time(time_buf, sizeof(time_buf), resume_info.resume_elapsed);
+ snprintf(buffer, buffer_len, "%s, %d%s", time_buf,
+ resume_info.resume_index + 1,
+ resume_info.shuffle ? (char*) str(LANG_BOOKMARK_SHUFFLE) : "");
return buffer;
}
}
+/* ----------------------------------------------------------------------- */
+/* This function parses a bookmark, says the voice UI part of it. */
+/* ------------------------------------------------------------------------*/
+static void say_bookmark(const char* bookmark,
+ int bookmark_id,
+ bool show_playlist_name)
+{
+ char fnamebuf[MAX_PATH];
+ struct resume_info resume_info;
+ if (!parse_bookmark(fnamebuf, sizeof(fnamebuf), bookmark, &resume_info, false))
+ {
+ talk_id(LANG_BOOKMARK_INVALID, false);
+ return;
+ }
+
+ talk_number(bookmark_id + 1, false);
+
+ bool is_dir = (global_temp_buffer[0]
+ && global_temp_buffer[strlen(global_temp_buffer)-1] == '/');
+
+ /* HWCODEC cannot enqueue voice file entries and .talk thumbnails
+ together, because there is no guarantee that the same mp3
+ parameters are used. */
+ if(show_playlist_name)
+ { /* It's useful to know which playlist this is */
+ if(is_dir)
+ talk_dir_or_spell(global_temp_buffer,
+ TALK_IDARRAY(VOICE_DIR), true);
+ else talk_file_or_spell(NULL, global_temp_buffer,
+ TALK_IDARRAY(LANG_PLAYLIST), true);
+ }
+
+ if(resume_info.shuffle)
+ talk_id(LANG_SHUFFLE, true);
+
+ talk_id(VOICE_BOOKMARK_SELECT_INDEX_TEXT, true);
+ talk_number(resume_info.resume_index + 1, true);
+ talk_id(LANG_TIME, true);
+ talk_value(resume_info.resume_elapsed / 1000, UNIT_TIME, true);
+
+ /* Track filename */
+ if(!is_dir)
+ global_temp_buffer[0] = 0;
+ talk_file_or_spell(global_temp_buffer, fnamebuf,
+ TALK_IDARRAY(VOICE_FILE), true);
+}
+
static int bookmark_list_voice_cb(int list_index, void* data)
{
struct bookmark_list* bookmarks = (struct bookmark_list*) data;
@@ -722,6 +836,57 @@ static int bookmark_list_voice_cb(int list_index, void* data)
}
/* ----------------------------------------------------------------------- */
+/* This function takes a location in a bookmark file and deletes that */
+/* bookmark. */
+/* Returns true on successful bookmark deletion. */
+/* ------------------------------------------------------------------------*/
+static bool delete_bookmark(const char* bookmark_file_name, int bookmark_id)
+{
+ int temp_bookmark_file = 0;
+ int bookmark_file = 0;
+ int bookmark_count = 0;
+
+ /* Opening up a temp bookmark file */
+ temp_bookmark_file = open_temp_bookmark(global_temp_buffer,
+ sizeof(global_temp_buffer),
+ O_WRONLY | O_CREAT | O_TRUNC,
+ bookmark_file_name);
+
+ if (temp_bookmark_file < 0)
+ return false; /* can't open the temp file */
+
+ /* Reading in the previous bookmarks and writing them to the temp file */
+ bookmark_file = open(bookmark_file_name, O_RDONLY);
+ if (bookmark_file >= 0)
+ {
+ while (read_line(bookmark_file, global_temp_buffer,
+ sizeof(global_temp_buffer)) > 0)
+ {
+ if (bookmark_id != bookmark_count)
+ {
+ write(temp_bookmark_file, global_temp_buffer,
+ strlen(global_temp_buffer));
+ write(temp_bookmark_file, "\n", 1);
+ }
+ bookmark_count++;
+ }
+ close(bookmark_file);
+ }
+ close(temp_bookmark_file);
+
+ /* only retrieve the path*/
+ open_temp_bookmark(global_temp_buffer,
+ sizeof(global_temp_buffer),
+ O_PATH,
+ bookmark_file_name);
+
+ remove(bookmark_file_name);
+ rename(global_temp_buffer, bookmark_file_name);
+
+ return true;
+}
+
+/* ----------------------------------------------------------------------- */
/* This displays the bookmarks in a file and allows the user to */
/* select one to play. */
/* *selected_bookmark contains a non NULL value on successful bookmark */
@@ -730,7 +895,9 @@ static int bookmark_list_voice_cb(int list_index, void* data)
/* if no selection was made and BOOKMARK_USB_CONNECTED if the selection */
/* menu is forced to exit due to a USB connection. */
/* ------------------------------------------------------------------------*/
-static int select_bookmark(const char* bookmark_file_name, bool show_dont_resume, char** selected_bookmark)
+static int select_bookmark(const char* bookmark_file_name,
+ bool show_dont_resume,
+ char** selected_bookmark)
{
struct bookmark_list* bookmarks;
struct gui_synclist list;
@@ -747,12 +914,13 @@ static int select_bookmark(const char* bookmark_file_name, bool show_dont_resume
bookmarks->filename = bookmark_file_name;
bookmarks->start = 0;
bookmarks->show_playlist_name
- = strcmp(bookmark_file_name, RECENT_BOOKMARK_FILE) == 0;
- gui_synclist_init(&list, &get_bookmark_info, (void*) bookmarks, false, 2, NULL);
+ = (strcmp(bookmark_file_name, RECENT_BOOKMARK_FILE) == 0);
+
+ gui_synclist_init(&list, &get_bookmark_info,
+ (void*) bookmarks, false, 2, NULL);
+
if(global_settings.talk_menu)
gui_synclist_set_voice_callback(&list, bookmark_list_voice_cb);
- gui_synclist_set_title(&list, str(LANG_BOOKMARK_SELECT_BOOKMARK),
- Icon_Bookmark);
while (!exit)
{
@@ -787,14 +955,15 @@ static int select_bookmark(const char* bookmark_file_name, bool show_dont_resume
}
buffer_bookmarks(bookmarks, bookmarks->start);
+ gui_synclist_set_title(&list, str(LANG_BOOKMARK_SELECT_BOOKMARK),
+ Icon_Bookmark);
gui_synclist_draw(&list);
cond_talk_ids_fq(VOICE_EXT_BMARK);
gui_synclist_speak_item(&list);
refresh = false;
}
- list_do_action(CONTEXT_BOOKMARKSCREEN, HZ / 2,
- &list, &action, LIST_WRAP_UNLESS_HELD);
+ list_do_action(CONTEXT_BOOKMARKSCREEN, HZ / 2, &list, &action);
item = gui_synclist_get_sel_pos(&list) / 2;
if (bookmarks->show_dont_resume)
@@ -843,17 +1012,7 @@ static int select_bookmark(const char* bookmark_file_name, bool show_dont_resume
case ACTION_BMS_DELETE:
if (item >= 0)
{
- const char *lines[]={
- ID2P(LANG_REALLY_DELETE)
- };
- const char *yes_lines[]={
- ID2P(LANG_DELETING)
- };
-
- const struct text_message message={lines, 1};
- const struct text_message yes_message={yes_lines, 1};
-
- if(gui_syncyesno_run(&message, &yes_message, NULL)==YESNO_YES)
+ if (confirm_delete_yesno("") == YESNO_YES)
{
delete_bookmark(bookmark_file_name, item);
bookmarks->reload = true;
@@ -879,264 +1038,247 @@ static int select_bookmark(const char* bookmark_file_name, bool show_dont_resume
}
/* ----------------------------------------------------------------------- */
-/* This function takes a location in a bookmark file and deletes that */
-/* bookmark. */
-/* Returns true on successful bookmark deletion. */
+/* This function parses a bookmark and then plays it. */
+/* Returns true on successful bookmark play. */
/* ------------------------------------------------------------------------*/
-static bool delete_bookmark(const char* bookmark_file_name, int bookmark_id)
+static bool play_bookmark(const char* bookmark)
{
- int temp_bookmark_file = 0;
- int bookmark_file = 0;
- int bookmark_count = 0;
-
- /* Opening up a temp bookmark file */
- snprintf(global_temp_buffer, sizeof(global_temp_buffer),
- "%s.tmp", bookmark_file_name);
- temp_bookmark_file = open(global_temp_buffer,
- O_WRONLY | O_CREAT | O_TRUNC, 0666);
-
- if (temp_bookmark_file < 0)
- return false; /* can't open the temp file */
+ char fnamebuf[MAX_PATH];
+ struct resume_info resume_info;
+#if defined(HAVE_PITCHCONTROL)
+ /* preset pitch and speed to 100% in case bookmark doesn't have info */
+ resume_info.pitch = sound_get_pitch();
+ resume_info.speed = dsp_get_timestretch();
+#endif
- /* Reading in the previous bookmarks and writing them to the temp file */
- bookmark_file = open(bookmark_file_name, O_RDONLY);
- if (bookmark_file >= 0)
+ if (parse_bookmark(fnamebuf, sizeof(fnamebuf), bookmark, &resume_info, true))
{
- while (read_line(bookmark_file, global_read_buffer,
- sizeof(global_read_buffer)) > 0)
+ global_settings.repeat_mode = resume_info.repeat_mode;
+ global_settings.playlist_shuffle = resume_info.shuffle;
+#if defined(HAVE_PITCHCONTROL)
+ sound_set_pitch(resume_info.pitch);
+ dsp_set_timestretch(resume_info.speed);
+#endif
+ if (!warn_on_pl_erase())
+ return false;
+ bool success = bookmark_play(global_temp_buffer, resume_info.resume_index,
+ resume_info.resume_elapsed, resume_info.resume_offset,
+ resume_info.resume_seed, fnamebuf);
+ if (success) /* verify we loaded the correct track */
{
- if (bookmark_id != bookmark_count)
+ const struct mp3entry *id3 = audio_current_track();
+ if (id3)
{
- write(temp_bookmark_file, global_read_buffer,
- strlen(global_read_buffer));
- write(temp_bookmark_file, "\n", 1);
+ const char *path;
+ const char *track;
+ path_basename(id3->path, &path);
+ path_basename(fnamebuf, &track);
+ if (strcmp(path, track) == 0)
+ {
+ return true;
+ }
}
- bookmark_count++;
+ audio_stop();
}
- close(bookmark_file);
}
- close(temp_bookmark_file);
-
- remove(bookmark_file_name);
- rename(global_temp_buffer, bookmark_file_name);
- return true;
+ return false;
}
+/*-------------------------------------------------------------------------*/
+/* PUBLIC INTERFACE -------------------------------------------------------*/
+/*-------------------------------------------------------------------------*/
+
+
/* ----------------------------------------------------------------------- */
-/* This function parses a bookmark, says the voice UI part of it. */
-/* ------------------------------------------------------------------------*/
-static void say_bookmark(const char* bookmark,
- int bookmark_id, bool show_playlist_name)
+/* This is an interface function from the context menu. */
+/* Returns true on successful bookmark creation. */
+/* ----------------------------------------------------------------------- */
+bool bookmark_create_menu(void)
{
- if (!parse_bookmark(bookmark, true, false))
- {
- talk_id(LANG_BOOKMARK_INVALID, false);
- return;
- }
-
- talk_number(bookmark_id + 1, false);
+ return write_bookmark(true);
+}
+/* ----------------------------------------------------------------------- */
+/* This function acts as the load interface from the context menu. */
+/* This function determines the bookmark file name and then loads that file*/
+/* for the user. The user can then select or delete previous bookmarks. */
+/* This function returns BOOKMARK_SUCCESS on the selection of a track to */
+/* resume, BOOKMARK_FAIL if the menu is exited without a selection and */
+/* BOOKMARK_USB_CONNECTED if the menu is forced to exit due to a USB */
+/* connection. */
+/* ----------------------------------------------------------------------- */
+int bookmark_load_menu(void)
+{
+ char bm_filename[MAX_PATH];
+ char* bookmark;
+ int ret = BOOKMARK_FAIL;
- bool is_dir = (global_temp_buffer[0]
- && global_temp_buffer[strlen(global_temp_buffer)-1] == '/');
+ push_current_activity(ACTIVITY_BOOKMARKSLIST);
- /* HWCODEC cannot enqueue voice file entries and .talk thumbnails
- together, because there is no guarantee that the same mp3
- parameters are used. */
- if(show_playlist_name)
- { /* It's useful to know which playlist this is */
- if(is_dir)
- talk_dir_or_spell(global_temp_buffer,
- TALK_IDARRAY(VOICE_DIR), true);
- else talk_file_or_spell(NULL, global_temp_buffer,
- TALK_IDARRAY(LANG_PLAYLIST), true);
+ char* name = playlist_get_name(NULL, global_temp_buffer,
+ sizeof(global_temp_buffer));
+ if (generate_bookmark_file_name(bm_filename, sizeof(bm_filename), name, -1))
+ {
+ ret = select_bookmark(bm_filename, false, &bookmark);
+ if (bookmark != NULL)
+ {
+ ret = play_bookmark(bookmark) ? BOOKMARK_SUCCESS : BOOKMARK_FAIL;
+ }
}
- if(bm.shuffle)
- talk_id(LANG_SHUFFLE, true);
-
- talk_id(VOICE_BOOKMARK_SELECT_INDEX_TEXT, true);
- talk_number(bm.resume_index + 1, true);
- talk_id(LANG_TIME, true);
- talk_value(bm.resume_time / 1000, UNIT_TIME, true);
-
- /* Track filename */
- if(!is_dir)
- global_temp_buffer[0] = 0;
- talk_file_or_spell(global_temp_buffer, global_filename,
- TALK_IDARRAY(VOICE_FILE), true);
+ pop_current_activity();
+ return ret;
}
/* ----------------------------------------------------------------------- */
-/* This function parses a bookmark and then plays it. */
-/* Returns true on successful bookmark play. */
-/* ------------------------------------------------------------------------*/
-static bool play_bookmark(const char* bookmark)
+/* Gives the user a list of the Most Recent Bookmarks. This is an */
+/* interface function */
+/* Returns true on the successful selection of a recent bookmark. */
+/* ----------------------------------------------------------------------- */
+bool bookmark_mrb_load()
{
-#if defined(HAVE_PITCHCONTROL)
- /* preset pitch and speed to 100% in case bookmark doesn't have info */
- bm.pitch = sound_get_pitch();
- bm.speed = dsp_get_timestretch();
-#endif
+ char* bookmark;
+ bool ret = false;
- if (parse_bookmark(bookmark, true, true))
+ push_current_activity(ACTIVITY_BOOKMARKSLIST);
+ select_bookmark(RECENT_BOOKMARK_FILE, false, &bookmark);
+ if (bookmark != NULL)
{
- global_settings.repeat_mode = bm.repeat_mode;
- global_settings.playlist_shuffle = bm.shuffle;
-#if defined(HAVE_PITCHCONTROL)
- sound_set_pitch(bm.pitch);
- dsp_set_timestretch(bm.speed);
-#endif
- if (!warn_on_pl_erase())
- return false;
- return bookmark_play(global_temp_buffer, bm.resume_index,
- bm.resume_time, bm.resume_offset, bm.resume_seed, global_filename);
+ ret = play_bookmark(bookmark);
}
- return false;
+ pop_current_activity();
+ return ret;
}
-static const char* skip_token(const char* s)
+/* ----------------------------------------------------------------------- */
+/* This function handles an autobookmark creation. This is an interface */
+/* function. */
+/* Returns true on successful bookmark creation. */
+/* ----------------------------------------------------------------------- */
+bool bookmark_autobookmark(bool prompt_ok)
{
- while (*s && *s != ';')
- {
- s++;
- }
+ logf("%s", __func__);
+ bool update;
+
+ if (!bookmark_is_bookmarkable_state())
+ return false;
+
+ audio_pause(); /* first pause playback */
+ update = (global_settings.autoupdatebookmark && bookmark_exists());
- if (*s)
+ if (update)
+ return write_bookmark(true);
+
+ switch (global_settings.autocreatebookmark)
{
- s++;
- }
+ case BOOKMARK_YES:
+ return write_bookmark(true);
- return s;
-}
+ case BOOKMARK_NO:
+ return false;
-static const char* int_token(const char* s, int* dest)
-{
- *dest = atoi(s);
- return skip_token(s);
-}
+ case BOOKMARK_RECENT_ONLY_YES:
+ return write_bookmark(false);
+ }
+ const char *lines[]={ID2P(LANG_AUTO_BOOKMARK_QUERY)};
+ const struct text_message message={lines, 1};
-static const char* long_token(const char* s, long* dest)
-{
- *dest = atoi(s); /* Should be atol, but we don't have it. */
- return skip_token(s);
+ if(prompt_ok && gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES)
+ {
+ if (global_settings.autocreatebookmark == BOOKMARK_RECENT_ONLY_ASK)
+ return write_bookmark(false);
+ else
+ return write_bookmark(true);
+ }
+ return false;
}
/* ----------------------------------------------------------------------- */
-/* This function takes a bookmark and parses it. This function also */
-/* validates the bookmark. The parse_filenames flag indicates whether */
-/* the filename tokens are to be extracted. */
-/* Returns true on successful bookmark parse. */
-/* ----------------------------------------------------------------------- */
-static bool parse_bookmark(const char *bookmark, const bool parse_filenames, const bool strip_dir)
+/* This function will determine if an autoload is necessary. This is an */
+/* interface function. */
+/* Returns */
+/* BOOKMARK_DO_RESUME on bookmark load or bookmark selection. */
+/* BOOKMARK_DONT_RESUME if we're not going to resume */
+/* BOOKMARK_CANCEL if user canceled */
+/* ------------------------------------------------------------------------*/
+int bookmark_autoload(const char* file)
{
- const char* s = bookmark;
- const char* end;
+ logf("%s", __func__);
+ char bm_filename[MAX_PATH];
+ char* bookmark;
-#define GET_INT_TOKEN(var) s = int_token(s, &var)
-#define GET_LONG_TOKEN(var) s = long_token(s, &var)
-#define GET_BOOL_TOKEN(var) var = (atoi(s)!=0); s = skip_token(s)
+ if(global_settings.autoloadbookmark == BOOKMARK_NO)
+ return BOOKMARK_DONT_RESUME;
- /* if new format bookmark, extract the optional content flags,
- otherwise treat as an original format bookmark */
- int opt_flags = 0;
- bool new_format = (strchr(s, '>') == s);
- if (new_format)
+ /*Checking to see if a bookmark file exists.*/
+ if(!generate_bookmark_file_name(bm_filename, sizeof(bm_filename), file, -1))
{
- s++;
- GET_INT_TOKEN(opt_flags);
+ return BOOKMARK_DONT_RESUME;
}
- /* extract all original bookmark tokens */
- GET_INT_TOKEN(bm.resume_index);
- GET_LONG_TOKEN(bm.resume_offset);
- GET_INT_TOKEN(bm.resume_seed);
- if (!new_format) /* skip deprecated token */
- s = skip_token(s);
- GET_LONG_TOKEN(bm.resume_time);
- GET_INT_TOKEN(bm.repeat_mode);
- GET_BOOL_TOKEN(bm.shuffle);
-
- /* extract all optional bookmark tokens */
- if (opt_flags & BM_PITCH)
- GET_INT_TOKEN(bm.pitch);
- if (opt_flags & BM_SPEED)
- GET_INT_TOKEN(bm.speed);
+ if(!file_exists(bm_filename))
+ return BOOKMARK_DONT_RESUME;
- if (*s == 0)
+ if(global_settings.autoloadbookmark == BOOKMARK_YES)
{
- return false;
+ return (bookmark_load(bm_filename, true)
+ ? BOOKMARK_DO_RESUME : BOOKMARK_DONT_RESUME);
}
-
- end = strchr(s, ';');
-
- /* extract file names */
- if (parse_filenames)
+ else
{
- size_t len = (end == NULL) ? strlen(s) : (size_t) (end - s);
- len = MIN(TEMP_BUF_SIZE - 1, len);
- strlcpy(global_temp_buffer, s, len + 1);
+ int ret = select_bookmark(bm_filename, true, &bookmark);
- if (end != NULL)
+ if (bookmark != NULL)
{
- end++;
- if (strip_dir)
- {
- s = strrchr(end, '/');
- if (s)
- {
- end = s;
- end++;
- }
- }
- strlcpy(global_filename, end, MAX_PATH);
+ if (!play_bookmark(bookmark))
+ return BOOKMARK_CANCEL;
+ return BOOKMARK_DO_RESUME;
}
- }
- return true;
+ return (ret != BOOKMARK_SUCCESS) ? BOOKMARK_CANCEL : BOOKMARK_DONT_RESUME;
+ }
}
/* ----------------------------------------------------------------------- */
-/* This function is used by multiple functions and is used to generate a */
-/* bookmark named based off of the input. */
-/* Changing this function could result in how the bookmarks are stored. */
-/* it would be here that the centralized/decentralized bookmark code */
-/* could be placed. */
-/* Returns true if the file name is generated, false if it was too long */
-/* ----------------------------------------------------------------------- */
-static bool generate_bookmark_file_name(const char *in)
+/* This function loads the bookmark information into the resume memory. */
+/* This is an interface function. */
+/* Returns true on successful bookmark load. */
+/* ------------------------------------------------------------------------*/
+bool bookmark_load(const char* file, bool autoload)
{
- /* if this is a root dir MP3, rename the bookmark file root_dir.bmark */
- /* otherwise, name it based on the in variable */
- if (!strcmp("/", in))
- strcpy(global_bookmark_file_name, "/root_dir.bmark");
- else
- {
-#ifdef HAVE_MULTIVOLUME
- /* The "root" of an extra volume need special handling too. */
- const char *filename;
- path_strip_volume(in, &filename, true);
- bool volume_root = *filename == '\0';
-#endif
- size_t len = strlcpy(global_bookmark_file_name, in, MAX_PATH);
- if(len >= MAX_PATH)
- return false;
+ logf("%s", __func__);
+ int fd;
+ char* bookmark = NULL;
- if(global_bookmark_file_name[len-1] == '/') {
- global_bookmark_file_name[len-1] = '\0';
- len--;
+ if(autoload)
+ {
+ fd = open(file, O_RDONLY);
+ if(fd >= 0)
+ {
+ if(read_line(fd, global_temp_buffer, sizeof(global_temp_buffer)) > 0)
+ bookmark=global_temp_buffer;
+ close(fd);
}
+ }
+ else
+ {
+ /* This is not an auto-load, so list the bookmarks */
+ select_bookmark(file, false, &bookmark);
+ }
-#ifdef HAVE_MULTIVOLUME
- if (volume_root)
- len = strlcat(global_bookmark_file_name, "/volume_dir.bmark", MAX_PATH);
- else
-#endif
- len = strlcat(global_bookmark_file_name, ".bmark", MAX_PATH);
+ if (bookmark != NULL)
+ {
+ if (!play_bookmark(bookmark))
+ {
+ /* Selected bookmark not found. */
+ if (!autoload)
+ {
+ splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
+ }
- if(len >= MAX_PATH)
return false;
+ }
}
return true;
@@ -1148,13 +1290,15 @@ static bool generate_bookmark_file_name(const char *in)
/* ----------------------------------------------------------------------- */
bool bookmark_exists(void)
{
+ char bm_filename[MAX_PATH];
bool exist=false;
char* name = playlist_get_name(NULL, global_temp_buffer,
sizeof(global_temp_buffer));
- if (generate_bookmark_file_name(name))
+ if (!playlist_dynamic_only() &&
+ generate_bookmark_file_name(bm_filename, sizeof(bm_filename), name, -1))
{
- exist = file_exists(global_bookmark_file_name);
+ exist = file_exists(bm_filename);
}
return exist;
}
@@ -1172,12 +1316,13 @@ bool bookmark_is_bookmarkable_state(void)
/* no track playing */
(playlist_get_resume_info(&resume_index) == -1) ||
/* invalid queue info */
- (playlist_modified(NULL)))
- /* can't bookmark while in the queue */
+ (playlist_modified(NULL)) ||
+ /* can't bookmark playlists modified by user */
+ (playlist_dynamic_only()))
+ /* can't bookmark playlists without associated folder or playlist file */
{
return false;
}
return true;
}
-
diff --git a/apps/bookmark.h b/apps/bookmark.h
index ff7b87c1bf..192e577ce6 100644
--- a/apps/bookmark.h
+++ b/apps/bookmark.h
@@ -29,11 +29,17 @@ enum {
BOOKMARK_USB_CONNECTED = 1
};
+enum {
+ BOOKMARK_CANCEL,
+ BOOKMARK_DONT_RESUME,
+ BOOKMARK_DO_RESUME
+};
+
int bookmark_load_menu(void);
bool bookmark_autobookmark(bool prompt_ok);
bool bookmark_create_menu(void);
bool bookmark_mrb_load(void);
-bool bookmark_autoload(const char* file);
+int bookmark_autoload(const char* file);
bool bookmark_load(const char* file, bool autoload);
bool bookmark_exists(void);
bool bookmark_is_bookmarkable_state(void);
diff --git a/apps/buffering.c b/apps/buffering.c
index 8661a42ab8..81b861ccf1 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -20,7 +20,6 @@
****************************************************************************/
#include "config.h"
#include <string.h>
-#include "strlcpy.h"
#include "system.h"
#include "storage.h"
#include "thread.h"
@@ -417,7 +416,8 @@ add_handle(unsigned int flags, size_t data_size, const char *path,
h->signaled = 0; /* Data can be waited for */
/* Save the provided path */
- memcpy(h->path, path, pathsize);
+ if (path)
+ memcpy(h->path, path, pathsize);
/* Return the start of the data area */
*data_out = ringbuf_add(index, handlesize);
diff --git a/apps/codecs.c b/apps/codecs.c
index 4d2dd34ce0..9f34d26e14 100644
--- a/apps/codecs.c
+++ b/apps/codecs.c
@@ -203,8 +203,9 @@ static int codec_load_ram(struct codec_api *api)
return CODEC_ERROR;
}
- if (hdr->api_version > CODEC_API_VERSION
- || hdr->api_version < CODEC_MIN_API_VERSION) {
+ if (hdr->api_version != CODEC_API_VERSION ||
+ c_hdr->api_size > sizeof(struct codec_api))
+ {
logf("codec api version error");
lc_close(curr_handle);
curr_handle = NULL;
diff --git a/apps/core_keymap.c b/apps/core_keymap.c
index dbe7ae0072..89e7913c33 100644
--- a/apps/core_keymap.c
+++ b/apps/core_keymap.c
@@ -27,119 +27,68 @@
#include "logf.h"
#if !defined(__PCTOOL__) || defined(CHECKWPS)
-static int keymap_handle = -1;
-
-static int core_alloc_keymap(size_t bufsz)
+int core_set_keyremap(struct button_mapping* core_keymap, int count)
{
- keymap_handle = core_alloc_ex("key remap", bufsz, &buflib_ops_locked);
- return keymap_handle;
+ return action_set_keymap(core_keymap, count);
}
-static void core_free_keymap(void)
+static int open_key_remap(const char *filename, int *countp)
{
- action_set_keymap(NULL, -1);
- if (keymap_handle > 0) /* free old buffer */
+ int fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ size_t fsize = filesize(fd);
+ int count = fsize / sizeof(struct button_mapping);
+ if (count == 0 || (size_t)(count * sizeof(struct button_mapping)) != fsize)
{
- keymap_handle = core_free(keymap_handle);
+ logf("core_keyremap: bad filesize %d / %lu", count, (unsigned long)fsize);
+ goto error;
}
-}
-
-/* Allocates buffer from core and copies keymap into it */
-int core_set_keyremap(struct button_mapping* core_keymap, int count)
-{
- core_free_keymap();
- if (count > 0)
+ struct button_mapping header;
+ if(read(fd, &header, sizeof(header)) != (ssize_t)sizeof(header))
{
- size_t bufsize = count * sizeof(struct button_mapping);
- if (core_keymap != NULL && core_alloc_keymap(bufsize) > 0)
- {
- char *buf = core_get_data(keymap_handle);
- memcpy(buf, core_keymap, bufsize);
- count = action_set_keymap((struct button_mapping *) buf, count);
- }
- else
- count = -1;
+ logf("core_keyremap: read error");
+ goto error;
}
- return count;
-}
-int core_load_key_remap(const char *filename)
-{
- char *buf;
- int fd = -1;
- int count = 0;
- size_t fsize = 0;
- core_free_keymap();
-
- if (filename != NULL)
- count = open_key_remap(filename, &fd, &fsize);
- while (count > 0)
+ if (header.action_code != KEYREMAP_VERSION ||
+ header.button_code != KEYREMAP_HEADERID ||
+ header.pre_button_code != count)
{
- if (core_alloc_keymap(fsize) <= 0)
- {
- count = -30;
- logf("core_keymap: %d Failed to allocate buffer", count);
- break;
- }
- buf = core_get_data(keymap_handle);
- if (read(fd, buf, fsize) == (ssize_t) fsize)
- {
- count = action_set_keymap((struct button_mapping *) buf, count);
- }
- else
- {
- count = -40;
- logf("core_keymap: %d Failed to read", count);
- }
- break;
+ logf("core_keyremap: bad header %d", count);
+ goto error;
}
+
+ *countp = count - 1;
+ return fd;
+
+ error:
close(fd);
- return count;
+ return -1;
}
-int open_key_remap(const char *filename, int *fd, size_t *fsize)
+int core_load_key_remap(const char *filename)
{
- int count = 0;
+ int count = 0; /* gcc falsely believes this may be used uninitialized */
+ int fd = open_key_remap(filename, &count);
+ if (fd < 0)
+ return -1;
- while (filename && fd && fsize)
+ size_t bufsize = count * sizeof(struct button_mapping);
+ int handle = core_alloc(bufsize);
+ if (handle > 0)
{
- *fsize = 0;
- *fd = open(filename, O_RDONLY);
- if (*fd)
- {
- *fsize = filesize(*fd);
-
- count = *fsize / sizeof(struct button_mapping);
+ void *data = core_get_data_pinned(handle);
- if (count * sizeof(struct button_mapping) != *fsize)
- {
- count = -10;
- logf("core_keymap: %d Size mismatch", count);
- break;
- }
+ if (read(fd, data, bufsize) == (ssize_t)bufsize)
+ count = action_set_keymap_handle(handle, count);
- if (count > 1)
- {
- struct button_mapping header = {0};
- read(*fd, &header, sizeof(struct button_mapping));
- if (KEYREMAP_VERSION == header.action_code &&
- KEYREMAP_HEADERID == header.button_code &&
- header.pre_button_code == count)
- {
- count--;
- *fsize -= sizeof(struct button_mapping);
- }
- else /* Header mismatch */
- {
- count = -20;
- logf("core_keymap: %d Header mismatch", count);
- break;
- }
- }
- }
- break;
+ core_put_data_pinned(data);
}
+
+ close(fd);
return count;
}
diff --git a/apps/core_keymap.h b/apps/core_keymap.h
index dad9875364..2077daa685 100644
--- a/apps/core_keymap.h
+++ b/apps/core_keymap.h
@@ -34,13 +34,6 @@
/* Allocates core buffer, copies keymap to allow buttons for actions to be remapped*/
int core_set_keyremap(struct button_mapping* core_keymap, int count);
-/* open_key_remap(filename , *fd (you must close file_descriptor), *fsize)
- * checks/strips header and returns remaining count
- * fd is opened and set to first record
- * filesize contains the size of the remaining records
-*/
-int open_key_remap(const char *filename, int *fd, size_t *filesize);
-
/* load a remap file to allow buttons for actions to be remapped */
int core_load_key_remap(const char *filename);
diff --git a/apps/cuesheet.c b/apps/cuesheet.c
index 98040f9992..bbdc93746e 100644
--- a/apps/cuesheet.c
+++ b/apps/cuesheet.c
@@ -58,28 +58,28 @@ static bool search_for_cuesheet(const char *path, struct cuesheet_file *cue_file
slash_cuepath = &cuepath[slash - path];
dot = strrchr(slash_cuepath, '.');
if (dot)
- strlcpy(dot, ".cue", MAX_PATH - (dot-cuepath));
+ strmemccpy(dot, ".cue", MAX_PATH - (dot-cuepath));
if (!dot || !file_exists(cuepath))
{
strcpy(cuepath, CUE_DIR);
if (strlcat(cuepath, slash, MAX_PATH) >= MAX_PATH)
goto skip; /* overflow */
- char *dot = strrchr(cuepath, '.');
+ dot = strrchr(cuepath, '.');
strcpy(dot, ".cue");
if (!file_exists(cuepath))
{
skip:
if ((len+4) >= MAX_PATH)
return false;
- strlcpy(cuepath, path, MAX_PATH);
+ strmemccpy(cuepath, path, MAX_PATH);
strlcat(cuepath, ".cue", MAX_PATH);
if (!file_exists(cuepath))
return false;
}
}
- strlcpy(cue_file->path, cuepath, MAX_PATH);
+ strmemccpy(cue_file->path, cuepath, MAX_PATH);
return true;
}
@@ -91,7 +91,7 @@ bool look_for_cuesheet_file(struct mp3entry *track_id3, struct cuesheet_file *cu
cue_file->pos = track_id3->embedded_cuesheet.pos;
cue_file->size = track_id3->embedded_cuesheet.size;
cue_file->encoding = track_id3->embedded_cuesheet.encoding;
- strlcpy(cue_file->path, track_id3->path, MAX_PATH);
+ strmemccpy(cue_file->path, track_id3->path, MAX_PATH);
return true;
}
@@ -139,7 +139,7 @@ static unsigned long parse_cue_index(const char *line)
while (isdigit(*line))
{
value = 10 * value + (*line - '0');
- if (value > field_max[field]) /* Sanity check bail early */
+ if (field >= 0 && value > field_max[field]) /* Sanity check bail early */
return 0;
line++;
}
@@ -363,7 +363,7 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
}
else
{
- strlcpy(dest, string, count);
+ strmemccpy(dest, string, count);
}
}
}
@@ -386,7 +386,7 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
strcpy(cue->file, cue->path);
char *slash = strrchr(cue->file, '/');
if (!slash++) slash = cue->file;
- strlcpy(slash, line, MAX_PATH - (slash - cue->file));
+ strmemccpy(slash, line, MAX_PATH - (slash - cue->file));
}
/* If some songs don't have performer info, we copy the cuesheet performer */
@@ -394,10 +394,10 @@ bool parse_cuesheet(struct cuesheet_file *cue_file, struct cuesheet *cue)
for (i = 0; i < cue->track_count; i++)
{
if (*(cue->tracks[i].performer) == '\0')
- strlcpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3);
+ strmemccpy(cue->tracks[i].performer, cue->performer, MAX_NAME*3);
if (*(cue->tracks[i].songwriter) == '\0')
- strlcpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3);
+ strmemccpy(cue->tracks[i].songwriter, cue->songwriter, MAX_NAME*3);
}
return true;
@@ -441,7 +441,7 @@ static const char* list_get_name_cb(int selected_item,
struct cuesheet *cue = (struct cuesheet *)data;
if (selected_item & 1)
- strlcpy(buffer, cue->tracks[selected_item/2].title, buffer_len);
+ strmemccpy(buffer, cue->tracks[selected_item/2].title, buffer_len);
else
snprintf(buffer, buffer_len, "%02d. %s", selected_item/2+1,
cue->tracks[selected_item/2].performer);
@@ -481,7 +481,7 @@ void browse_cuesheet(struct cuesheet *cue)
{
gui_synclist_draw(&lists);
action = get_action(CONTEXT_LIST,TIMEOUT_BLOCK);
- if (gui_synclist_do_button(&lists, &action, LIST_WRAP_UNLESS_HELD))
+ if (gui_synclist_do_button(&lists, &action))
continue;
switch (action)
{
@@ -508,7 +508,7 @@ void browse_cuesheet(struct cuesheet *cue)
/* check that this cue is the same one that would be found by
a search from playback */
char file[MAX_PATH];
- strlcpy(file, cue->file, MAX_PATH);
+ strmemccpy(file, cue->file, MAX_PATH);
if (!strcmp(cue->path, file) || /* if embedded */
(search_for_cuesheet(file, &cue_file) &&
@@ -523,6 +523,8 @@ void browse_cuesheet(struct cuesheet *cue)
case ACTION_STD_CANCEL:
done = true;
+ default:
+ break;
}
}
}
@@ -535,7 +537,7 @@ bool display_cuesheet_content(char* filename)
if (!cue || bufsize < sizeof(struct cuesheet))
return false;
- strlcpy(cue_file.path, filename, MAX_PATH);
+ strmemccpy(cue_file.path, filename, MAX_PATH);
cue_file.pos = 0;
cue_file.size = 0;
@@ -565,12 +567,12 @@ bool curr_cuesheet_skip(struct cuesheet *cue, int direction, unsigned long curr_
if (!(direction <= 0 && track == 0))
{
/* If skipping forward, skip to next cuesheet segment. If skipping
- backward before DEFAULT_SKIP_TRESH milliseconds have elapsed, skip
+ backward before DEFAULT_SKIP_THRESH milliseconds have elapsed, skip
to previous cuesheet segment. If skipping backward after
- DEFAULT_SKIP_TRESH seconds have elapsed, skip to the start of the
+ DEFAULT_SKIP_THRESH seconds have elapsed, skip to the start of the
current cuesheet segment */
if (direction == 1 ||
- ((curr_pos - cue->tracks[track].offset) < DEFAULT_SKIP_TRESH))
+ ((curr_pos - cue->tracks[track].offset) < DEFAULT_SKIP_THRESH))
{
track += direction;
}
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index f510597ad2..5b73f8badd 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -23,13 +23,12 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
-#include <string.h>
+#include <string-extra.h>
#include "lcd.h"
#include "lang.h"
#include "menu.h"
#include "debug_menu.h"
#include "kernel.h"
-#include "structec.h"
#include "action.h"
#include "debug.h"
#include "thread.h"
@@ -210,6 +209,10 @@ static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
*x_offset += 1;
action = ACTION_REDRAW;
}
+ else if (IS_SYSEVENT(action))
+ {
+ return ACTION_REDRAW;
+ }
else if (action != ACTION_UNKNOWN)
{
*x_offset = 0;
@@ -227,7 +230,6 @@ static bool dbg_os(void)
simplelist_info_init(&info, IF_COP("Core and ") "Stack usage:",
MAXTHREADS IF_COP( + NUM_CORES ), &xoffset);
- info.hide_selection = true;
info.scroll_all = false;
info.action_callback = dbg_threads_action_callback;
info.get_name = threads_getname;
@@ -341,7 +343,6 @@ static bool dbg_cpuinfo(void)
info.get_name = get_cpuinfo;
info.action_callback = cpuinfo_cb;
info.timeout = HZ;
- info.hide_selection = true;
info.scroll_all = true;
return simplelist_show_list(&info);
}
@@ -498,6 +499,7 @@ static bool dbg_buffering_thread(void)
#undef STR_DATAREM
}
+#ifdef BUFLIB_DEBUG_PRINT
static const char* bf_getname(int selected_item, void *data,
char *buffer, size_t buffer_len)
{
@@ -517,13 +519,12 @@ static int bf_action_cb(int action, struct gui_synclist* list)
else
{
splash(HZ/1, "Attempting a 64k allocation");
- int handle = core_alloc("test", 64<<10);
+ int handle = core_alloc(64<<10);
splash(HZ/2, (handle > 0) ? "Success":"Fail");
/* for some reason simplelist doesn't allow adding items here if
* info.get_name is given, so use normal list api */
gui_synclist_set_nb_items(list, core_get_num_blocks());
- if (handle > 0)
- core_free(handle);
+ core_free(handle);
}
action = ACTION_REDRAW;
}
@@ -539,6 +540,7 @@ static bool dbg_buflib_allocs(void)
info.timeout = HZ;
return simplelist_show_list(&info);
}
+#endif /* BUFLIB_DEBUG_PRINT */
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
static const char* dbg_partitions_getname(int selected_item, void *data,
@@ -568,7 +570,6 @@ static bool dbg_partitions(void)
struct simplelist_info info;
simplelist_info_init(&info, "Partition Info", NUM_DRIVES * 4, NULL);
info.selection_size = 2;
- info.hide_selection = true;
info.scroll_all = true;
info.get_name = dbg_partitions_getname;
return simplelist_show_list(&info);
@@ -870,7 +871,7 @@ static int tsc2100debug_action_callback(int action, struct gui_synclist *lists)
if (action == ACTION_STD_OK)
{
*page = (*page+1)%3;
- snprintf(lists->title, 32, "tsc2100 registers - Page %d", *page);
+ snprintf((char*)lists->title, 32, "tsc2100 registers - Page %d", *page);
return ACTION_REDRAW;
}
return action;
@@ -1247,7 +1248,8 @@ static int disk_callback(int btn, struct gui_synclist *lists)
int *cardnum = (int*)lists->data;
unsigned char card_name[6];
unsigned char pbuf[32];
- char *title = lists->title;
+ /* Casting away const is safe; the buffer is defined as non-const. */
+ char *title = (char *)lists->title;
static const unsigned char i_vmin[] = { 0, 1, 5, 10, 25, 35, 60, 100 };
static const unsigned char i_vmax[] = { 1, 5, 10, 25, 35, 45, 80, 200 };
static const unsigned char * const kbit_units[] = { "kBit/s", "MBit/s", "GBit/s" };
@@ -1277,7 +1279,7 @@ static int disk_callback(int btn, struct gui_synclist *lists)
{
card_name[i] = card_extract_bits(card->cid, (103-8*i), 8);
}
- strlcpy(card_name, card_name, sizeof(card_name));
+ strmemccpy(card_name, card_name, sizeof(card_name));
simplelist_addline(
"%s Rev %d.%d", card_name,
(int) card_extract_bits(card->cid, 63, 4),
@@ -1630,7 +1632,8 @@ static int ata_smart_attr_to_string(
if (len >= name_sz) len = name_sz-1;
slen += len;
}
- snprintf(str+slen, size-slen, "%s", buf);
+
+ strmemccpy(str+slen, buf, size-slen);
}
return 1; /* ok */
@@ -1721,7 +1724,6 @@ static bool dbg_ata_smart(void)
struct simplelist_info info;
simplelist_info_init(&info, "S.M.A.R.T. Data [CONTEXT to dump]", 1, NULL);
info.action_callback = ata_smart_callback;
- info.hide_selection = true;
info.scroll_all = true;
return simplelist_show_list(&info);
}
@@ -1753,10 +1755,16 @@ static bool dbg_identify_info(void)
int fd = creat("/identify_info.bin", 0666);
if(fd >= 0)
{
+ const unsigned short *identify_info = ata_get_identify();
#ifdef ROCKBOX_LITTLE_ENDIAN
- ecwrite(fd, ata_get_identify(), SECTOR_SIZE/2, "s", true);
+ /* this is a pointer to a driver buffer so we can't modify it */
+ for (int i = 0; i < SECTOR_SIZE/2; ++i)
+ {
+ unsigned short word = swap16(identify_info[i]);
+ write(fd, &word, 2);
+ }
#else
- write(fd, ata_get_identify(), SECTOR_SIZE);
+ write(fd, identify_info, SECTOR_SIZE);
#endif
close(fd);
}
@@ -1775,7 +1783,6 @@ static bool dbg_disk_info(void)
info.title = title;
#endif
info.action_callback = disk_callback;
- info.hide_selection = true;
info.scroll_all = true;
return simplelist_show_list(&info);
}
@@ -1844,7 +1851,6 @@ static bool dbg_dircache_info(void)
int syncbuild = 0;
simplelist_info_init(&info, "Dircache Info", 8, &syncbuild);
info.action_callback = dircache_callback;
- info.hide_selection = true;
info.scroll_all = true;
return simplelist_show_list(&info);
}
@@ -1857,6 +1863,7 @@ static int database_callback(int btn, struct gui_synclist *lists)
(void)lists;
struct tagcache_stat *stat = tagcache_get_stat();
static bool synced = false;
+ static int update_entries = 0;
simplelist_set_line_count(0);
@@ -1868,6 +1875,8 @@ static int database_callback(int btn, struct gui_synclist *lists)
stat->ramcache ? "Yes" : "No");
simplelist_addline("RAM: %d/%d B",
stat->ramcache_used, stat->ramcache_allocated);
+ simplelist_addline("Total entries: %d",
+ stat->total_entries);
simplelist_addline("Progress: %d%% (%d entries)",
stat->progress, stat->processed_entries);
simplelist_addline("Curfile: %s",
@@ -1889,12 +1898,19 @@ static int database_callback(int btn, struct gui_synclist *lists)
if (!btn && stat->curentry)
{
synced = true;
- return ACTION_REDRAW;
+ if (update_entries <= stat->processed_entries)
+ {
+ update_entries = stat->processed_entries + 100;
+ return ACTION_REDRAW;
+ }
+ return ACTION_NONE;
}
if (btn == ACTION_STD_CANCEL)
+ {
+ update_entries = 0;
tagcache_screensync_enable(false);
-
+ }
return btn;
}
static bool dbg_tagcache_info(void)
@@ -1902,7 +1918,6 @@ static bool dbg_tagcache_info(void)
struct simplelist_info info;
simplelist_info_init(&info, "Database Info", 8, NULL);
info.action_callback = database_callback;
- info.hide_selection = true;
info.scroll_all = true;
/* Don't do nonblock here, must give enough processing time
@@ -2175,7 +2190,6 @@ static bool dbg_fm_radio(void)
radio_hardware_present() ? "yes" : "no");
info.action_callback = radio_hardware_present()?radio_callback : NULL;
- info.hide_selection = true;
return simplelist_show_list(&info);
}
#endif /* CONFIG_TUNER */
@@ -2211,7 +2225,7 @@ static bool dbg_set_memory_guard(void)
};
int mode = system_memory_guard(MEMGUARD_KEEP);
- set_option( "Catch mem accesses", &mode, INT, names, MAXMEMGUARD, NULL);
+ set_option( "Catch mem accesses", &mode, RB_INT, names, MAXMEMGUARD, NULL);
system_memory_guard(mode);
return false;
@@ -2304,11 +2318,6 @@ static bool cpu_boost_log(void)
static bool cpu_boost_log_dump(void)
{
int fd;
-#if CONFIG_RTC
- struct tm *nowtm;
- char fname[MAX_PATH];
-#endif
-
int count = cpu_boost_log_getcount();
char *str = cpu_boost_log_getlog_first();
@@ -2319,11 +2328,12 @@ static bool cpu_boost_log_dump(void)
return false;
#if CONFIG_RTC
- nowtm = get_time();
- snprintf(fname, MAX_PATH, "%s/boostlog_%04d%02d%02d%02d%02d%02d.txt", ROCKBOX_DIR,
- nowtm->tm_year + 1900, nowtm->tm_mon + 1, nowtm->tm_mday,
- nowtm->tm_hour, nowtm->tm_min, nowtm->tm_sec);
- fd = open(fname, O_CREAT|O_WRONLY|O_TRUNC);
+ char fname[MAX_PATH];
+ struct tm *nowtm = get_time();
+ fd = open_pathfmt(fname, sizeof(fname), O_CREAT|O_WRONLY|O_TRUNC,
+ "%s/boostlog_%04d%02d%02d%02d%02d%02d.txt", ROCKBOX_DIR,
+ nowtm->tm_year + 1900, nowtm->tm_mon + 1, nowtm->tm_mday,
+ nowtm->tm_hour, nowtm->tm_min, nowtm->tm_sec);
#else
fd = open(ROCKBOX_DIR "/boostlog.txt", O_CREAT|O_WRONLY|O_TRUNC, 0666);
#endif
@@ -2447,7 +2457,6 @@ static bool dbg_talk(void)
else
simplelist_info_init(&list, "Voice Information:", 2, &data);
list.scroll_all = true;
- list.hide_selection = true;
list.timeout = HZ;
list.get_name = dbg_talk_get_name;
@@ -2487,7 +2496,6 @@ static bool dbg_isp1583(void)
isp1583.scroll_all = true;
simplelist_info_init(&isp1583, "ISP1583", dbg_usb_num_items(), NULL);
isp1583.timeout = HZ/100;
- isp1583.hide_selection = true;
isp1583.get_name = dbg_usb_item;
isp1583.action_callback = isp1583_action_callback;
return simplelist_show_list(&isp1583);
@@ -2513,67 +2521,12 @@ static bool dbg_pic(void)
pic.scroll_all = true;
simplelist_info_init(&pic, "PIC", pic_dbg_num_items(), NULL);
pic.timeout = HZ/100;
- pic.hide_selection = true;
pic.get_name = pic_dbg_item;
pic.action_callback = pic_action_callback;
return simplelist_show_list(&pic);
}
#endif
-static bool dbg_skin_engine(void)
-{
- struct simplelist_info info;
- int i, total = 0;
-#if defined(HAVE_BACKDROP_IMAGE)
- int ref_count;
- char *path;
- size_t bytes;
- int path_prefix_len = strlen(ROCKBOX_DIR "/wps/");
-#endif
- simplelist_info_init(&info, "Skin engine usage", 0, NULL);
- simplelist_set_line_count(0);
- info.hide_selection = true;
- FOR_NB_SCREENS(j) {
-#if NB_SCREENS > 1
- simplelist_addline("%s display:",
- j == 0 ? "Main" : "Remote");
-#endif
- for (i = 0; i < skin_get_num_skins(); i++) {
- struct skin_stats *stats = skin_get_stats(i, j);
- if (stats->buflib_handles)
- {
- simplelist_addline("Skin ID: %d, %d allocations",
- i, stats->buflib_handles);
- simplelist_addline("\tskin: %d bytes",
- stats->tree_size);
- simplelist_addline("\tImages: %d bytes",
- stats->images_size);
- simplelist_addline("\tTotal: %d bytes",
- stats->tree_size + stats->images_size);
- total += stats->tree_size + stats->images_size;
- }
- }
- }
- simplelist_addline("Skin total usage: %d bytes", total);
-#if defined(HAVE_BACKDROP_IMAGE)
- simplelist_addline("Backdrop Images:");
- i = 0;
- while (skin_backdrop_get_debug(i++, &path, &ref_count, &bytes)) {
- if (ref_count > 0) {
-
- if (!strncasecmp(path, ROCKBOX_DIR "/wps/", path_prefix_len))
- path += path_prefix_len;
- simplelist_addline("%s", path);
- simplelist_addline("\tref_count: %d", ref_count);
- simplelist_addline("\tsize: %d", bytes);
- total += bytes;
- }
- }
- simplelist_addline("Total usage: %d bytes", total);
-#endif
- return simplelist_show_list(&info);
-}
-
#if defined(HAVE_BOOTDATA) && !defined(SIMULATOR)
static bool dbg_boot_data(void)
{
@@ -2611,7 +2564,6 @@ static bool dbg_boot_data(void)
boot_data.payload[i+1], boot_data.payload[i+2], boot_data.payload[i+3]);
}
- info.hide_selection = true;
return simplelist_show_list(&info);
}
#endif /* defined(HAVE_BOOTDATA) && !defined(SIMULATOR) */
@@ -2688,7 +2640,9 @@ static const struct {
#ifdef PM_DEBUG
{ "pm histogram", peak_meter_histogram},
#endif /* PM_DEBUG */
+#ifdef BUFLIB_DEBUG_PRINT
{ "View buflib allocs", dbg_buflib_allocs },
+#endif
#ifndef SIMULATOR
#if CONFIG_TUNER
{ "FM Radio", dbg_fm_radio },
diff --git a/apps/enc_config.c b/apps/enc_config.c
index 65ef65667a..d06ac84b5f 100644
--- a/apps/enc_config.c
+++ b/apps/enc_config.c
@@ -183,7 +183,7 @@ static bool mp3_enc_bitrate(struct menucallback_data *data)
int index = round_value_to_list32(cfg->mp3_enc.bitrate, rate_list,
n_rates, false);
- bool res = set_option(str(LANG_BITRATE), &index, INT,
+ bool res = set_option(str(LANG_BITRATE), &index, RB_INT,
items, n_rates, NULL);
index = round_value_to_list32(rate_list[index], mp3_enc_bitr,
MP3_ENC_NUM_BITR, false);
@@ -193,9 +193,9 @@ static bool mp3_enc_bitrate(struct menucallback_data *data)
} /* mp3_enc_bitrate */
/* mp3_enc configuration menu */
-MENUITEM_FUNCTION(mp3_bitrate, MENU_FUNC_USEPARAM, ID2P(LANG_BITRATE),
- mp3_enc_bitrate,
- &menu_callback_data, enc_menuitem_callback, Icon_NOICON);
+MENUITEM_FUNCTION_W_PARAM(mp3_bitrate, 0, ID2P(LANG_BITRATE),
+ mp3_enc_bitrate, &menu_callback_data,
+ enc_menuitem_callback, Icon_NOICON);
MAKE_MENU( mp3_enc_menu, ID2P(LANG_ENCODER_SETTINGS),
enc_menuitem_enteritem, Icon_NOICON,
&mp3_bitrate);
@@ -286,7 +286,7 @@ static int enc_menuitem_callback(int action,
{
(void)this_list;
struct menucallback_data *data =
- (struct menucallback_data*)this_item->function->param;
+ (struct menucallback_data*)this_item->function_param->param;
if (action == ACTION_EXIT_MENUITEM)
{
diff --git a/apps/features.txt b/apps/features.txt
index 2262f7502e..bafaa11599 100644
--- a/apps/features.txt
+++ b/apps/features.txt
@@ -296,3 +296,7 @@ hibylinux
(CONFIG_KEYPAD == IRIVER_H10_PAD)
clear_settings_on_hold
#endif
+
+#if defined(HAVE_PERCEPTUAL_VOLUME)
+perceptual_volume
+#endif
diff --git a/apps/filetree.c b/apps/filetree.c
index 1944713d13..eb429c83e3 100644
--- a/apps/filetree.c
+++ b/apps/filetree.c
@@ -51,33 +51,69 @@
#endif
#include "wps.h"
-static int compare_sort_dir; /* qsort key for sorting directories */
+static struct compare_data
+{
+ int sort_dir; /* qsort key for sorting directories */
+ int(*_compar)(const char*, const char*, size_t);
+} cmp_data;
+
+/* dummmy functions to allow compatibility with strncmp & strncasecmp */
+static int strnatcmp_n(const char *a, const char *b, size_t n)
+{
+ (void)n;
+ return strnatcmp(a, b);
+}
+static int strnatcasecmp_n(const char *a, const char *b, size_t n)
+{
+ (void)n;
+ return strnatcasecmp(a, b);
+}
int ft_build_playlist(struct tree_context* c, int start_index)
{
int i;
int start=start_index;
+ int res;
+ struct playlist_info *playlist = playlist_get_current();
tree_lock_cache(c);
struct entry *entries = tree_get_entries(c);
- for(i = 0;i < c->filesindir;i++)
+ struct playlist_insert_context pl_context;
+
+ res = playlist_insert_context_create(playlist, &pl_context,
+ PLAYLIST_REPLACE, false, false);
+ if (res >= 0)
{
- if((entries[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO)
+ cpu_boost(true);
+ for(i = 0;i < c->filesindir;i++)
{
- if (playlist_add(entries[i].name) < 0)
+#if 0 /*only needed if displaying progress */
+ /* user abort */
+ if (action_userabort(TIMEOUT_NOBLOCK))
+ {
break;
+ }
+#endif
+ if((entries[i].attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO)
+ {
+ res = playlist_insert_context_add(&pl_context, entries[i].name);
+ if (res < 0)
+ break;
+ }
+ else
+ {
+ /* Adjust the start index when se skip non-MP3 entries */
+ if(i < start)
+ start_index--;
+ }
}
- else
- {
- /* Adjust the start index when se skip non-MP3 entries */
- if(i < start)
- start_index--;
- }
+ cpu_boost(false);
}
+
+ playlist_insert_context_release(&pl_context);
tree_unlock_cache(c);
-
return start_index;
}
@@ -89,7 +125,8 @@ int ft_build_playlist(struct tree_context* c, int start_index)
* avoid allocating yet another path buffer on the stack (and save some
* code; the caller typically needs to create the full pathname anyway)...
*/
-bool ft_play_playlist(char* pathname, char* dirname, char* filename, bool skip_dyn_warning)
+bool ft_play_playlist(char* pathname, char* dirname,
+ char* filename, bool skip_warn_and_bookmarks)
{
if (global_settings.party_mode && audio_status())
{
@@ -97,28 +134,19 @@ bool ft_play_playlist(char* pathname, char* dirname, char* filename, bool skip_d
return false;
}
- if (bookmark_autoload(pathname))
+ if (!skip_warn_and_bookmarks)
{
- return false;
+ int res = bookmark_autoload(pathname);
+ if (res == BOOKMARK_CANCEL || res == BOOKMARK_DO_RESUME || !warn_on_pl_erase())
+ return false;
}
splash(0, ID2P(LANG_WAIT));
- /* about to create a new current playlist...
- * allow user to cancel the operation.
- * Do not show if skip_dyn_warning is true */
- if (!skip_dyn_warning)
- {
- if (!warn_on_pl_erase())
- return false;
- }
-
if (playlist_create(dirname, filename) != -1)
{
if (global_settings.playlist_shuffle)
- {
playlist_shuffle(current_tick, -1);
- }
playlist_start(0, 0, 0);
return true;
@@ -198,7 +226,7 @@ static int compare(const void* p1, const void* p2)
if (e1->attr & ATTR_DIRECTORY && e2->attr & ATTR_DIRECTORY)
{ /* two directories */
- criteria = compare_sort_dir;
+ criteria = cmp_data.sort_dir;
#ifdef HAVE_MULTIVOLUME
if (e1->attr & ATTR_VOLUME || e2->attr & ATTR_VOLUME)
@@ -233,41 +261,23 @@ static int compare(const void* p1, const void* p2)
if (t1 != t2) /* if different */
return (t1 - t2) * (criteria == SORT_TYPE_REVERSED ? -1 : 1);
- /* else fall through to alphabetical sorting */
+ /* else alphabetical sorting */
+ return cmp_data._compar(e1->name, e2->name, MAX_PATH);
}
case SORT_DATE:
case SORT_DATE_REVERSED:
- /* Ignore SORT_TYPE */
- if (criteria == SORT_DATE || criteria == SORT_DATE_REVERSED)
- {
- if (e1->time_write != e2->time_write)
- return (e1->time_write - e2->time_write)
- * (criteria == SORT_DATE_REVERSED ? -1 : 1);
- /* else fall through to alphabetical sorting */
- }
-
+ {
+ if (e1->time_write != e2->time_write)
+ return (e1->time_write - e2->time_write)
+ * (criteria == SORT_DATE_REVERSED ? -1 : 1);
+ /* else fall through to alphabetical sorting */
+ }
case SORT_ALPHA:
case SORT_ALPHA_REVERSED:
{
- if (global_settings.sort_case)
- {
- if (global_settings.interpret_numbers == SORT_INTERPRET_AS_NUMBER)
- return strnatcmp(e1->name, e2->name)
- * (criteria == SORT_ALPHA_REVERSED ? -1 : 1);
- else
- return strncmp(e1->name, e2->name, MAX_PATH)
- * (criteria == SORT_ALPHA_REVERSED ? -1 : 1);
- }
- else
- {
- if (global_settings.interpret_numbers == SORT_INTERPRET_AS_NUMBER)
- return strnatcasecmp(e1->name, e2->name)
- * (criteria == SORT_ALPHA_REVERSED ? -1 : 1);
- else
- return strncasecmp(e1->name, e2->name, MAX_PATH)
- * (criteria == SORT_ALPHA_REVERSED ? -1 : 1);
- }
+ return cmp_data._compar(e1->name, e2->name, MAX_PATH) *
+ (criteria == SORT_ALPHA_REVERSED ? -1 : 1);
}
}
@@ -277,12 +287,18 @@ static int compare(const void* p1, const void* p2)
/* load and sort directory into the tree's cache. returns NULL on failure. */
int ft_load(struct tree_context* c, const char* tempdir)
{
+ if (c->out_of_tree > 0) /* something else is loaded */
+ return 0;
+
int files_in_dir = 0;
int name_buffer_used = 0;
struct dirent *entry;
bool (*callback_show_item)(char *, int, struct tree_context *) = NULL;
DIR *dir;
+ if (!c->is_browsing)
+ c->browse = NULL;
+
if (tempdir)
dir = opendir(tempdir);
else
@@ -392,7 +408,22 @@ int ft_load(struct tree_context* c, const char* tempdir)
c->dirlength = files_in_dir;
closedir(dir);
- compare_sort_dir = c->sort_dir;
+ cmp_data.sort_dir = c->sort_dir;
+ if (global_settings.sort_case)
+ {
+ if (global_settings.interpret_numbers == SORT_INTERPRET_AS_NUMBER)
+ cmp_data._compar = strnatcmp_n;
+ else
+ cmp_data._compar = strncmp;
+ }
+ else
+ {
+ if (global_settings.interpret_numbers == SORT_INTERPRET_AS_NUMBER)
+ cmp_data._compar = strnatcasecmp_n;
+ else
+ cmp_data._compar = strncasecmp;
+ }
+
qsort(tree_get_entries(c), files_in_dir, sizeof(struct entry), compare);
/* If thumbnail talking is enabled, make an extra run to mark files with
@@ -488,7 +519,9 @@ int ft_enter(struct tree_context* c)
break;
case FILE_ATTR_AUDIO:
- if (bookmark_autoload(c->currdir))
+ {
+ int res = bookmark_autoload(c->currdir);
+ if (res == BOOKMARK_CANCEL || res == BOOKMARK_DO_RESUME)
break;
splash(0, ID2P(LANG_WAIT));
@@ -522,7 +555,7 @@ int ft_enter(struct tree_context* c)
play = true;
}
break;
-
+ }
#if CONFIG_TUNER
/* fmr preset file */
case FILE_ATTR_FMR:
@@ -674,7 +707,7 @@ int ft_enter(struct tree_context* c)
break;
}
- struct entry* file = tree_get_entry_at(c, c->selected_item);
+ file = tree_get_entry_at(c, c->selected_item);
if (!file)
{
splashf(HZ, str(LANG_READ_FAILED), str(LANG_UNKNOWN));
@@ -733,6 +766,7 @@ int ft_enter(struct tree_context* c)
}
}
}
+
return rc;
}
@@ -775,5 +809,7 @@ int ft_exit(struct tree_context* c)
if (exit_func)
rc = 3;
+ c->out_of_tree = 0;
+
return rc;
}
diff --git a/apps/filetree.h b/apps/filetree.h
index 178ba0e973..7931c3c454 100644
--- a/apps/filetree.h
+++ b/apps/filetree.h
@@ -26,6 +26,7 @@ int ft_load(struct tree_context* c, const char* tempdir);
int ft_enter(struct tree_context* c);
int ft_exit(struct tree_context* c);
int ft_build_playlist(struct tree_context* c, int start_index);
-bool ft_play_playlist(char* pathname, char* dirname, char* filename, bool skip_dyn_warning);
+bool ft_play_playlist(char* pathname, char* dirname,
+ char* filename, bool skip_warn_and_bookmarks);
#endif
diff --git a/apps/filetypes.c b/apps/filetypes.c
index 02d2af282e..bda7018381 100644
--- a/apps/filetypes.c
+++ b/apps/filetypes.c
@@ -38,6 +38,7 @@
#include "splash.h"
#include "core_alloc.h"
#include "icons.h"
+/*#define LOGF_ENABLE*/
#include "logf.h"
/* max filetypes (plugins & icons stored here) */
@@ -45,112 +46,172 @@
/* max viewer plugins */
#define MAX_VIEWERS 56
+static void read_builtin_types_init(void) INIT_ATTR;
+static void read_viewers_config_init(void) INIT_ATTR;
+static void read_config_init(int fd) INIT_ATTR;
+
/* a table for the known file types */
static const struct filetype inbuilt_filetypes[] = {
- { "mp3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mp2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mpa", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mp1", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "ogg", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "oga", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "wma", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "wmv", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "asf", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "wav", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "flac",FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "ac3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "a52", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mpc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "wv", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "m4a", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "m4b", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mp4", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mod", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mpga", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "shn", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "aif", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "aiff",FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "spx" ,FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "opus",FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "sid", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "adx", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "nsf", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "nsfe",FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "spc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "ape", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mac", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "sap" ,FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "rm", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "ra", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "rmvb",FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "cmc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "cm3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "cmr", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "cms", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "dmc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "dlt", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mpt", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mpd", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "rmt", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "tmc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "tm8", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "tm2", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "oma", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "aa3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "at3", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "mmf", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "au", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "snd", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "vox", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "w64", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "tta", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "ay", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "vtx", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "gbs", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "hes", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "sgc", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "vgm", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "vgz", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "kss", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "aac", FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
- { "m3u", FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
- { "m3u8",FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
- { "cfg", FILE_ATTR_CFG, Icon_Config, VOICE_EXT_CFG },
- { "wps", FILE_ATTR_WPS, Icon_Wps, VOICE_EXT_WPS },
+ { "mp3", FILE_ATTR_AUDIO },
+ { "mp2", FILE_ATTR_AUDIO },
+ { "mpa", FILE_ATTR_AUDIO },
+ { "mp1", FILE_ATTR_AUDIO },
+ { "ogg", FILE_ATTR_AUDIO },
+ { "oga", FILE_ATTR_AUDIO },
+ { "wma", FILE_ATTR_AUDIO },
+ { "wmv", FILE_ATTR_AUDIO },
+ { "asf", FILE_ATTR_AUDIO },
+ { "wav", FILE_ATTR_AUDIO },
+ { "flac", FILE_ATTR_AUDIO },
+ { "ac3", FILE_ATTR_AUDIO },
+ { "a52", FILE_ATTR_AUDIO },
+ { "mpc", FILE_ATTR_AUDIO },
+ { "wv", FILE_ATTR_AUDIO },
+ { "m4a", FILE_ATTR_AUDIO },
+ { "m4b", FILE_ATTR_AUDIO },
+ { "mp4", FILE_ATTR_AUDIO },
+ { "mod", FILE_ATTR_AUDIO },
+ { "mpga", FILE_ATTR_AUDIO },
+ { "shn", FILE_ATTR_AUDIO },
+ { "aif", FILE_ATTR_AUDIO },
+ { "aiff", FILE_ATTR_AUDIO },
+ { "spx" , FILE_ATTR_AUDIO },
+ { "opus", FILE_ATTR_AUDIO },
+ { "sid", FILE_ATTR_AUDIO },
+ { "adx", FILE_ATTR_AUDIO },
+ { "nsf", FILE_ATTR_AUDIO },
+ { "nsfe", FILE_ATTR_AUDIO },
+ { "spc", FILE_ATTR_AUDIO },
+ { "ape", FILE_ATTR_AUDIO },
+ { "mac", FILE_ATTR_AUDIO },
+ { "sap" , FILE_ATTR_AUDIO },
+ { "rm", FILE_ATTR_AUDIO },
+ { "ra", FILE_ATTR_AUDIO },
+ { "rmvb", FILE_ATTR_AUDIO },
+ { "cmc", FILE_ATTR_AUDIO },
+ { "cm3", FILE_ATTR_AUDIO },
+ { "cmr", FILE_ATTR_AUDIO },
+ { "cms", FILE_ATTR_AUDIO },
+ { "dmc", FILE_ATTR_AUDIO },
+ { "dlt", FILE_ATTR_AUDIO },
+ { "mpt", FILE_ATTR_AUDIO },
+ { "mpd", FILE_ATTR_AUDIO },
+ { "rmt", FILE_ATTR_AUDIO },
+ { "tmc", FILE_ATTR_AUDIO },
+ { "tm8", FILE_ATTR_AUDIO },
+ { "tm2", FILE_ATTR_AUDIO },
+ { "oma", FILE_ATTR_AUDIO },
+ { "aa3", FILE_ATTR_AUDIO },
+ { "at3", FILE_ATTR_AUDIO },
+ { "mmf", FILE_ATTR_AUDIO },
+ { "au", FILE_ATTR_AUDIO },
+ { "snd", FILE_ATTR_AUDIO },
+ { "vox", FILE_ATTR_AUDIO },
+ { "w64", FILE_ATTR_AUDIO },
+ { "tta", FILE_ATTR_AUDIO },
+ { "ay", FILE_ATTR_AUDIO },
+ { "vtx", FILE_ATTR_AUDIO },
+ { "gbs", FILE_ATTR_AUDIO },
+ { "hes", FILE_ATTR_AUDIO },
+ { "sgc", FILE_ATTR_AUDIO },
+ { "vgm", FILE_ATTR_AUDIO },
+ { "vgz", FILE_ATTR_AUDIO },
+ { "kss", FILE_ATTR_AUDIO },
+ { "aac", FILE_ATTR_AUDIO },
+ { "m3u", FILE_ATTR_M3U },
+ { "m3u8", FILE_ATTR_M3U },
+ { "cfg", FILE_ATTR_CFG },
+ { "wps", FILE_ATTR_WPS },
#ifdef HAVE_REMOTE_LCD
- { "rwps",FILE_ATTR_RWPS, Icon_Wps, VOICE_EXT_RWPS },
+ { "rwps", FILE_ATTR_RWPS },
#endif
#if CONFIG_TUNER
- { "fmr", FILE_ATTR_FMR, Icon_Preset, LANG_FMR },
- { "fms", FILE_ATTR_FMS, Icon_Wps, VOICE_EXT_FMS },
+ { "fmr", FILE_ATTR_FMR },
+ { "fms", FILE_ATTR_FMS },
#endif
- { "lng", FILE_ATTR_LNG, Icon_Language, LANG_LANGUAGE },
- { "rock",FILE_ATTR_ROCK,Icon_Plugin, VOICE_EXT_ROCK },
- { "lua", FILE_ATTR_LUA, Icon_Plugin, VOICE_EXT_ROCK },
- { "opx", FILE_ATTR_OPX, Icon_Plugin, VOICE_EXT_ROCK },
- { "fnt", FILE_ATTR_FONT,Icon_Font, VOICE_EXT_FONT },
- { "kbd", FILE_ATTR_KBD, Icon_Keyboard, VOICE_EXT_KBD },
- { "bmark",FILE_ATTR_BMARK, Icon_Bookmark, VOICE_EXT_BMARK },
- { "cue", FILE_ATTR_CUE, Icon_Bookmark, VOICE_EXT_CUESHEET },
- { "sbs", FILE_ATTR_SBS, Icon_Wps, VOICE_EXT_SBS },
+ { "log", FILE_ATTR_LOG },
+ { "lng", FILE_ATTR_LNG },
+ { "rock", FILE_ATTR_ROCK },
+ { "lua", FILE_ATTR_LUA },
+ { "opx", FILE_ATTR_OPX },
+ { "fnt", FILE_ATTR_FONT },
+ { "kbd", FILE_ATTR_KBD },
+ { "bmark",FILE_ATTR_BMARK },
+ { "cue", FILE_ATTR_CUE },
+ { "sbs", FILE_ATTR_SBS },
#ifdef HAVE_REMOTE_LCD
- { "rsbs", FILE_ATTR_RSBS, Icon_Wps, VOICE_EXT_RSBS },
+ { "rsbs", FILE_ATTR_RSBS },
#if CONFIG_TUNER
- { "rfms", FILE_ATTR_RFMS, Icon_Wps, VOICE_EXT_RFMS },
+ { "rfms", FILE_ATTR_RFMS },
#endif
#endif
#ifdef BOOTFILE_EXT
- { BOOTFILE_EXT, FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ },
+ { BOOTFILE_EXT, FILE_ATTR_MOD },
#endif
#ifdef BOOTFILE_EXT2
- { BOOTFILE_EXT2, FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ },
+ { BOOTFILE_EXT2, FILE_ATTR_MOD },
+#endif
+};
+
+struct fileattr_icon_voice {
+ int tree_attr;
+ uint16_t icon;
+ uint16_t voiceclip;
+};
+
+/* a table for the known file types icons & voice clips */
+static const struct fileattr_icon_voice inbuilt_attr_icons_voices[] = {
+ { FILE_ATTR_AUDIO, Icon_Audio, VOICE_EXT_MPA },
+ { FILE_ATTR_M3U, Icon_Playlist, LANG_PLAYLIST },
+ { FILE_ATTR_CFG, Icon_Config, VOICE_EXT_CFG },
+ { FILE_ATTR_WPS, Icon_Wps, VOICE_EXT_WPS },
+#ifdef HAVE_REMOTE_LCD
+ {FILE_ATTR_RWPS, Icon_Wps, VOICE_EXT_RWPS },
+#endif
+#if CONFIG_TUNER
+ { FILE_ATTR_FMR, Icon_Preset, LANG_FMR },
+ { FILE_ATTR_FMS, Icon_Wps, VOICE_EXT_FMS },
+#endif
+ { FILE_ATTR_LNG, Icon_Language, LANG_LANGUAGE },
+ { FILE_ATTR_ROCK, Icon_Plugin, VOICE_EXT_ROCK },
+ { FILE_ATTR_LUA, Icon_Plugin, VOICE_EXT_ROCK },
+ { FILE_ATTR_OPX, Icon_Plugin, VOICE_EXT_ROCK },
+ { FILE_ATTR_FONT, Icon_Font, VOICE_EXT_FONT },
+ { FILE_ATTR_KBD, Icon_Keyboard, VOICE_EXT_KBD },
+ { FILE_ATTR_BMARK, Icon_Bookmark, VOICE_EXT_BMARK },
+ { FILE_ATTR_CUE, Icon_Bookmark, VOICE_EXT_CUESHEET },
+ { FILE_ATTR_SBS, Icon_Wps, VOICE_EXT_SBS },
+#ifdef HAVE_REMOTE_LCD
+ { FILE_ATTR_RSBS, Icon_Wps, VOICE_EXT_RSBS },
+#if CONFIG_TUNER
+ { FILE_ATTR_RFMS, Icon_Wps, VOICE_EXT_RFMS },
+#endif
+#endif
+#if defined(BOOTFILE_EXT) || defined(BOOTFILE_EXT2)
+ { FILE_ATTR_MOD, Icon_Firmware, VOICE_EXT_AJZ },
#endif
};
-void tree_get_filetypes(const struct filetype** types, int* count)
+long tree_get_filetype_voiceclip(int attr)
{
- *types = inbuilt_filetypes;
- *count = sizeof(inbuilt_filetypes) / sizeof(*inbuilt_filetypes);
+ if (global_settings.talk_filetype)
+ {
+ size_t count = ARRAY_SIZE(inbuilt_attr_icons_voices);
+ /* try to find a voice ID for the extension, if known */
+ attr &= FILE_ATTR_MASK; /* file type */
+
+ for (size_t i = count - 1; i < count; i--)
+ {
+ if (attr == inbuilt_attr_icons_voices[i].tree_attr)
+ {
+ logf("%s found attr %d id %d", __func__, attr,
+ inbuilt_attr_icons_voices[i].voiceclip);
+ return inbuilt_attr_icons_voices[i].voiceclip;
+ }
+ }
+ }
+ logf("%s not found attr %d", __func__, attr);
+ return -1;
}
#define ROCK_EXTENSION "rock"
@@ -244,8 +305,6 @@ static int find_extension(const char* extension)
return -1;
}
-static void read_builtin_types(void);
-static void read_config(int fd);
#ifdef HAVE_LCD_COLOR
/* Colors file format is similar to icons:
* ext:hex_color
@@ -262,9 +321,9 @@ void read_color_theme_file(void) {
unknown_file.color = -1;
if (!global_settings.colors_file[0] || global_settings.colors_file[0] == '-')
return;
- snprintf(buffer, MAX_PATH, THEME_DIR "/%s.colours",
- global_settings.colors_file);
- fd = open(buffer, O_RDONLY);
+
+ fd = open_pathfmt(buffer, sizeof(buffer), O_RDONLY,
+ THEME_DIR "/%s.colours", global_settings.colors_file);
if (fd < 0)
return;
while (read_line(fd, buffer, MAX_PATH) > 0)
@@ -303,11 +362,11 @@ void read_viewer_theme_file(void)
custom_filetype_icons[i] = filetypes[i].icon;
}
- snprintf(buffer, MAX_PATH, "%s/%s.icons", ICON_DIR,
- global_settings.viewers_icon_file);
- fd = open(buffer, O_RDONLY);
+ fd = open_pathfmt(buffer, sizeof(buffer), O_RDONLY,
+ ICON_DIR "/%s.icons", global_settings.viewers_icon_file);
if (fd < 0)
return;
+
while (read_line(fd, buffer, MAX_PATH) > 0)
{
if (!settings_parseline(buffer, &ext, &icon))
@@ -339,7 +398,7 @@ void read_viewer_theme_file(void)
custom_icons_loaded = true;
}
-static void read_viewers_config(void)
+static void read_viewers_config_init(void)
{
int fd = open(VIEWERS_CONFIG, O_RDONLY);
if(fd < 0)
@@ -351,18 +410,18 @@ static void read_viewers_config(void)
/* estimate bufsize with the filesize, will not be larger */
strdup_bufsize = (size_t)filesz;
- strdup_handle = core_alloc_ex("filetypes", strdup_bufsize, &ops);
+ strdup_handle = core_alloc_ex(strdup_bufsize, &ops);
if(strdup_handle <= 0)
goto out;
- read_config(fd);
- core_shrink(strdup_handle, core_get_data(strdup_handle), strdup_cur_idx);
+ read_config_init(fd);
+ core_shrink(strdup_handle, NULL, strdup_cur_idx);
out:
close(fd);
}
-void filetype_init(void)
+void filetype_init(void)
{
/* set the directory item first */
filetypes[0].extension = NULL;
@@ -373,8 +432,8 @@ void filetype_init(void)
viewer_count = 0;
filetype_count = 1;
- read_builtin_types();
- read_viewers_config();
+ read_builtin_types_init();
+ read_viewers_config_init();
read_viewer_theme_file();
#ifdef HAVE_LCD_COLOR
read_color_theme_file();
@@ -397,22 +456,35 @@ static void rm_whitespaces(char* str)
*s = '\0';
}
-static void read_builtin_types(void)
+static void read_builtin_types_init(void)
{
- int count = sizeof(inbuilt_filetypes)/sizeof(*inbuilt_filetypes), i;
- for(i=0; i<count && (filetype_count < MAX_FILETYPES); i++)
+ int tree_attr;
+ size_t count = ARRAY_SIZE(inbuilt_filetypes);
+ size_t icon_count = ARRAY_SIZE(inbuilt_attr_icons_voices);
+ for(size_t i = 0; (i < count) && (filetype_count < MAX_FILETYPES); i++)
{
filetypes[filetype_count].extension = inbuilt_filetypes[i].extension;
filetypes[filetype_count].plugin = NULL;
- filetypes[filetype_count].attr = inbuilt_filetypes[i].tree_attr>>8;
+
+ tree_attr = inbuilt_filetypes[i].tree_attr;
+ filetypes[filetype_count].attr = tree_attr>>8;
if (filetypes[filetype_count].attr > highest_attr)
highest_attr = filetypes[filetype_count].attr;
- filetypes[filetype_count].icon = inbuilt_filetypes[i].icon;
+
+ filetypes[filetype_count].icon = unknown_file.icon;
+ for (size_t j = icon_count - 1; j < icon_count; j--)
+ {
+ if (tree_attr == inbuilt_attr_icons_voices[j].tree_attr)
+ {
+ filetypes[filetype_count].icon = inbuilt_attr_icons_voices[j].icon;
+ break;
+ }
+ }
filetype_count++;
}
}
-static void read_config(int fd)
+static void read_config_init(int fd)
{
char line[64], *s, *e;
char *extension, *plugin;
@@ -618,7 +690,7 @@ int filetype_list_viewers(const char* current_file)
int i = viewers[info.selection];
snprintf(plugin, MAX_PATH, "%s/%s." ROCK_EXTENSION,
PLUGIN_DIR, filetypes[i].plugin);
- plugin_load(plugin, current_file);
+ ret = plugin_load(plugin, current_file);
}
return ret;
}
diff --git a/apps/filetypes.h b/apps/filetypes.h
index efe9f3f5df..2886fa2850 100644
--- a/apps/filetypes.h
+++ b/apps/filetypes.h
@@ -48,19 +48,20 @@
#define FILE_ATTR_FMS 0x1200 /* FM screen skin file */
#define FILE_ATTR_RFMS 0x1300 /* FM screen skin file */
#define FILE_ATTR_OPX 0x1400 /* open plugins shortcut */
+#define FILE_ATTR_LOG 0x1500 /* log file */
#define FILE_ATTR_MASK 0xFF00 /* which bits tree.c uses for file types */
struct filetype {
char* extension;
int tree_attr;
- enum themable_icons icon;
- int voiceclip;
};
-void tree_get_filetypes(const struct filetype**, int*) INIT_ATTR;
+
+long tree_get_filetype_voiceclip(int attr);
/* init the filetypes structs.
uses audio buffer for storage, so call early in init... */
void filetype_init(void) INIT_ATTR;
+
void read_viewer_theme_file(void);
#ifdef HAVE_LCD_COLOR
void read_color_theme_file(void);
diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c
index a67ac8cb0a..bebff821f8 100644
--- a/apps/gui/bitmap/list-skinned.c
+++ b/apps/gui/bitmap/list-skinned.c
@@ -213,8 +213,7 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
if (list_start_item+cur_line+1 > list->nb_items)
break;
current_drawing_line = list_start_item+cur_line;
- is_selected = list->show_selection_marker &&
- list_start_item+cur_line == list->selected_item;
+ is_selected = list_start_item+cur_line == list->selected_item;
for (viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), listcfg[screen]->data->tree);
viewport;
diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c
index 53874a8dfa..c10f0082d3 100644
--- a/apps/gui/bitmap/list.c
+++ b/apps/gui/bitmap/list.c
@@ -103,7 +103,7 @@ static void _default_listdraw_fn(struct list_putlineinfo_t *list_info)
bool show_cursor = list_info->show_cursor;
bool have_icons = list_info->have_icons;
struct line_desc *linedes = list_info->linedes;
- char *dsp_text = list_info->dsp_text;
+ const char *dsp_text = list_info->dsp_text;
if (is_title)
{
@@ -196,10 +196,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
const int list_start_item = list->start_item[screen];
const bool scrollbar_in_left = (list->scrollbar == SCROLLBAR_LEFT);
const bool scrollbar_in_right = (list->scrollbar == SCROLLBAR_RIGHT);
-
- const bool show_cursor = list->show_selection_marker &&
- (list->cursor_style == SYNCLIST_CURSOR_NOSTYLE);
-
+ const bool show_cursor = (list->cursor_style == SYNCLIST_CURSOR_NOSTYLE);
const bool have_icons = list->callback_get_item_icon && list->show_icons;
struct viewport *parent = (list->parent[screen]);
@@ -329,14 +326,16 @@ void list_draw(struct screen *display, struct gui_synclist *list)
unsigned const char *s;
char entry_buffer[MAX_PATH];
unsigned char *entry_name;
- const int text_pos = 0; /* UNUSED */
int line = i - start;
int line_indent = 0;
int style = STYLE_DEFAULT;
bool is_selected = false;
s = list->callback_get_item_name(i, list->data, entry_buffer,
sizeof(entry_buffer));
- entry_name = P2STR(s);
+ if (P2ID((unsigned char *)s) > VOICEONLY_DELIMITER)
+ entry_name = "";
+ else
+ entry_name = P2STR(s);
while (*entry_name == '\t')
{
@@ -355,7 +354,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
/* position the string at the correct offset place */
int item_width,h;
display->getstringsize(entry_name, &item_width, &h);
- item_offset = gui_list_get_item_offset(list, item_width, text_pos,
+ item_offset = gui_list_get_item_offset(list, item_width, indent + (list->show_icons ? icon_w : 0),
display, list_text_vp);
/* draw the selected line */
@@ -365,8 +364,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
!hide_selection &&
#endif
i >= list->selected_item
- && i < list->selected_item + list->selected_size
- && list->show_selection_marker)
+ && i < list->selected_item + list->selected_size)
{/* The selected item must be displayed scrolling */
#ifdef HAVE_LCD_COLOR
if (list->selection_color)
diff --git a/apps/gui/color_picker.c b/apps/gui/color_picker.c
index a32f1ee179..ef17c0a230 100644
--- a/apps/gui/color_picker.c
+++ b/apps/gui/color_picker.c
@@ -154,7 +154,6 @@ static void draw_screen(struct screen *display, char *title,
{
unsigned text_color = LCD_BLACK;
unsigned background_color = LCD_WHITE;
- char buf[32];
int i, char_height, line_height;
int max_label_width;
int text_x, text_top;
@@ -253,17 +252,16 @@ static void draw_screen(struct screen *display, char *title,
set_drawinfo(display, mode, fg, bg);
/* Draw label */
- buf[0] = str(LANG_COLOR_RGB_LABELS)[i];
- buf[1] = '\0';
vp.flags &= ~VP_FLAG_ALIGNMENT_MASK;
- display->putsxy(text_x, text_top, buf);
+ display->putsxyf(text_x, text_top, "%c", str(LANG_COLOR_RGB_LABELS)[i]);
/* Draw color value */
+ vp.flags |= VP_FLAG_ALIGN_RIGHT;
if (display->depth >= 24)
- snprintf(buf, 4, "%03d", rgb->rgb_val[i] & 0xFF);
+ display->putsxyf(text_x, text_top, "%03d", rgb->rgb_val[i] & 0xFF);
else
- snprintf(buf, 3, "%02d", rgb->rgb_val[i] & 0x3F);
- vp.flags |= VP_FLAG_ALIGN_RIGHT;
- display->putsxy(text_x, text_top, buf);
+ display->putsxyf(text_x, text_top, "%02d", rgb->rgb_val[i] & 0x3F);
+
+
/* Draw scrollbar */
gui_scrollbar_draw(display, /* screen */
@@ -280,9 +278,6 @@ static void draw_screen(struct screen *display, char *title,
text_top += line_height;
} /* end for */
- /* Format RGB: #rrggbb */
- snprintf(buf, sizeof(buf), str(LANG_COLOR_RGB_VALUE),
- rgb->red, rgb->green, rgb->blue);
vp.flags |= VP_FLAG_ALIGN_CENTER;
if (display->depth >= 16)
{
@@ -301,8 +296,9 @@ static void draw_screen(struct screen *display, char *title,
/* Draw RGB: #rrggbb in middle of swatch */
set_drawinfo(display, DRMODE_FG, get_black_or_white(rgb),
background_color);
-
- display->putsxy(0, top + (height - char_height) / 2, buf);
+ /* Format RGB: #rrggbb */
+ display->putsxyf(0, top + (height - char_height) / 2,
+ str(LANG_COLOR_RGB_VALUE), rgb->red, rgb->green, rgb->blue);
/* Draw border around the rect */
set_drawinfo(display, DRMODE_SOLID, text_color, background_color);
@@ -318,7 +314,9 @@ static void draw_screen(struct screen *display, char *title,
if (height >= char_height)
{
set_drawinfo(display, DRMODE_SOLID, text_color, background_color);
- display->putsxy(0, top + (height - char_height) / 2, buf);
+ /* Format RGB: #rrggbb */
+ display->putsxyf(0, top + (height - char_height) / 2,
+ str(LANG_COLOR_RGB_VALUE), rgb->red, rgb->green, rgb->blue);
}
}
diff --git a/apps/gui/folder_select.c b/apps/gui/folder_select.c
index cef95e179e..a76d77562b 100644
--- a/apps/gui/folder_select.c
+++ b/apps/gui/folder_select.c
@@ -185,7 +185,7 @@ static struct folder* load_folder(struct folder* parent, char *folder)
if (len >= sizeof(fullpath))
goto fail;
}
- strlcpy(&fullpath[len], folder, sizeof(fullpath) - len);
+ strmemccpy(&fullpath[len], folder, sizeof(fullpath) - len);
logf("load_folder: [%s]", fullpath);
dir = opendir(fullpath);
@@ -208,7 +208,7 @@ static struct folder* load_folder(struct folder* parent, char *folder)
if ((dn[0] == '.') && (dn[1] == '\0' || (dn[1] == '.' && dn[2] == '\0')))
continue;
/* copy entry name to end of buffer, save pointer */
- int len = strlen((char *)entry->d_name);
+ len = strlen((char *)entry->d_name);
char *name = folder_alloc_from_end(len+1); /*for NULL*/
if (name == NULL)
{
@@ -518,7 +518,7 @@ static int select_paths(struct folder* root, const char* filenames)
lastfnp = fnp;
if (len <= 0 || len + 1 >= buflen)
continue;
- strlcpy(buf, sstr, len + 1);
+ strmemccpy(buf, sstr, len + 1);
struct child *item = find_from_filename(buf, root);
if (item)
item->state = SELECTED;
@@ -563,7 +563,7 @@ static void save_folders_r(struct folder *root, char* dst, size_t maxlen, size_t
int dlen = strlen(dst);
if (dlen + len >= maxlen)
continue;
- strlcpy(&dst[dlen], buffer_front, maxlen - dlen);
+ strmemccpy(&dst[dlen], buffer_front, maxlen - dlen);
}
else
{
diff --git a/apps/gui/icon.c b/apps/gui/icon.c
index 9fe7090f4a..7a59a72151 100644
--- a/apps/gui/icon.c
+++ b/apps/gui/icon.c
@@ -32,6 +32,7 @@
#include "bmp.h"
#include "filetypes.h"
#include "language.h"
+#include "misc.h"
#include "bitmaps/default_icons.h"
#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
@@ -63,7 +64,6 @@ static struct iconset {
struct bitmap bmp;
bool loaded;
int handle;
- int handle_locked;
} iconsets[Iconset_Count][NB_SCREENS];
#define ICON_HEIGHT(screen) (!iconsets[Iconset_user][screen].loaded ? \
@@ -160,8 +160,6 @@ static int buflib_move_callback(int handle, void* current, void* new)
struct iconset *set = &iconsets[i][j];
if (set->bmp.data == current)
{
- if (set->handle_locked > 0)
- return BUFLIB_CB_CANNOT_MOVE;
set->bmp.data = new;
return BUFLIB_CB_OK;
}
@@ -169,59 +167,27 @@ static int buflib_move_callback(int handle, void* current, void* new)
}
return BUFLIB_CB_OK;
}
-static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL};
static void load_icons(const char* filename, enum Iconset iconset,
enum screen_type screen)
{
- ssize_t size_read;
- ssize_t buf_size;
- int fd;
- int bmpformat = (FORMAT_ANY|FORMAT_DITHER|FORMAT_TRANSPARENT);
+ static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL};
+ const int bmpformat = (FORMAT_ANY|FORMAT_DITHER|FORMAT_TRANSPARENT);
struct iconset *ic = &iconsets[iconset][screen];
+ ssize_t buf_reqd;
ic->loaded = false;
- ic->handle = 0;
+ ic->handle = CLB_ALOC_ERR;
if (filename[0] && filename[0] != '-')
{
- char path[MAX_PATH];
-
- snprintf(path, sizeof(path), ICON_DIR "/%s.bmp", filename);
- fd = open(path, O_RDONLY);
- if (fd < 0)
- return;
- buf_size = read_bmp_fd(fd, &ic->bmp, 0,
- bmpformat|FORMAT_RETURN_SIZE, NULL);
- if (buf_size > 0)
- ic->handle = core_alloc_ex(filename, (size_t) buf_size, &buflib_ops);
-
- if (ic->handle <= 0)
- {
- /* error */
- goto finished;
- }
- lseek(fd, 0, SEEK_SET);
- ic->bmp.data = core_get_data(ic->handle);
-
- ic->handle_locked = 1;
- size_read = read_bmp_fd(fd, &ic->bmp, buf_size, bmpformat, NULL);
- ic->handle_locked = 0;
-
- if (size_read < 0)
+ char fname[MAX_PATH];
+ snprintf(fname, sizeof(fname), ICON_DIR "/%s.bmp", filename);
+ ic->handle = core_load_bmp(fname, &ic->bmp, bmpformat, &buf_reqd, &buflib_ops);
+ if (ic->handle != CLB_ALOC_ERR)
{
- /* error */
- size_read = 0;
- }
- /* free unused alpha channel, if any */
- core_shrink(ic->handle, ic->bmp.data, size_read);
-
- if (size_read == 0)
- ic->handle = core_free(ic->handle);
- else
+ ic->bmp.data = core_get_data(ic->handle);
ic->loaded = true;
-finished:
- close(fd);
- return;
+ }
}
}
diff --git a/apps/gui/line.c b/apps/gui/line.c
index d319ff3c51..7e84aa7b31 100644
--- a/apps/gui/line.c
+++ b/apps/gui/line.c
@@ -264,8 +264,7 @@ next:
else
{
/* any other character here is an erroneous format string */
- snprintf(tempbuf, sizeof(tempbuf), "<E:%c>", ch);
- display->putsxy(xpos, y, tempbuf);
+ display->putsxyf(xpos, y, "<E:%c>", ch);
/* Don't consider going forward, fix the caller */
return;
}
diff --git a/apps/gui/list.c b/apps/gui/list.c
index 29c80574c2..85046ead54 100644
--- a/apps/gui/list.c
+++ b/apps/gui/list.c
@@ -47,12 +47,6 @@
*/
#define FRAMEDROP_TRIGGER 6
-static int offset_step = 16; /* pixels per screen scroll step */
-/* should lines scroll out of the screen */
-static bool offset_out_of_view = false;
-
-static void gui_list_select_at_offset(struct gui_synclist * gui_list,
- int offset);
void list_draw(struct screen *display, struct gui_synclist *list);
static long last_dirty_tick;
@@ -129,7 +123,7 @@ void list_init_item_height(struct gui_synclist *list, enum screen_type screen)
#endif
}
-void gui_synclist_init_display_settings(struct gui_synclist * list)
+static void gui_synclist_init_display_settings(struct gui_synclist * list)
{
struct user_settings *gs = &global_settings;
list->scrollbar = gs->scrollbar;
@@ -182,7 +176,6 @@ void gui_synclist_init(struct gui_synclist * gui_list,
list_init_viewports(gui_list);
FOR_NB_SCREENS(i)
list_init_item_height(gui_list, i);
- gui_list->limit_scroll = false;
gui_list->data = data;
gui_list->scroll_all = scroll_all;
gui_list->selected_size = selected_size;
@@ -191,7 +184,6 @@ void gui_synclist_init(struct gui_synclist * gui_list,
gui_list->scheduled_talk_tick = gui_list->last_talked_tick = 0;
gui_list->dirty_tick = current_tick;
- gui_list->show_selection_marker = true;
#ifdef HAVE_LCD_COLOR
gui_list->title_color = -1;
@@ -200,13 +192,6 @@ void gui_synclist_init(struct gui_synclist * gui_list,
#endif
}
-/* this toggles the selection bar or cursor */
-void gui_synclist_hide_selection_marker(struct gui_synclist * lists, bool hide)
-{
- lists->show_selection_marker = !hide;
-}
-
-
int gui_list_get_item_offset(struct gui_synclist * gui_list,
int item_width,
int text_pos,
@@ -215,7 +200,7 @@ int gui_list_get_item_offset(struct gui_synclist * gui_list,
{
int item_offset;
- if (offset_out_of_view)
+ if (global_settings.offset_out_of_view)
{
item_offset = gui_list->offset_position[display->screen_type];
}
@@ -269,11 +254,7 @@ static void gui_list_put_selection_on_screen(struct gui_synclist * gui_list,
const int scroll_limit_up = (nb_lines < gui_list->selected_size+2 ? 0:1);
const int scroll_limit_down = (scroll_limit_up+gui_list->selected_size);
- if (gui_list->show_selection_marker == false)
- {
- new_start_item = gui_list->selected_item;
- }
- else if (gui_list->selected_size >= nb_lines)
+ if (gui_list->selected_size >= nb_lines)
{
new_start_item = gui_list->selected_item;
}
@@ -398,7 +379,7 @@ void gui_synclist_select_item(struct gui_synclist * gui_list, int item_number)
}
static void gui_list_select_at_offset(struct gui_synclist * gui_list,
- int offset)
+ int offset, bool allow_wrap)
{
int new_selection;
if (gui_list->selected_size > 1)
@@ -410,41 +391,15 @@ static void gui_list_select_at_offset(struct gui_synclist * gui_list,
if (new_selection >= gui_list->nb_items)
{
- new_selection = gui_list->limit_scroll ?
- gui_list->nb_items - gui_list->selected_size : 0;
- edge_beep(gui_list, !gui_list->limit_scroll);
+ new_selection = allow_wrap ? 0 : gui_list->nb_items - gui_list->selected_size;
+ edge_beep(gui_list, allow_wrap);
}
else if (new_selection < 0)
{
- new_selection = gui_list->limit_scroll ?
- 0 : gui_list->nb_items - gui_list->selected_size;
- edge_beep(gui_list, !gui_list->limit_scroll);
+ new_selection = allow_wrap ? gui_list->nb_items - gui_list->selected_size : 0;
+ edge_beep(gui_list, allow_wrap);
}
- else if (gui_list->show_selection_marker == false)
- {
- FOR_NB_SCREENS(i)
- {
- int nb_lines = list_get_nb_lines(gui_list, i);
- if (offset > 0)
- {
- int screen_top = MAX(0, gui_list->nb_items - nb_lines);
- gui_list->start_item[i] = MIN(screen_top, gui_list->start_item[i] +
- gui_list->selected_size);
- gui_list->selected_item = gui_list->start_item[i];
- }
- else
- {
- gui_list->start_item[i] = MAX(0, gui_list->start_item[i] -
- gui_list->selected_size);
- gui_list->selected_item = gui_list->start_item[i] + nb_lines;
- }
-#ifdef HAVE_TOUCHSCREEN
- gui_list->y_pos = gui_list->start_item[SCREEN_MAIN] * gui_list->line_height[SCREEN_MAIN];
-#endif
- }
- return;
- }
gui_synclist_select_item(gui_list, new_selection);
}
@@ -475,22 +430,12 @@ void gui_synclist_del_item(struct gui_synclist * gui_list)
}
}
-void gui_list_screen_scroll_step(int ofs)
-{
- offset_step = ofs;
-}
-
-void gui_list_screen_scroll_out_of_view(bool enable)
-{
- offset_out_of_view = enable;
-}
-
/*
* Set the title and title icon of the list. Setting title to NULL disables
* both the title and icon. Use NOICON if there is no icon.
*/
void gui_synclist_set_title(struct gui_synclist * gui_list,
- char * title, enum themable_icons icon)
+ const char * title, enum themable_icons icon)
{
gui_list->title = title;
gui_list->title_icon = icon;
@@ -558,26 +503,25 @@ void gui_synclist_set_sel_color(struct gui_synclist * lists,
#endif
static void gui_synclist_select_next_page(struct gui_synclist * lists,
- enum screen_type screen)
+ enum screen_type screen,
+ bool allow_wrap)
{
int nb_lines = list_get_nb_lines(lists, screen);
if (lists->selected_size > 1)
nb_lines = MAX(1, nb_lines/lists->selected_size);
- gui_list_select_at_offset(lists, nb_lines);
+
+ gui_list_select_at_offset(lists, nb_lines, allow_wrap);
}
static void gui_synclist_select_previous_page(struct gui_synclist * lists,
- enum screen_type screen)
+ enum screen_type screen,
+ bool allow_wrap)
{
int nb_lines = list_get_nb_lines(lists, screen);
if (lists->selected_size > 1)
nb_lines = MAX(1, nb_lines/lists->selected_size);
- gui_list_select_at_offset(lists, -nb_lines);
-}
-void gui_synclist_limit_scroll(struct gui_synclist * lists, bool scroll)
-{
- lists->limit_scroll = scroll;
+ gui_list_select_at_offset(lists, -nb_lines, allow_wrap);
}
/*
@@ -592,7 +536,7 @@ static void gui_synclist_scroll_right(struct gui_synclist * lists)
/* FIXME: This is a fake right boundry limiter. there should be some
* callback function to find the longest item on the list in pixels,
* to stop the list from scrolling past that point */
- lists->offset_position[i] += offset_step;
+ lists->offset_position[i] += global_settings.screen_scroll_step;
if (lists->offset_position[i] > 1000)
lists->offset_position[i] = 1000;
}
@@ -606,7 +550,7 @@ static void gui_synclist_scroll_left(struct gui_synclist * lists)
{
FOR_NB_SCREENS(i)
{
- lists->offset_position[i] -= offset_step;
+ lists->offset_position[i] -= global_settings.screen_scroll_step;
if (lists->offset_position[i] < 0)
lists->offset_position[i] = 0;
}
@@ -616,18 +560,24 @@ bool gui_synclist_keyclick_callback(int action, void* data)
{
struct gui_synclist *lists = (struct gui_synclist *)data;
- /* block the beep if we are at the end of the list and we are not wrapping.
- * CAVEAT: mosts lists don't set limit_scroll untill it sees a repeat
- * press at the end of the list so this can cause an extra beep.
- */
- if (lists->limit_scroll == false)
- return true;
+ /* Block the beep if we're at the end of the list and we're not wrapping. */
if (lists->selected_item == 0)
- return (action != ACTION_STD_PREV && action != ACTION_STD_PREVREPEAT);
+ {
+ if (action == ACTION_STD_PREVREPEAT)
+ return false;
+ if (action == ACTION_STD_PREV && !lists->wraparound)
+ return false;
+ }
+
if (lists->selected_item == lists->nb_items - lists->selected_size)
- return (action != ACTION_STD_NEXT && action != ACTION_STD_NEXTREPEAT);
+ {
+ if (action == ACTION_STD_NEXTREPEAT)
+ return false;
+ if (action == ACTION_STD_NEXT && !lists->wraparound)
+ return false;
+ }
- return action != ACTION_NONE;
+ return action != ACTION_NONE && !IS_SYSEVENT(action);
}
/*
@@ -650,8 +600,7 @@ static void _lists_uiviewport_update_callback(unsigned short id, void *data)
gui_synclist_draw(current_lists);
}
-bool gui_synclist_do_button(struct gui_synclist * lists,
- int *actionptr, enum list_wrap wrap)
+bool gui_synclist_do_button(struct gui_synclist * lists, int *actionptr)
{
int action = *actionptr;
static bool pgleft_allow_cancel = false;
@@ -662,6 +611,9 @@ bool gui_synclist_do_button(struct gui_synclist * lists,
static int next_item_modifier = 1;
static int last_accel_tick = 0;
+ if (IS_SYSEVENT(action))
+ return false;
+
if (action != ACTION_TOUCHSCREEN)
{
if (global_settings.list_accel_start_delay)
@@ -697,23 +649,9 @@ bool gui_synclist_do_button(struct gui_synclist * lists,
/* Disable the skin redraw callback */
current_lists = NULL;
- switch (wrap)
- {
- case LIST_WRAP_ON:
- gui_synclist_limit_scroll(lists, !(lists->wraparound));
- break;
- case LIST_WRAP_OFF:
- gui_synclist_limit_scroll(lists, true);
- break;
- case LIST_WRAP_UNLESS_HELD:
- if (action == ACTION_STD_PREVREPEAT ||
- action == ACTION_STD_NEXTREPEAT ||
- action == ACTION_LISTTREE_PGUP ||
- action == ACTION_LISTTREE_PGDOWN)
- gui_synclist_limit_scroll(lists, true);
- else gui_synclist_limit_scroll(lists, !(lists->wraparound));
- break;
- };
+
+ /* repeat actions block list wraparound */
+ bool allow_wrap = lists->wraparound;
switch (action)
{
@@ -723,17 +661,18 @@ bool gui_synclist_do_button(struct gui_synclist * lists,
#ifdef HAVE_VOLUME_IN_LIST
case ACTION_LIST_VOLUP:
- global_settings.volume += sound_steps(SOUND_VOLUME);
- setvol();
+ adjust_volume(1);
return true;
case ACTION_LIST_VOLDOWN:
- global_settings.volume -= sound_steps(SOUND_VOLUME);
- setvol();
+ adjust_volume(-1);
return true;
#endif
- case ACTION_STD_PREV:
case ACTION_STD_PREVREPEAT:
- gui_list_select_at_offset(lists, -next_item_modifier);
+ allow_wrap = false; /* Prevent list wraparound on repeating actions */
+ /*Fallthrough*/
+ case ACTION_STD_PREV:
+
+ gui_list_select_at_offset(lists, -next_item_modifier, allow_wrap);
#ifndef HAVE_WHEEL_ACCELERATION
if (button_queue_count() < FRAMEDROP_TRIGGER)
#endif
@@ -742,9 +681,11 @@ bool gui_synclist_do_button(struct gui_synclist * lists,
*actionptr = ACTION_STD_PREV;
return true;
- case ACTION_STD_NEXT:
case ACTION_STD_NEXTREPEAT:
- gui_list_select_at_offset(lists, next_item_modifier);
+ allow_wrap = false; /* Prevent list wraparound on repeating actions */
+ /*Fallthrough*/
+ case ACTION_STD_NEXT:
+ gui_list_select_at_offset(lists, next_item_modifier, allow_wrap);
#ifndef HAVE_WHEEL_ACCELERATION
if (button_queue_count() < FRAMEDROP_TRIGGER)
#endif
@@ -795,7 +736,7 @@ bool gui_synclist_do_button(struct gui_synclist * lists,
SCREEN_REMOTE :
#endif
SCREEN_MAIN;
- gui_synclist_select_previous_page(lists, screen);
+ gui_synclist_select_previous_page(lists, screen, false);
gui_synclist_draw(lists);
yield();
*actionptr = ACTION_STD_NEXT;
@@ -810,7 +751,7 @@ bool gui_synclist_do_button(struct gui_synclist * lists,
SCREEN_REMOTE :
#endif
SCREEN_MAIN;
- gui_synclist_select_next_page(lists, screen);
+ gui_synclist_select_next_page(lists, screen, false);
gui_synclist_draw(lists);
yield();
*actionptr = ACTION_STD_PREV;
@@ -849,8 +790,7 @@ int list_do_action_timeout(struct gui_synclist *lists, int timeout)
}
bool list_do_action(int context, int timeout,
- struct gui_synclist *lists, int *action,
- enum list_wrap wrap)
+ struct gui_synclist *lists, int *action)
/* Combines the get_action() (with possibly overridden timeout) and
gui_synclist_do_button() calls. Returns the list action from
do_button, and places the action from get_action in *action. */
@@ -858,14 +798,7 @@ bool list_do_action(int context, int timeout,
timeout = list_do_action_timeout(lists, timeout);
keyclick_set_callback(gui_synclist_keyclick_callback, lists);
*action = get_action(context, timeout);
- return gui_synclist_do_button(lists, action, wrap);
-}
-
-bool gui_synclist_item_is_onscreen(struct gui_synclist *lists,
- enum screen_type screen, int item)
-{
- int nb_lines = list_get_nb_lines(lists, screen);
- return (unsigned)(item - lists->start_item[screen]) < (unsigned) nb_lines;
+ return gui_synclist_do_button(lists, action);
}
/* Simple use list implementation */
@@ -925,7 +858,6 @@ bool simplelist_show_list(struct simplelist_info *info)
struct gui_synclist lists;
int action, old_line_count = simplelist_line_count;
list_get_name *getname;
- int wrap = global_settings.list_wraparound ? LIST_WRAP_UNLESS_HELD : LIST_WRAP_OFF;
if (info->get_name)
getname = info->get_name;
else
@@ -950,12 +882,6 @@ bool simplelist_show_list(struct simplelist_info *info)
gui_synclist_set_sel_color(&lists, info->selection_color);
#endif
- if (info->hide_selection)
- {
- gui_synclist_hide_selection_marker(&lists, true);
- wrap = LIST_WRAP_OFF;
- }
-
if (info->action_callback)
info->action_callback(ACTION_REDRAW, &lists);
@@ -974,8 +900,7 @@ bool simplelist_show_list(struct simplelist_info *info)
while(1)
{
- list_do_action(CONTEXT_LIST, info->timeout,
- &lists, &action, wrap);
+ list_do_action(CONTEXT_LIST, info->timeout, &lists, &action);
/* We must yield in this case or no other thread can run */
if (info->timeout == TIMEOUT_NOBLOCK)
@@ -1039,7 +964,6 @@ void simplelist_info_init(struct simplelist_info *info, char* title,
info->title = title;
info->count = count;
info->selection_size = 1;
- info->hide_selection = false;
info->scroll_all = false;
info->hide_theme = false;
info->speak_onshow = true;
diff --git a/apps/gui/list.h b/apps/gui/list.h
index 4dc83a1b27..40a27d1061 100644
--- a/apps/gui/list.h
+++ b/apps/gui/list.h
@@ -30,12 +30,6 @@
#define SCROLLBAR_WIDTH global_settings.scrollbar_width
-enum list_wrap {
- LIST_WRAP_ON = 0,
- LIST_WRAP_OFF,
- LIST_WRAP_UNLESS_HELD,
-};
-
enum synclist_cursor
{
SYNCLIST_CURSOR_NOSTYLE = 0,
@@ -96,7 +90,7 @@ struct list_putlineinfo_t {
struct viewport *vp;
struct line_desc *linedes;
struct gui_synclist * list;
- char *dsp_text;
+ const char *dsp_text;
bool is_selected;
bool is_title;
@@ -155,13 +149,9 @@ struct gui_synclist
bool talk_menu;
bool wraparound;
bool scroll_paginated;
- /* defines wether the list should stop when reaching the top/bottom
- * or should continue (by going to bottom/top) */
- bool limit_scroll;
/* whether the text of the whole items of the list have to be
* scrolled or only for the selected item */
bool scroll_all;
- bool show_selection_marker; /* set to true by default */
int nb_items;
int selected_item;
@@ -185,7 +175,7 @@ struct gui_synclist
/* The data that will be passed to the callback function YOU implement */
void * data;
/* The optional title, set to NULL for none */
- char * title;
+ const char * title;
/* Optional title icon */
enum themable_icons title_icon;
@@ -199,12 +189,7 @@ struct gui_synclist
extern void list_init(void);
-/* parse global setting to static int */
-extern void gui_list_screen_scroll_step(int ofs);
-/* parse global setting to static bool */
-extern void gui_list_screen_scroll_out_of_view(bool enable);
-extern void gui_synclist_init_display_settings(struct gui_synclist * list);
extern void gui_synclist_init(
struct gui_synclist * lists,
list_get_name callback_get_item_name,
@@ -232,13 +217,8 @@ extern void gui_synclist_select_item(struct gui_synclist * lists,
int item_number);
extern void gui_synclist_add_item(struct gui_synclist * lists);
extern void gui_synclist_del_item(struct gui_synclist * lists);
-extern void gui_synclist_limit_scroll(struct gui_synclist * lists, bool scroll);
-extern void gui_synclist_set_title(struct gui_synclist * lists, char * title,
+extern void gui_synclist_set_title(struct gui_synclist * lists, const char * title,
enum themable_icons icon);
-extern void gui_synclist_hide_selection_marker(struct gui_synclist *lists,
- bool hide);
-extern bool gui_synclist_item_is_onscreen(struct gui_synclist *lists,
- enum screen_type screen, int item);
extern bool gui_synclist_keyclick_callback(int action, void* data);
/*
@@ -246,20 +226,9 @@ extern bool gui_synclist_keyclick_callback(int action, void* data);
* returns true if the action was handled.
* NOTE: *action may be changed regardless of return value
*/
-extern bool gui_synclist_do_button(struct gui_synclist * lists,
- int *action,
- enum list_wrap);
+extern bool gui_synclist_do_button(struct gui_synclist * lists, int *action);
#if !defined(PLUGIN)
-struct listitem_viewport_cfg {
- struct wps_data *data;
- OFFSETTYPE(char *) label;
- int width;
- int height;
- int xmargin;
- int ymargin;
- bool tile;
- struct skin_viewport selected_item_vp;
-};
+struct listitem_viewport_cfg;
bool skinlist_get_item(struct screen *display, struct gui_synclist *list, int x, int y, int *item);
bool skinlist_draw(struct screen *display, struct gui_synclist *list);
@@ -291,8 +260,7 @@ extern int list_do_action_timeout(struct gui_synclist *lists, int timeout);
list_do_action_timeout) with the gui_synclist_do_button call, for
convenience. */
extern bool list_do_action(int context, int timeout,
- struct gui_synclist *lists, int *action,
- enum list_wrap wrap);
+ struct gui_synclist *lists, int *action);
/** Simplelist implementation.
@@ -301,10 +269,9 @@ extern bool list_do_action(int context, int timeout,
**/
struct simplelist_info {
- char *title; /* title to show on the list */
+ const char *title; /* title to show on the list */
int count; /* number of items in the list, each item is selection_size high */
int selection_size; /* list selection size, usually 1 */
- bool hide_selection;
bool scroll_all;
bool hide_theme;
bool speak_onshow; /* list speaks first item or 'empty list' */
@@ -350,7 +317,6 @@ void simplelist_addline(const char *fmt, ...);
/* setup the info struct. members not setup in this function need to be assigned manually
members set in this function:
info.selection_size = 1;
- info.hide_selection = false;
info.scroll_all = false;
info.hide_theme = false;
info.speak_onshow = true;
diff --git a/apps/gui/option_select.c b/apps/gui/option_select.c
index 7068fee510..afc11fc4ee 100644
--- a/apps/gui/option_select.c
+++ b/apps/gui/option_select.c
@@ -36,6 +36,8 @@
#include "menu.h"
#include "quickscreen.h"
+/* HASFLAG compares value to flags returns true if set, false otherwise */
+#define HASFLAG(settings_list, flag) ((settings_list->flags & (flag)) == (flag))
static int selection_to_val(const struct settings_list *setting, int selection);
int option_value_as_int(const struct settings_list *setting)
@@ -65,29 +67,29 @@ const char *option_get_valuestring(const struct settings_list *setting,
intptr_t temp_var)
{
const char* str = buffer;
- if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING)
+ if (HASFLAG(setting, F_BOOL_SETTING))
{
bool val = (bool)temp_var;
- strlcpy(buffer, str(val? setting->bool_setting->lang_yes :
- setting->bool_setting->lang_no), buf_len);
+ strmemccpy(buffer, str(val? setting->bool_setting->lang_yes :
+ setting->bool_setting->lang_no), buf_len);
}
#if 0 /* probably dont need this one */
- else if ((setting->flags & F_FILENAME) == F_FILENAME)
+ else if (HASFLAG(setting, F_FILENAME))
{
struct filename_setting *info = setting->filename_setting;
snprintf(buffer, buf_len, "%s%s%s", info->prefix,
(char*)temp_var, info->suffix);
}
#endif
- else if (((setting->flags & F_INT_SETTING) == F_INT_SETTING) ||
- ((setting->flags & F_TABLE_SETTING) == F_TABLE_SETTING))
+ else if ((HASFLAG(setting, F_INT_SETTING)) ||
+ HASFLAG(setting, F_TABLE_SETTING))
{
const struct int_setting *int_info = setting->int_setting;
const struct table_setting *tbl_info = setting->table_setting;
int info_unit;
const char *str_unit;
const char* (*formatter)(char*, size_t, int, const char*);
- if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
+ if (HASFLAG(setting, F_INT_SETTING))
{
formatter = int_info->formatter;
info_unit = int_info->unit;
@@ -98,67 +100,68 @@ const char *option_get_valuestring(const struct settings_list *setting,
info_unit = tbl_info->unit;
}
- if ((setting->flags & F_TIME_SETTING) == F_TIME_SETTING)
+ bool is_time_setting = HASFLAG(setting, F_TIME_SETTING);
+ if (is_time_setting)
str = option_get_timestring(buffer, buf_len, (long)temp_var, info_unit);
str_unit = unit_strings_core[info_unit];
+
if (formatter)
str = formatter(buffer, buf_len, (int)temp_var, str_unit);
- else if ((setting->flags & F_TIME_SETTING) != F_TIME_SETTING)
+ else if (!is_time_setting)
snprintf(buffer, buf_len, "%d %s", (int)temp_var, str_unit?str_unit:"");
}
- else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
+ else if (HASFLAG(setting, F_T_SOUND))
{
format_sound_value(buffer, buf_len,
setting->sound_setting->setting,
temp_var);
}
- else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)
+ else if (HASFLAG(setting, F_CHOICE_SETTING))
{
- if (setting->flags & F_CHOICETALKS)
+ if (HASFLAG(setting, F_CHOICETALKS))
{
- int setting_id;
const struct choice_setting *info = setting->choice_setting;
if (info->talks[(int)temp_var] < LANG_LAST_INDEX_IN_ARRAY)
{
- strlcpy(buffer, str(info->talks[(int)temp_var]), buf_len);
+ strmemccpy(buffer, str(info->talks[(int)temp_var]), buf_len);
}
else
{
- find_setting(setting->setting, &setting_id);
- cfg_int_to_string(setting_id, (int)temp_var, buffer, buf_len);
+ cfg_int_to_string(setting, (int)temp_var, buffer, buf_len);
}
}
else
{
int value = (int)temp_var;
char *val = P2STR(setting->choice_setting->desc[value]);
- strlcpy(buffer, val, buf_len);
+ strmemccpy(buffer, val, buf_len);
}
}
return str;
}
void option_talk_value(const struct settings_list *setting, int value, bool enqueue)
{
- if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING)
+
+ if (HASFLAG(setting, F_BOOL_SETTING))
{
bool val = (value==1);
talk_id(val? setting->bool_setting->lang_yes :
setting->bool_setting->lang_no, enqueue);
}
#if 0 /* probably dont need this one */
- else if ((setting->flags & F_FILENAME) == F_FILENAME)
+ else if (HASFLAG(setting, F_FILENAME))
{
}
#endif
- else if (((setting->flags & F_INT_SETTING) == F_INT_SETTING) ||
- ((setting->flags & F_TABLE_SETTING) == F_TABLE_SETTING))
+ else if ((HASFLAG(setting, F_INT_SETTING)) ||
+ HASFLAG(setting, F_TABLE_SETTING))
{
const struct int_setting *int_info = setting->int_setting;
const struct table_setting *tbl_info = setting->table_setting;
int unit;
int32_t (*get_talk_id)(int, int);
- if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
+ if (HASFLAG(setting, F_INT_SETTING))
{
unit = int_info->unit;
get_talk_id = int_info->get_talk_id;
@@ -170,12 +173,12 @@ void option_talk_value(const struct settings_list *setting, int value, bool enqu
}
if (get_talk_id)
talk_id(get_talk_id(value, unit), enqueue);
- else if ((setting->flags & F_TIME_SETTING) == F_TIME_SETTING)
+ else if (HASFLAG(setting, F_TIME_SETTING))
talk_time_intervals(value, unit, enqueue);
else
talk_value(value, unit, enqueue);
}
- else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
+ else if (HASFLAG(setting, F_T_SOUND))
{
int talkunit = UNIT_INT;
int sound_setting = setting->sound_setting->setting;
@@ -190,9 +193,9 @@ void option_talk_value(const struct settings_list *setting, int value, bool enqu
talkunit = UNIT_HERTZ;
talk_value_decimal(phys, talkunit, decimals, enqueue);
}
- else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)
+ else if (HASFLAG(setting, F_CHOICE_SETTING))
{
- if (setting->flags & F_CHOICETALKS)
+ if (HASFLAG(setting, F_CHOICETALKS))
{
talk_id(setting->choice_setting->talks[value], enqueue);
}
@@ -218,14 +221,14 @@ void option_select_next_val(const struct settings_list *setting,
{
int val = 0;
int *value = setting->setting;
- if ((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING)
+ if (HASFLAG(setting, F_BOOL_SETTING))
{
*(bool*)value = !*(bool*)value;
if (apply && setting->bool_setting->option_callback)
setting->bool_setting->option_callback(*(bool*)value);
return;
}
- else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
+ else if (HASFLAG(setting, F_INT_SETTING))
{
struct int_setting *info = (struct int_setting *)setting->int_setting;
bool neg_step = (info->step < 0);
@@ -245,7 +248,7 @@ void option_select_next_val(const struct settings_list *setting,
if (apply && info->option_callback)
info->option_callback(val);
}
- else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
+ else if (HASFLAG(setting, F_T_SOUND))
{
int setting_id = setting->sound_setting->setting;
int steps = sound_steps(setting_id);
@@ -267,7 +270,7 @@ void option_select_next_val(const struct settings_list *setting,
if (apply)
sound_set(setting_id, val);
}
- else if ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING)
+ else if (HASFLAG(setting, F_CHOICE_SETTING))
{
struct choice_setting *info = (struct choice_setting *)setting->choice_setting;
if (!previous)
@@ -286,7 +289,7 @@ void option_select_next_val(const struct settings_list *setting,
if (apply && info->option_callback)
info->option_callback(val);
}
- else if ((setting->flags & F_TABLE_SETTING) == F_TABLE_SETTING)
+ else if (HASFLAG(setting, F_TABLE_SETTING))
{
const struct table_setting *tbl_info = setting->table_setting;
int i, add;
@@ -314,13 +317,15 @@ static int selection_to_val(const struct settings_list *setting, int selection)
int min = 0;
*/
int max = 0, step = 1;
- if (((setting->flags & F_BOOL_SETTING) == F_BOOL_SETTING) ||
- ((setting->flags & F_CHOICE_SETTING) == F_CHOICE_SETTING))
+ if ((HASFLAG(setting, F_BOOL_SETTING)) ||
+ HASFLAG(setting, F_CHOICE_SETTING))
+ {
return selection;
- else if ((setting->flags & F_TABLE_SETTING) == F_TABLE_SETTING)
+ }
+ else if (HASFLAG(setting, F_TABLE_SETTING))
{
const struct table_setting *info = setting->table_setting;
- if (setting->flags&F_ALLOW_ARBITRARY_VALS &&
+ if (HASFLAG(setting, F_ALLOW_ARBITRARY_VALS) &&
table_setting_array_position != -1 &&
(selection >= table_setting_array_position))
{
@@ -331,7 +336,7 @@ static int selection_to_val(const struct settings_list *setting, int selection)
else
return info->values[selection];
}
- else if ((setting->flags & F_T_SOUND) == F_T_SOUND)
+ else if (HASFLAG(setting, F_T_SOUND))
{
int setting_id = setting->sound_setting->setting;
if(global_settings.list_order == LIST_ORDER_DESCENDING)
@@ -348,7 +353,7 @@ static int selection_to_val(const struct settings_list *setting, int selection)
max = sound_min(setting_id);
}
}
- else if ((setting->flags & F_INT_SETTING) == F_INT_SETTING)
+ else if (HASFLAG(setting, F_INT_SETTING))
{
const struct int_setting *info = setting->int_setting;
if(global_settings.list_order == LIST_ORDER_DESCENDING)
@@ -394,13 +399,13 @@ static void val_to_selection(const struct settings_list *setting, int oldvalue,
/* set the number of items and current selection */
if (var_type == F_T_INT || var_type == F_T_UINT)
{
- if (setting->flags&F_CHOICE_SETTING)
+ if (HASFLAG(setting, F_CHOICE_SETTING))
{
*nb_items = setting->choice_setting->count;
*selected = oldvalue;
*function = setting->choice_setting->option_callback;
}
- else if (setting->flags&F_TABLE_SETTING)
+ else if (HASFLAG(setting, F_TABLE_SETTING))
{
const struct table_setting *info = setting->table_setting;
int i;
@@ -409,7 +414,7 @@ static void val_to_selection(const struct settings_list *setting, int oldvalue,
table_setting_array_position = -1;
for (i=0;*selected==-1 && i<*nb_items;i++)
{
- if (setting->flags&F_ALLOW_ARBITRARY_VALS &&
+ if (HASFLAG(setting, F_ALLOW_ARBITRARY_VALS) &&
(oldvalue < info->values[i]))
{
table_setting_oldval = oldvalue;
@@ -422,7 +427,7 @@ static void val_to_selection(const struct settings_list *setting, int oldvalue,
}
*function = info->option_callback;
}
- else if (setting->flags&F_T_SOUND)
+ else if (HASFLAG(setting, F_T_SOUND))
{
int setting_id = setting->sound_setting->setting;
int steps = sound_steps(setting_id);
@@ -470,9 +475,10 @@ bool option_screen(const struct settings_list *setting,
struct gui_synclist lists;
int oldvalue, nb_items = 0, selected = 0, temp_var;
int *variable;
- bool allow_wrap = setting->flags & F_NO_WRAP ? false : true;
- bool cb_on_select_only =
- ((setting->flags & F_CB_ON_SELECT_ONLY) == F_CB_ON_SELECT_ONLY);
+ bool allow_wrap = (!HASFLAG(setting, F_NO_WRAP));
+ bool cb_on_select_only = HASFLAG(setting, F_CB_ON_SELECT_ONLY);
+ bool cb_on_changed = HASFLAG(setting, F_CB_ONLY_IF_CHANGED);
+
int var_type = setting->flags&F_T_MASK;
void (*function)(int) = NULL;
char *title;
@@ -506,15 +512,18 @@ bool option_screen(const struct settings_list *setting,
gui_synclist_set_nb_items(&lists, nb_items);
gui_synclist_select_item(&lists, selected);
- gui_synclist_limit_scroll(&lists, true);
gui_synclist_draw(&lists);
/* talk the item */
gui_synclist_speak_item(&lists);
while (!done)
{
+ /* override user wraparound setting; used mainly by EQ settings.
+ * Not sure this is justified? */
+ if (!allow_wrap)
+ lists.wraparound = false;
+
if (list_do_action(CONTEXT_LIST, HZ, /* HZ so the status bar redraws */
- &lists, &action,
- allow_wrap? LIST_WRAP_UNLESS_HELD: LIST_WRAP_OFF))
+ &lists, &action))
{
/* setting changed */
selected = gui_synclist_get_sel_pos(&lists);
@@ -524,7 +533,7 @@ bool option_screen(const struct settings_list *setting,
}
else if (action == ACTION_NONE)
continue;
- else if (action == ACTION_STD_CANCEL)
+ else if (action == ACTION_STD_CANCEL || action == ACTION_STD_MENU)
{
/* setting canceled, restore old value if changed */
if (*variable != oldvalue)
@@ -560,26 +569,33 @@ bool option_screen(const struct settings_list *setting,
}
settings_save();
done = true;
- if (cb_on_select_only && function)
- function(*variable);
+ cb_on_select_only = false; /* unset the flag so callback can be called */
}
else if(default_event_handler(action) == SYS_USB_CONNECTED)
+ {
+ pop_current_activity();
return true;
+ }
+
/* callback */
- if (function && !cb_on_select_only)
- function(*variable);
+ if (!cb_on_select_only && function)
+ {
+ if (!cb_on_changed || (*variable != oldvalue))
+ {
+ function(*variable);
+ /* if the volume is changing we need to let the skins know */
+ if (function == sound_get_fn(SOUND_VOLUME))
+ global_status.last_volume_change = current_tick;
+ }
+ }
- /* if the volume is changing we need to let the skins know */
- if (function == sound_get_fn(SOUND_VOLUME))
- global_status.last_volume_change = current_tick;
}
pop_current_activity();
return false;
}
-int get_setting_info_for_bar(int setting_id, int *count, int *val)
+int get_setting_info_for_bar(const struct settings_list *setting, int *count, int *val)
{
- const struct settings_list *setting = &settings[setting_id];
int var_type = setting->flags&F_T_MASK;
void (*function)(int) = NULL;
int oldvalue;
@@ -604,9 +620,8 @@ int get_setting_info_for_bar(int setting_id, int *count, int *val)
}
#ifdef HAVE_TOUCHSCREEN
-void update_setting_value_from_touch(int setting_id, int selection)
+void update_setting_value_from_touch(const struct settings_list *setting, int selection)
{
- const struct settings_list *setting = &settings[setting_id];
int new_val = selection_to_val(setting, selection);
int var_type = setting->flags&F_T_MASK;
diff --git a/apps/gui/option_select.h b/apps/gui/option_select.h
index 104e86f64d..eabe5825e7 100644
--- a/apps/gui/option_select.h
+++ b/apps/gui/option_select.h
@@ -46,9 +46,9 @@ void option_talk_value(const struct settings_list *setting, int value, bool enqu
/* only use this for int and bool settings */
int option_value_as_int(const struct settings_list *setting);
-int get_setting_info_for_bar(int setting_id, int *count, int *val);
+int get_setting_info_for_bar(const struct settings_list *setting, int *count, int *val);
#ifdef HAVE_TOUCHSCREEN
-void update_setting_value_from_touch(int setting_id, int selection);
+void update_setting_value_from_touch(const struct settings_list *setting, int selection);
#endif
#endif /* _GUI_OPTION_SELECT_H_ */
diff --git a/apps/gui/quickscreen.c b/apps/gui/quickscreen.c
index e403e13e6c..109414336f 100644
--- a/apps/gui/quickscreen.c
+++ b/apps/gui/quickscreen.c
@@ -320,13 +320,13 @@ static int quickscreen_touchscreen_button(void)
}
#endif
-static bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter, bool *usb)
+static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter, bool *usb)
{
int button;
struct viewport parent[NB_SCREENS];
struct viewport vps[NB_SCREENS][QUICKSCREEN_ITEM_COUNT];
struct viewport vp_icons[NB_SCREENS];
- bool changed = false;
+ int ret = QUICKSCREEN_OK;
/* To quit we need either :
* - a second press on the button that made us enter
* - an action taken while pressing the enter button,
@@ -367,7 +367,7 @@ static bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_ente
}
if (gui_quickscreen_do_button(qs, button))
{
- changed = true;
+ ret |= QUICKSCREEN_CHANGED;
can_quit = true;
FOR_NB_SCREENS(i)
gui_quickscreen_draw(qs, &screens[i], &parent[i],
@@ -378,17 +378,20 @@ static bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_ente
else if (button == button_enter)
can_quit = true;
else if (button == ACTION_QS_VOLUP) {
- global_settings.volume += sound_steps(SOUND_VOLUME);
- setvol();
+ adjust_volume(1);
FOR_NB_SCREENS(i)
skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_NON_STATIC);
}
else if (button == ACTION_QS_VOLDOWN) {
- global_settings.volume -= sound_steps(SOUND_VOLUME);
- setvol();
+ adjust_volume(-1);
FOR_NB_SCREENS(i)
skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_NON_STATIC);
}
+ else if (button == ACTION_STD_CONTEXT)
+ {
+ ret |= QUICKSCREEN_GOTO_SHORTCUTS_MENU;
+ break;
+ }
if ((button == button_enter) && can_quit)
break;
@@ -401,80 +404,60 @@ static bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_ente
{ /* stop scrolling before exiting */
for (int j = 0; j < QUICKSCREEN_ITEM_COUNT; j++)
screens[i].scroll_stop_viewport(&vps[i][j]);
- viewportmanager_theme_undo(i, true);
+ viewportmanager_theme_undo(i, !(ret & QUICKSCREEN_GOTO_SHORTCUTS_MENU));
}
- pop_current_activity();
- return changed;
-}
+ if (ret & QUICKSCREEN_GOTO_SHORTCUTS_MENU) /* Eliminate flashing of parent during */
+ pop_current_activity_without_refresh(); /* transition to Shortcuts */
+ else
+ pop_current_activity();
-static const struct settings_list *get_setting(int gs_value,
- const struct settings_list *defaultval)
-{
- if (gs_value != -1 && gs_value < nb_settings &&
- is_setting_quickscreenable(&settings[gs_value]))
- return &settings[gs_value];
- return defaultval;
+ return ret;
}
int quick_screen_quick(int button_enter)
{
struct gui_quickscreen qs;
- bool oldshuffle = global_settings.playlist_shuffle;
- int oldrepeat = global_settings.repeat_mode;
#ifdef HAVE_ALBUMART
int old_album_art = global_settings.album_art;
#endif
bool usb = false;
- if (global_settings.shortcuts_replaces_qs)
- return do_shortcut_menu(NULL);
+ for (int i = 0; i < 4; ++i)
+ {
+ qs.items[i] = global_settings.qs_items[i];
- qs.items[QUICKSCREEN_TOP] =
- get_setting(global_settings.qs_items[QUICKSCREEN_TOP], NULL);
- qs.items[QUICKSCREEN_LEFT] =
- get_setting(global_settings.qs_items[QUICKSCREEN_LEFT],
- find_setting(&global_settings.playlist_shuffle, NULL));
- qs.items[QUICKSCREEN_RIGHT] =
- get_setting(global_settings.qs_items[QUICKSCREEN_RIGHT],
- find_setting(&global_settings.repeat_mode, NULL));
- qs.items[QUICKSCREEN_BOTTOM] =
- get_setting(global_settings.qs_items[QUICKSCREEN_BOTTOM], NULL);
+ if (!is_setting_quickscreenable(qs.items[i]))
+ qs.items[i] = NULL;
+ }
qs.callback = NULL;
- if (gui_syncquickscreen_run(&qs, button_enter, &usb))
+ int ret = gui_syncquickscreen_run(&qs, button_enter, &usb);
+ if (ret & QUICKSCREEN_CHANGED)
{
settings_save();
- /* make sure repeat/shuffle/any other nasty ones get updated */
- if ( oldrepeat != global_settings.repeat_mode &&
- (audio_status() & AUDIO_STATUS_PLAY) )
- {
- audio_flush_and_reload_tracks();
- }
- if (oldshuffle != global_settings.playlist_shuffle
- && audio_status() & AUDIO_STATUS_PLAY)
- {
- replaygain_update();
- if (global_settings.playlist_shuffle)
- playlist_randomise(NULL, current_tick, true);
- else
- playlist_sort(NULL, true);
- }
#ifdef HAVE_ALBUMART
if (old_album_art != global_settings.album_art)
set_albumart_mode(global_settings.album_art);
#endif
}
- return (usb ? 1:0);
+ if (usb)
+ return QUICKSCREEN_IN_USB;
+ return ret & QUICKSCREEN_GOTO_SHORTCUTS_MENU ? QUICKSCREEN_GOTO_SHORTCUTS_MENU :
+ QUICKSCREEN_OK;
}
/* stuff to make the quickscreen configurable */
bool is_setting_quickscreenable(const struct settings_list *setting)
{
+ if (!setting)
+ return true;
+
/* to keep things simple, only settings which have a lang_id set are ok */
- if (setting->lang_id < 0 || (setting->flags&F_BANFROMQS))
+ if (setting->lang_id < 0 || (setting->flags & F_BANFROMQS))
return false;
- switch (setting->flags&F_T_MASK)
+
+ switch (setting->flags & F_T_MASK)
{
case F_T_BOOL:
return true;
@@ -485,16 +468,3 @@ bool is_setting_quickscreenable(const struct settings_list *setting)
return false;
}
}
-
-void set_as_qs_item(const struct settings_list *setting,
- enum quickscreen_item item)
-{
- int i;
- for (i = 0; i < nb_settings; i++)
- {
- if (&settings[i] == setting)
- break;
- }
-
- global_settings.qs_items[item] = i;
-}
diff --git a/apps/gui/quickscreen.h b/apps/gui/quickscreen.h
index 015928ee8a..bd8008bd34 100644
--- a/apps/gui/quickscreen.h
+++ b/apps/gui/quickscreen.h
@@ -36,6 +36,13 @@ enum quickscreen_item {
QUICKSCREEN_ITEM_COUNT,
};
+enum quickscreen_return {
+ QUICKSCREEN_OK = 0,
+ QUICKSCREEN_IN_USB = 0x1,
+ QUICKSCREEN_GOTO_SHORTCUTS_MENU = 0x2,
+ QUICKSCREEN_CHANGED = 0x4,
+};
+
struct gui_quickscreen
{
const struct settings_list *items[QUICKSCREEN_ITEM_COUNT];
@@ -46,7 +53,6 @@ struct gui_quickscreen
extern int quick_screen_quick(int button_enter);
int quickscreen_set_option(void *data);
bool is_setting_quickscreenable(const struct settings_list *setting);
-void set_as_qs_item(const struct settings_list *setting,
- enum quickscreen_item item);
+
#endif /*_GUI_QUICK_SCREEN_H_*/
#endif /* HAVE_QUICKSCREEN */
diff --git a/apps/gui/skin_engine/skin_backdrops.c b/apps/gui/skin_engine/skin_backdrops.c
index 146dccb18a..eecf5b0433 100644
--- a/apps/gui/skin_engine/skin_backdrops.c
+++ b/apps/gui/skin_engine/skin_backdrops.c
@@ -41,7 +41,6 @@ static struct skin_backdrop {
} backdrops[NB_BDROPS];
#define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS
-static int handle_being_loaded;
static int current_lcd_backdrop[NB_SCREENS];
bool skin_backdrop_get_debug(int index, char **path, int *ref_count, size_t *size)
@@ -65,8 +64,8 @@ bool skin_backdrop_get_debug(int index, char **path, int *ref_count, size_t *siz
static int buflib_move_callback(int handle, void* current, void* new)
{
- if (handle == handle_being_loaded)
- return BUFLIB_CB_CANNOT_MOVE;
+ (void)handle;
+
for (int i=0; i<NB_BDROPS; i++)
{
if (backdrops[i].buffer == current)
@@ -96,7 +95,6 @@ bool skin_backdrop_init(void)
}
FOR_NB_SCREENS(i)
current_lcd_backdrop[i] = -1;
- handle_being_loaded = -1;
first_go = false;
}
return go_status;
@@ -139,7 +137,7 @@ int skin_backdrop_assign(char* backdrop, char *bmpdir,
}
if (free >= 0)
{
- strlcpy(backdrops[free].name, filename, MAX_PATH);
+ strmemccpy(backdrops[free].name, filename, MAX_PATH);
backdrops[free].buffer = NULL;
backdrops[free].screen = screen;
backdrops[free].ref_count = 1;
@@ -176,22 +174,22 @@ bool skin_backdrops_preload(void)
}
if (*filename && *filename != '-')
{
- backdrops[i].buflib_handle = core_alloc_ex(filename, buf_size, &buflib_ops);
+ backdrops[i].buflib_handle = core_alloc_ex(buf_size, &buflib_ops);
if (backdrops[i].buflib_handle > 0)
{
backdrops[i].buffer = core_get_data(backdrops[i].buflib_handle);
if (strcmp(filename, BACKDROP_BUFFERNAME))
{
- handle_being_loaded = backdrops[i].buflib_handle;
+ core_pin(backdrops[i].buflib_handle);
backdrops[i].loaded =
screens[screen].backdrop_load(filename, backdrops[i].buffer);
+ core_unpin(backdrops[i].buflib_handle);
if (!backdrops[i].loaded)
{
core_free(backdrops[i].buflib_handle);
backdrops[i].buflib_handle = -1;
retval = false;
}
- handle_being_loaded = -1;
}
else
backdrops[i].loaded = true;
@@ -267,8 +265,7 @@ void skin_backdrop_unload(int backdrop_id)
backdrops[backdrop_id].ref_count--;
if (backdrops[backdrop_id].ref_count <= 0)
{
- if (backdrops[backdrop_id].buflib_handle > 0)
- core_free(backdrops[backdrop_id].buflib_handle);
+ core_free(backdrops[backdrop_id].buflib_handle);
backdrops[backdrop_id].buffer = NULL;
backdrops[backdrop_id].buflib_handle = -1;
backdrops[backdrop_id].loaded = false;
@@ -290,18 +287,17 @@ void skin_backdrop_load_setting(void)
if (backdrops[i].buflib_handle <= 0)
{
backdrops[i].buflib_handle =
- core_alloc_ex(global_settings.backdrop_file,
- LCD_BACKDROP_BYTES, &buflib_ops);
+ core_alloc_ex(LCD_BACKDROP_BYTES, &buflib_ops);
if (backdrops[i].buflib_handle <= 0)
return;
}
bool loaded;
+ core_pin(backdrops[i].buflib_handle);
backdrops[i].buffer = core_get_data(backdrops[i].buflib_handle);
- handle_being_loaded = backdrops[i].buflib_handle;
loaded = screens[SCREEN_MAIN].backdrop_load(
global_settings.backdrop_file,
backdrops[i].buffer);
- handle_being_loaded = -1;
+ core_unpin(backdrops[i].buflib_handle);
backdrops[i].name[2] = loaded ? '.' : '\0';
backdrops[i].loaded = loaded;
return;
diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c
index 4a3dcc2177..913bdcfbc4 100644
--- a/apps/gui/skin_engine/skin_display.c
+++ b/apps/gui/skin_engine/skin_display.c
@@ -46,6 +46,7 @@
#include "tagcache.h"
#include "list.h"
#include "option_select.h"
+#include "buffering.h"
#include "peakmeter.h"
/* Image stuff */
@@ -64,7 +65,7 @@
#endif
#include "root_menu.h"
-
+#include "wps.h"
#include "wps_internals.h"
#include "skin_engine.h"
#include "statusbar-skinned.h"
@@ -82,7 +83,7 @@ void skin_update(enum skinnable_screens skin, enum screen_type screen,
struct gui_wps *gwps = skin_get_gwps(skin, screen);
/* This maybe shouldnt be here,
* This is also safe for skined screen which dont use the id3 */
- struct mp3entry *id3 = skin_get_global_state()->id3;
+ struct mp3entry *id3 = get_wps_state()->id3;
bool cuesheet_update = (id3 != NULL ? cuesheet_subtrack_changed(id3) : false);
if (cuesheet_update)
skin_request_full_update(skin);
@@ -157,11 +158,12 @@ void ab_draw_markers(struct screen * screen, int capacity,
#endif
-void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
+void draw_progressbar(struct gui_wps *gwps, struct skin_viewport* skin_viewport,
+ int line, struct progressbar *pb)
{
struct screen *display = gwps->display;
- struct viewport *vp = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), pb->vp);
- struct wps_state *state = skin_get_global_state();
+ struct viewport *vp = &skin_viewport->vp;
+ struct wps_state *state = get_wps_state();
struct mp3entry *id3 = state->id3;
int x = pb->x, y = pb->y, width = pb->width, height = pb->height;
unsigned long length, end;
@@ -183,8 +185,13 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
{
int minvol = sound_min(SOUND_VOLUME);
int maxvol = sound_max(SOUND_VOLUME);
- length = maxvol-minvol;
- end = global_settings.volume-minvol;
+#if defined(HAVE_PERCEPTUAL_VOLUME) || defined(HAVE_TOUCHSCREEN)
+ length = 1000;
+ end = to_normalized_volume(global_settings.volume, minvol, maxvol, length);
+#else
+ length = maxvol - minvol;
+ end = global_settings.volume - minvol;
+#endif
}
else if (pb->type == SKIN_TOKEN_BATTERY_PERCENTBAR)
{
@@ -210,7 +217,7 @@ void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb)
else if (pb->type == SKIN_TOKEN_SETTINGBAR)
{
int val, count;
- get_setting_info_for_bar(pb->setting_id, &count, &val);
+ get_setting_info_for_bar(pb->setting, &count, &val);
length = count - 1;
end = val;
}
@@ -411,8 +418,7 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
#ifdef HAVE_ALBUMART
/* now draw the AA */
struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
- if (aa && SKINOFFSETTOPTR(get_skin_buffer(data), aa->vp) == vp
- && aa->draw_handle >= 0)
+ if (aa && aa->draw_handle >= 0)
{
draw_album_art(gwps, aa->draw_handle, false);
aa->draw_handle = -1;
@@ -499,78 +505,82 @@ void write_line(struct screen *display, struct align_pos *format_align,
/* CASE 1: left and centered string overlap */
/* there is a left string, need to merge left and center */
- if ((left_width != 0 && center_width != 0) &&
- (left_width + space_width > center_xpos)) {
- /* replace the former separator '\0' of left and
- center string with a space */
- *(--format_align->center) = ' ';
- /* calculate the new width and position of the merged string */
- left_width = left_width + space_width + center_width;
- /* there is no centered string anymore */
- center_width = 0;
- }
- /* there is no left string, move center to left */
- if ((left_width == 0 && center_width != 0) &&
- (left_width > center_xpos)) {
- /* move the center string to the left string */
- format_align->left = format_align->center;
- /* calculate the new width and position of the string */
- left_width = center_width;
- /* there is no centered string anymore */
- center_width = 0;
- }
+ if (center_width != 0)
+ {
+ if (left_width != 0 && left_width + space_width > center_xpos) {
+ /* replace the former separator '\0' of left and
+ center string with a space */
+ *(--format_align->center) = ' ';
+ /* calculate the new width and position of the merged string */
+ left_width = left_width + space_width + center_width;
+ /* there is no centered string anymore */
+ center_width = 0;
+ }
+ /* there is no left string, move center to left */
+ else if (left_width == 0 && center_xpos < 0) {
+ /* move the center string to the left string */
+ format_align->left = format_align->center;
+ /* calculate the new width and position of the string */
+ left_width = center_width;
+ /* there is no centered string anymore */
+ center_width = 0;
+ }
+ } /*(center_width != 0)*/
/* CASE 2: centered and right string overlap */
/* there is a right string, need to merge center and right */
- if ((center_width != 0 && right_width != 0) &&
- (center_xpos + center_width + space_width > right_xpos)) {
- /* replace the former separator '\0' of center and
- right string with a space */
- *(--format_align->right) = ' ';
- /* move the center string to the right after merge */
- format_align->right = format_align->center;
- /* calculate the new width and position of the merged string */
- right_width = center_width + space_width + right_width;
- right_xpos = (viewport_width - right_width);
- /* there is no centered string anymore */
- center_width = 0;
- }
- /* there is no right string, move center to right */
- if ((center_width != 0 && right_width == 0) &&
- (center_xpos + center_width > right_xpos)) {
- /* move the center string to the right string */
- format_align->right = format_align->center;
- /* calculate the new width and position of the string */
- right_width = center_width;
- right_xpos = (viewport_width - right_width);
- /* there is no centered string anymore */
- center_width = 0;
- }
+ if (center_width != 0)
+ {
+ int center_left_x = center_xpos + center_width;
+ if (right_width != 0 && center_left_x + space_width > right_xpos) {
+ /* replace the former separator '\0' of center and
+ right string with a space */
+ *(--format_align->right) = ' ';
+ /* move the center string to the right after merge */
+ format_align->right = format_align->center;
+ /* calculate the new width and position of the merged string */
+ right_width = center_width + space_width + right_width;
+ right_xpos = (viewport_width - right_width);
+ /* there is no centered string anymore */
+ center_width = 0;
+ }
+ /* there is no right string, move center to right */
+ else if (right_width == 0 && center_left_x > right_xpos) {
+ /* move the center string to the right string */
+ format_align->right = format_align->center;
+ /* calculate the new width and position of the string */
+ right_width = center_width;
+ right_xpos = (viewport_width - right_width);
+ /* there is no centered string anymore */
+ center_width = 0;
+ }
+ } /*(center_width != 0)*/
/* CASE 3: left and right overlap
There is no center string anymore, either there never
was one or it has been merged in case 1 or 2 */
/* there is a left string, need to merge left and right */
- if ((left_width != 0 && center_width == 0 && right_width != 0) &&
- (left_width + space_width > right_xpos)) {
- /* replace the former separator '\0' of left and
- right string with a space */
- *(--format_align->right) = ' ';
- /* calculate the new width and position of the string */
- left_width = left_width + space_width + right_width;
- /* there is no right string anymore */
- right_width = 0;
- }
- /* there is no left string, move right to left */
- if ((left_width == 0 && center_width == 0 && right_width != 0) &&
- (left_width > right_xpos)) {
- /* move the right string to the left string */
- format_align->left = format_align->right;
- /* calculate the new width and position of the string */
- left_width = right_width;
- /* there is no right string anymore */
- right_width = 0;
- }
+ if (center_width == 0 && right_width != 0)
+ {
+ if (left_width != 0 && left_width + space_width > right_xpos) {
+ /* replace the former separator '\0' of left and
+ right string with a space */
+ *(--format_align->right) = ' ';
+ /* calculate the new width and position of the string */
+ left_width = left_width + space_width + right_width;
+ /* there is no right string anymore */
+ right_width = 0;
+ }
+ /* there is no left string, move right to left */
+ else if (left_width == 0 && right_xpos < 0) {
+ /* move the right string to the left string */
+ format_align->left = format_align->right;
+ /* calculate the new width and position of the string */
+ left_width = right_width;
+ /* there is no right string anymore */
+ right_width = 0;
+ }
+ } /* (center_width == 0 && right_width != 0)*/
if (scroll && ((left_width > scroll_width) ||
(center_width > scroll_width) ||
@@ -601,9 +611,9 @@ void write_line(struct screen *display, struct align_pos *format_align,
char *center = format_align->center ?: "";
char *right = format_align->right ?: "";
- display->put_line(0, line, linedes, "$t$*s$t$*s$t", left,
- center_xpos - left_width, center,
- right_xpos - (center_xpos + center_width), right);
+ display->put_line(0, line, linedes, "$t$*s$t$*s$t", left_width == 0 ? "" : left ,
+ center_xpos - left_width, center_width == 0 ? "" : center,
+ right_xpos - center_xpos - center_width, right_width == 0 ? "" : right);
}
}
@@ -632,14 +642,86 @@ void draw_peakmeters(struct gui_wps *gwps, int line_number,
}
}
-bool skin_has_sbs(enum screen_type screen, struct wps_data *data)
+#ifdef HAVE_ALBUMART
+/* Draw the album art bitmap from the given handle ID onto the given WPS.
+ Call with clear = true to clear the bitmap instead of drawing it. */
+void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear)
+{
+ if (!gwps || !gwps->data || !gwps->display || handle_id < 0)
+ return;
+
+ struct wps_data *data = gwps->data;
+ struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
+
+ if (!aa)
+ return;
+
+ struct bitmap *bmp;
+ if (bufgetdata(handle_id, 0, (void *)&bmp) <= 0)
+ return;
+
+ short x = aa->x;
+ short y = aa->y;
+ short width = bmp->width;
+ short height = bmp->height;
+
+ if (aa->width > 0)
+ {
+ /* Crop if the bitmap is too wide */
+ width = MIN(bmp->width, aa->width);
+
+ /* Align */
+ if (aa->xalign & WPS_ALBUMART_ALIGN_RIGHT)
+ x += aa->width - width;
+ else if (aa->xalign & WPS_ALBUMART_ALIGN_CENTER)
+ x += (aa->width - width) / 2;
+ }
+
+ if (aa->height > 0)
+ {
+ /* Crop if the bitmap is too high */
+ height = MIN(bmp->height, aa->height);
+
+ /* Align */
+ if (aa->yalign & WPS_ALBUMART_ALIGN_BOTTOM)
+ y += aa->height - height;
+ else if (aa->yalign & WPS_ALBUMART_ALIGN_CENTER)
+ y += (aa->height - height) / 2;
+ }
+
+ if (!clear)
+ {
+ /* Draw the bitmap */
+ gwps->display->bitmap_part((fb_data*)bmp->data, 0, 0,
+ STRIDE(gwps->display->screen_type,
+ bmp->width, bmp->height),
+ x, y, width, height);
+#ifdef HAVE_LCD_INVERT
+ if (global_settings.invert) {
+ gwps->display->set_drawmode(DRMODE_COMPLEMENT);
+ gwps->display->fillrect(x, y, width, height);
+ gwps->display->set_drawmode(DRMODE_SOLID);
+ }
+#endif
+ }
+ else
+ {
+ /* Clear the bitmap */
+ gwps->display->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+ gwps->display->fillrect(x, y, width, height);
+ gwps->display->set_drawmode(DRMODE_SOLID);
+ }
+}
+#endif
+
+bool skin_has_sbs(struct gui_wps *gwps)
{
- (void)screen;
- (void)data;
+ struct wps_data *data = gwps->data;
+
bool draw = false;
if (data->wps_sb_tag)
draw = data->show_sb_on_wps;
- else if (statusbar_position(screen) != STATUSBAR_OFF)
+ else if (statusbar_position(gwps->display->screen_type) != STATUSBAR_OFF)
draw = true;
return draw;
}
diff --git a/apps/gui/skin_engine/skin_display.h b/apps/gui/skin_engine/skin_display.h
index de1b0b20b5..56af12aa03 100644
--- a/apps/gui/skin_engine/skin_display.h
+++ b/apps/gui/skin_engine/skin_display.h
@@ -29,7 +29,8 @@
#define _SKIN_DISPLAY_H_
-void draw_progressbar(struct gui_wps *gwps, int line, struct progressbar *pb);
+void draw_progressbar(struct gui_wps *gwps, struct skin_viewport* skin_viewport,
+ int line, struct progressbar *pb);
void draw_playlist_viewer_list(struct gui_wps *gwps, struct playlistviewer *viewer);
/* clears the area where the image was shown */
void clear_image_pos(struct gui_wps *gwps, struct gui_img *img);
@@ -54,4 +55,10 @@ void write_line(struct screen *display, struct align_pos *format_align,
int line, bool scroll, struct line_desc *line_desc);
void draw_peakmeters(struct gui_wps *gwps, int line_number,
struct viewport *viewport);
+#ifdef HAVE_ALBUMART
+/* Draw the album art bitmap from the given handle ID onto the given Skin.
+ Call with clear = true to clear the bitmap instead of drawing it. */
+void draw_album_art(struct gui_wps *gwps, int handle_id, bool clear);
+#endif
+
#endif
diff --git a/apps/gui/skin_engine/skin_engine.c b/apps/gui/skin_engine/skin_engine.c
index 8ba76e5739..c007ed35d4 100644
--- a/apps/gui/skin_engine/skin_engine.c
+++ b/apps/gui/skin_engine/skin_engine.c
@@ -34,9 +34,11 @@
#if CONFIG_TUNER
#include "radio.h"
#endif
+#include "gui/list.h"
#include "skin_engine.h"
#include "skin_buffer.h"
#include "statusbar-skinned.h"
+#include "wps_internals.h"
#define FAILSAFENAME "rockbox_failsafe"
@@ -51,7 +53,6 @@ static bool skins_initialised = false;
static char* get_skin_filename(char *buf, size_t buf_size,
enum skinnable_screens skin, enum screen_type screen);
-struct wps_state wps_state = { .id3 = NULL };
static struct gui_skin_helper {
int (*preproccess)(enum screen_type screen, struct wps_data *data);
int (*postproccess)(enum screen_type screen, struct wps_data *data);
@@ -308,11 +309,6 @@ struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type scre
return &skins[skin][screen].gui_wps;
}
-struct wps_state *skin_get_global_state(void)
-{
- return &wps_state;
-}
-
/* This is called to find out if we the screen needs a full update.
* if true you MUST do a full update as the next call will return false */
bool skin_do_full_update(enum skinnable_screens skin,
@@ -334,3 +330,56 @@ void skin_request_full_update(enum skinnable_screens skin)
FOR_NB_SCREENS(i)
skins[skin][i].needs_full_update = true;
}
+
+bool dbg_skin_engine(void)
+{
+ struct simplelist_info info;
+ int i, total = 0;
+#if defined(HAVE_BACKDROP_IMAGE)
+ int ref_count;
+ char *path;
+ size_t bytes;
+ int path_prefix_len = strlen(ROCKBOX_DIR "/wps/");
+#endif
+ simplelist_info_init(&info, "Skin engine usage", 0, NULL);
+ simplelist_set_line_count(0);
+ FOR_NB_SCREENS(j) {
+#if NB_SCREENS > 1
+ simplelist_addline("%s display:",
+ j == 0 ? "Main" : "Remote");
+#endif
+ for (i = 0; i < skin_get_num_skins(); i++) {
+ struct skin_stats *stats = skin_get_stats(i, j);
+ if (stats->buflib_handles)
+ {
+ simplelist_addline("Skin ID: %d, %d allocations",
+ i, stats->buflib_handles);
+ simplelist_addline("\tskin: %d bytes",
+ stats->tree_size);
+ simplelist_addline("\tImages: %d bytes",
+ stats->images_size);
+ simplelist_addline("\tTotal: %d bytes",
+ stats->tree_size + stats->images_size);
+ total += stats->tree_size + stats->images_size;
+ }
+ }
+ }
+ simplelist_addline("Skin total usage: %d bytes", total);
+#if defined(HAVE_BACKDROP_IMAGE)
+ simplelist_addline("Backdrop Images:");
+ i = 0;
+ while (skin_backdrop_get_debug(i++, &path, &ref_count, &bytes)) {
+ if (ref_count > 0) {
+
+ if (!strncasecmp(path, ROCKBOX_DIR "/wps/", path_prefix_len))
+ path += path_prefix_len;
+ simplelist_addline("%s", path);
+ simplelist_addline("\tref_count: %d", ref_count);
+ simplelist_addline("\tsize: %d", bytes);
+ total += bytes;
+ }
+ }
+ simplelist_addline("Total usage: %d bytes", total);
+#endif
+ return simplelist_show_list(&info);
+}
diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h
index e26ec34d1f..d04c873e84 100644
--- a/apps/gui/skin_engine/skin_engine.h
+++ b/apps/gui/skin_engine/skin_engine.h
@@ -26,8 +26,7 @@
#ifndef PLUGIN
#include "tag_table.h"
-
-#include "wps_internals.h" /* TODO: remove this line.. shoudlnt be needed */
+#include "screen_access.h"
enum skinnable_screens {
CUSTOM_STATUSBAR,
@@ -39,24 +38,20 @@ enum skinnable_screens {
SKINNABLE_SCREENS_COUNT
};
+struct skin_stats;
+struct skin_viewport;
+struct gui_wps;
+
#ifdef HAVE_TOUCHSCREEN
-int skin_get_touchaction(struct wps_data *data, int* edge_offset,
- struct touchregion **retregion);
-void skin_disarm_touchregions(struct wps_data *data);
+int skin_get_touchaction(struct gui_wps *gwps, int* edge_offset);
+void skin_disarm_touchregions(struct gui_wps *gwps);
#endif
/* Do a update_type update of the skinned screen */
void skin_update(enum skinnable_screens skin, enum screen_type screen,
unsigned int update_type);
-/*
- * setup up the skin-data from a format-buffer (isfile = false)
- * or from a skinfile (isfile = true)
- */
-bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
- const char *buf, bool isfile, struct skin_stats *stats);
-
-bool skin_has_sbs(enum screen_type screen, struct wps_data *data);
+bool skin_has_sbs(struct gui_wps *gwps);
/* load a backdrop into the skin buffer.
@@ -81,7 +76,6 @@ int skin_wait_for_action(enum skinnable_screens skin, int context, int timeout);
void skin_load(enum skinnable_screens skin, enum screen_type screen,
const char *buf, bool isfile);
struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen);
-struct wps_state *skin_get_global_state(void);
void gui_sync_skin_init(void);
void skin_unload_all(void);
@@ -89,5 +83,7 @@ void skin_unload_all(void);
bool skin_do_full_update(enum skinnable_screens skin, enum screen_type screen);
void skin_request_full_update(enum skinnable_screens skin);
+bool dbg_skin_engine(void);
+
#endif /* !PLUGIN */
#endif
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index d89ca8b534..4d1526fcbc 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -426,12 +426,16 @@ static int parse_image_load(struct skin_element *element,
img->buflib_handle = -1;
img->is_9_segment = false;
img->loaded = false;
-
- /* save current viewport */
- img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
+ img->dither = false;
if (token->type == SKIN_TOKEN_IMAGE_DISPLAY)
+ {
token->value.data = PTRTOSKINOFFSET(skin_buffer, img);
+#ifdef HAVE_BACKDROP_IMAGE
+ if (curr_vp)
+ img->dither = curr_vp->output_to_backdrop_buffer;
+#endif
+ }
if (!strcmp(img->bm.data, "__list_icons__"))
{
@@ -497,7 +501,6 @@ static int parse_playlistview(struct skin_element *element,
struct playlistviewer *viewer = skin_buffer_alloc(sizeof(*viewer));
if (!viewer)
return WPS_ERROR_INVALID_PARAM;
- viewer->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
viewer->show_icons = true;
viewer->start_offset = get_param(element, 0)->data.number;
viewer->line = PTRTOSKINOFFSET(skin_buffer, get_param_code(element, 1));
@@ -615,7 +618,8 @@ static int parse_viewporttextstyle(struct skin_element *element,
if (element->params_count < 2 ||
!parse_color(curr_screen, get_param_text(element, 1), &colour))
return 1;
- line->style = STYLE_COLORED;
+ /* STYLE_COLORED is only a modifier and can't be used on its own */
+ line->style = STYLE_COLORED | STYLE_DEFAULT;
line->text_color = colour;
}
#ifdef HAVE_LCD_COLOR
@@ -714,8 +718,35 @@ static int parse_viewportcolour(struct skin_element *element,
return -1;
if (isdefault(param))
{
- colour->colour = get_viewport_default_colour(curr_screen,
- token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR);
+ unsigned int fg_color;
+ unsigned int bg_color;
+
+ switch (curr_screen)
+ {
+#if defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
+ case SCREEN_REMOTE:
+ fg_color = LCD_REMOTE_DEFAULT_FG;
+ bg_color = LCD_REMOTE_DEFAULT_BG;
+ break;
+#endif
+ default:
+#if defined(HAVE_LCD_COLOR)
+ fg_color = global_settings.fg_color;
+ bg_color = global_settings.bg_color;
+#elif LCD_DEPTH > 1
+ fg_color = LCD_DEFAULT_FG;
+ bg_color = LCD_DEFAULT_BG;
+#else
+ fg_color = 0;
+ bg_color = 0;
+#endif
+ break;
+ }
+
+ if (token->type == SKIN_TOKEN_VIEWPORT_FGCOLOUR)
+ colour->colour = fg_color;
+ else
+ colour->colour = bg_color;
}
else
{
@@ -723,7 +754,6 @@ static int parse_viewportcolour(struct skin_element *element,
&colour->colour))
return -1;
}
- colour->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
token->value.data = PTRTOSKINOFFSET(skin_buffer, colour);
if (element->line == curr_viewport_element->line)
{
@@ -780,14 +810,14 @@ static int parse_setting_and_lang(struct skin_element *element,
*/
(void)wps_data;
char *temp = get_param_text(element, 0);
- int i;
if (token->type == SKIN_TOKEN_TRANSLATEDSTRING)
{
#ifndef __PCTOOL__
- i = lang_english_to_id(temp);
+ int i = lang_english_to_id(temp);
if (i < 0)
i = LANG_LAST_INDEX_IN_ARRAY;
+ token->value.i = i;
#endif
}
else if (element->params_count > 1)
@@ -800,12 +830,13 @@ static int parse_setting_and_lang(struct skin_element *element,
else
{
#ifndef __PCTOOL__
- if (find_setting_by_cfgname(temp, &i) == NULL)
+ const struct settings_list *setting = find_setting_by_cfgname(temp);
+ if (!setting)
return WPS_ERROR_INVALID_PARAM;
+
+ token->value.xdata = (void *)setting;
#endif
}
- /* Store the setting number */
- token->value.i = i;
return 0;
}
@@ -942,7 +973,6 @@ static int parse_progressbar_tag(struct skin_element* element,
if (!pb)
return WPS_ERROR_INVALID_PARAM;
- pb->vp = PTRTOSKINOFFSET(skin_buffer, vp);
pb->follow_lang_direction = follow_lang_direction > 0;
pb->nofill = false;
pb->noborder = false;
@@ -950,7 +980,7 @@ static int parse_progressbar_tag(struct skin_element* element,
pb->image = PTRTOSKINOFFSET(skin_buffer, NULL);
pb->slider = PTRTOSKINOFFSET(skin_buffer, NULL);
pb->backdrop = PTRTOSKINOFFSET(skin_buffer, NULL);
- pb->setting_id = -1;
+ pb->setting = NULL;
pb->invert_fill_direction = false;
pb->horizontal = true;
@@ -1051,7 +1081,7 @@ static int parse_progressbar_tag(struct skin_element* element,
enum
{
eINVERT = 0, eNOFILL, eNOBORDER, eNOBAR, eSLIDER, eIMAGE,
- eBACKDROP, eVERTICAL, eHORIZONTAL, eNOTOUCH, eSETTING,
+ eBACKDROP, eVERTICAL, eHORIZONTAL, eNOTOUCH, eSETTING,
e_PB_TAG_COUNT
};
@@ -1135,7 +1165,8 @@ static int parse_progressbar_tag(struct skin_element* element,
param++;
text = SKINOFFSETTOPTR(skin_buffer, param->data.text);
#ifndef __PCTOOL__
- if (find_setting_by_cfgname(text, &pb->setting_id) == NULL)
+ pb->setting = find_setting_by_cfgname(text);
+ if (!pb->setting)
return WPS_ERROR_INVALID_PARAM;
#endif
}
@@ -1169,7 +1200,6 @@ static int parse_progressbar_tag(struct skin_element* element,
img->display = -1;
img->using_preloaded_icons = false;
img->buflib_handle = -1;
- img->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
img->loaded = false;
struct skin_token_list *item = new_skin_token_list_item(NULL, img);
if (!item)
@@ -1296,7 +1326,6 @@ static int parse_albumart_load(struct skin_element* element,
if (!isdefault(param3) && param3->type == PERCENT)
aa->height = param3->data.number * curr_vp->vp.height / 1000;
- aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
aa->draw_handle = -1;
/* if we got here, we parsed everything ok .. ! */
@@ -1526,48 +1555,48 @@ static int touchregion_setup_setting(struct skin_element *element, int param_no,
#ifndef __PCTOOL__
int p = param_no;
char *name = get_param_text(element, p++);
- int j;
-
- region->setting_data.setting = find_setting_by_cfgname(name, &j);
- if (region->setting_data.setting == NULL)
+ const struct settings_list *setting = find_setting_by_cfgname(name);
+ if (!setting)
return WPS_ERROR_INVALID_PARAM;
+ region->setting_data.setting = setting;
+
if (region->action == ACTION_SETTINGS_SET)
{
char* text;
int temp;
- struct touchsetting *setting =
+ struct touchsetting *touchsetting =
&region->setting_data;
if (element->params_count < p+1)
return -1;
text = get_param_text(element, p++);
- switch (settings[j].flags&F_T_MASK)
+ switch (setting->flags & F_T_MASK)
{
case F_T_CUSTOM:
- setting->value.text = PTRTOSKINOFFSET(skin_buffer, text);
+ touchsetting->value.text = PTRTOSKINOFFSET(skin_buffer, text);
break;
case F_T_INT:
case F_T_UINT:
- if (settings[j].cfg_vals == NULL)
+ if (setting->cfg_vals == NULL)
{
- setting->value.number = atoi(text);
+ touchsetting->value.number = atoi(text);
}
- else if (cfg_string_to_int(j, &temp, text))
+ else if (cfg_string_to_int(setting, &temp, text))
{
- if (settings[j].flags&F_TABLE_SETTING)
- setting->value.number =
- settings[j].table_setting->values[temp];
+ if (setting->flags & F_TABLE_SETTING)
+ touchsetting->value.number =
+ setting->table_setting->values[temp];
else
- setting->value.number = temp;
+ touchsetting->value.number = temp;
}
else
return -1;
break;
case F_T_BOOL:
- if (cfg_string_to_int(j, &temp, text))
+ if (cfg_string_to_int(setting, &temp, text))
{
- setting->value.number = temp;
+ touchsetting->value.number = temp;
}
else
return -1;
@@ -1828,9 +1857,7 @@ void skin_data_free_buflib_allocs(struct wps_data *wps_data)
abort:
wps_data->font_ids = PTRTOSKINOFFSET(skin_buffer, NULL); /* Safe if skin_buffer is NULL */
wps_data->images = PTRTOSKINOFFSET(skin_buffer, NULL);
- if (wps_data->buflib_handle > 0)
- core_free(wps_data->buflib_handle);
- wps_data->buflib_handle = -1;
+ wps_data->buflib_handle = core_free(wps_data->buflib_handle);
#endif
}
@@ -1871,13 +1898,11 @@ static void skin_data_reset(struct wps_data *wps_data)
}
#ifndef __PCTOOL__
-static int currently_loading_handle = -1;
static int buflib_move_callback(int handle, void* current, void* new)
{
+ (void)handle;
(void)current;
(void)new;
- if (handle == currently_loading_handle)
- return BUFLIB_CB_CANNOT_MOVE;
/* Any active skins may be scrolling - which means using viewports which
* will be moved after this callback returns. This is a hammer to make that
* safe. TODO: use a screwdriver instead.
@@ -1890,85 +1915,63 @@ static int buflib_move_callback(int handle, void* current, void* new)
return BUFLIB_CB_OK;
}
-static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL};
-static void lock_handle(int handle)
-{
- currently_loading_handle = handle;
-}
-static void unlock_handle(void)
-{
- currently_loading_handle = -1;
-}
#endif
-static int load_skin_bmp(struct wps_data *wps_data, struct bitmap *bitmap, char* bmpdir)
+static int load_skin_bmp(struct wps_data *wps_data, struct gui_img *img, char* bmpdir)
{
+
(void)wps_data; /* only needed for remote targets */
char img_path[MAX_PATH];
- int fd;
- int handle;
+ struct bitmap *bitmap = &img->bm;
+
get_image_filename(bitmap->data, bmpdir,
img_path, sizeof(img_path));
- /* load the image */
- int format;
-#ifdef HAVE_REMOTE_LCD
- if (curr_screen == SCREEN_REMOTE)
- format = FORMAT_ANY|FORMAT_REMOTE;
- else
-#endif
- format = FORMAT_ANY|FORMAT_TRANSPARENT;
-
- fd = open(img_path, O_RDONLY);
+#ifdef __PCTOOL__ /* just check if image exists */
+ int fd = open(img_path, O_RDONLY);
if (fd < 0)
{
DEBUGF("Couldn't open %s\n", img_path);
return fd;
}
-#ifndef __PCTOOL__
- int buf_size = read_bmp_fd(fd, bitmap, 0,
- format|FORMAT_RETURN_SIZE, NULL);
- if(buf_size < 0)
- {
- close(fd);
- return buf_size;
- }
+ close(fd);
+ return 1;
+#else /* load the image */
+ static struct buflib_callbacks buflib_ops = {buflib_move_callback, NULL, NULL};
+ int handle;
+ int bmpformat;
+ ssize_t buf_reqd;
+#ifdef HAVE_REMOTE_LCD
+ if (curr_screen == SCREEN_REMOTE)
+ bmpformat = FORMAT_ANY|FORMAT_REMOTE;
+ else
+#endif
+ bmpformat = img->dither ? FORMAT_ANY|FORMAT_DITHER|FORMAT_TRANSPARENT :
+ FORMAT_ANY|FORMAT_TRANSPARENT;
- handle = core_alloc_ex(bitmap->data, buf_size, &buflib_ops);
- if (handle <= 0)
+ handle = core_load_bmp(img_path, bitmap, bmpformat, &buf_reqd, &buflib_ops);
+ if (handle != CLB_ALOC_ERR)
{
- DEBUGF("Not enough skin buffer: need %zd more.\n",
- buf_size - skin_buffer_freespace());
- close(fd);
+ /* NOTE!: bitmap->data == NULL to force a crash later if the
+ caller doesnt call core_get_data() */
+ _stats->buflib_handles++;
+ _stats->images_size += buf_reqd;
return handle;
}
- _stats->buflib_handles++;
- _stats->images_size += buf_size;
- lseek(fd, 0, SEEK_SET);
- lock_handle(handle);
- bitmap->data = core_get_data(handle);
- int ret = read_bmp_fd(fd, bitmap, buf_size, format, NULL);
- bitmap->data = NULL; /* do this to force a crash later if the
- caller doesnt call core_get_data() */
- unlock_handle();
- close(fd);
- if (ret > 0)
+
+ if (buf_reqd == CLB_READ_ERR)
{
- /* free unused alpha channel, if any */
- core_shrink(handle, core_get_data(handle), ret);
- return handle;
+ /* Abort if we can't load an image */
+ DEBUGF("Couldn't load '%s' (%zu)\n", img_path, buf_reqd);
}
else
{
- /* Abort if we can't load an image */
- DEBUGF("Couldn't load '%s'\n", img_path);
- core_free(handle);
- return -1;
+ DEBUGF("Not enough skin buffer: need %zd more.\n",
+ buf_reqd - skin_buffer_freespace());
}
-#else /* !__PCTOOL__ */
- close(fd);
- return 1;
-#endif
+
+ return -1;
+#endif/* !__PCTOOL__ */
}
static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
@@ -1996,14 +1999,15 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
char path[MAX_PATH];
int handle;
strcpy(path, img->bm.data);
- handle = load_skin_bmp(wps_data, &img->bm, bmpdir);
+ handle = load_skin_bmp(wps_data, img, bmpdir);
img->buflib_handle = handle;
- img->loaded = img->buflib_handle >= 0;
+ img->loaded = img->buflib_handle > 0;
if (img->loaded)
{
struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, list->next);
img->subimage_height = img->bm.height / img->num_subimages;
+ struct bitmap* loaded_bm = &img->bm;
while (imglist)
{
token = SKINOFFSETTOPTR(skin_buffer, imglist->token);
@@ -2013,6 +2017,7 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
{
img->loaded = true;
img->buflib_handle = handle;
+ img->bm = *loaded_bm;
img->subimage_height = img->bm.height / img->num_subimages;
}
}
@@ -2396,13 +2401,6 @@ static int skin_element_callback(struct skin_element* element, void* data)
break;
#endif
#ifdef HAVE_ALBUMART
- case SKIN_TOKEN_ALBUMART_DISPLAY:
- if (SKINOFFSETTOPTR(skin_buffer, wps_data->albumart))
- {
- struct skin_albumart *aa = SKINOFFSETTOPTR(skin_buffer, wps_data->albumart);
- aa->vp = PTRTOSKINOFFSET(skin_buffer, &curr_vp->vp);
- }
- break;
case SKIN_TOKEN_ALBUMART_LOAD:
function = parse_albumart_load;
break;
@@ -2563,7 +2561,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
{
/* get the bitmap dir */
char *dot = strrchr(buf, '.');
- strlcpy(bmpdir, buf, dot - buf + 1);
+ strmemccpy(bmpdir, buf, dot - buf + 1);
}
else
{
@@ -2587,8 +2585,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
}
#endif
#ifndef __PCTOOL__
- wps_data->buflib_handle = core_alloc(isfile ? buf : "failsafe skin",
- skin_buffer_usage());
+ wps_data->buflib_handle = core_alloc(skin_buffer_usage());
if (wps_data->buflib_handle > 0)
{
wps_data->wps_loaded = true;
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c
index 1f777b6672..06f7d9798d 100644
--- a/apps/gui/skin_engine/skin_render.c
+++ b/apps/gui/skin_engine/skin_render.c
@@ -50,6 +50,7 @@
#include "root_menu.h"
#include "misc.h"
#include "list.h"
+#include "wps.h"
#define MAX_LINE 1024
@@ -66,7 +67,6 @@ struct skin_draw_info {
bool no_line_break;
bool line_scrolls;
bool force_redraw;
- bool viewport_change;
char *buf;
size_t buf_size;
@@ -74,6 +74,8 @@ struct skin_draw_info {
int offset; /* used by the playlist viewer */
};
+extern void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label);
+
typedef bool (*skin_render_func)(struct skin_element* alternator, struct skin_draw_info *info);
bool skin_render_alternator(struct skin_element* alternator, struct skin_draw_info *info);
@@ -93,11 +95,11 @@ get_child(OFFSETTYPE(struct skin_element**) children, int child)
static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
- struct skin_element *element, struct skin_viewport* skin_vp)
+ struct skin_element *element)
{
struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data);
if (!token) return false;
- struct viewport *vp = &skin_vp->vp;
+ struct skin_viewport *skin_vp = info->skin_vp;
struct wps_data *data = gwps->data;
bool do_refresh = (element->tag->flags & info->refresh_type) > 0;
@@ -108,9 +110,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
{
struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (!col) return false;
- struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
- if (!vp) return false;
- vp->fg_pattern = col->colour;
+ skin_vp->vp.fg_pattern = col->colour;
skin_vp->fgbg_changed = true;
}
break;
@@ -118,9 +118,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
{
struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (!col) return false;
- struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
- if (!vp) return false;
- vp->bg_pattern = col->colour;
+ skin_vp->vp.bg_pattern = col->colour;
skin_vp->fgbg_changed = true;
}
break;
@@ -196,7 +194,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_PEAKMETER:
data->peak_meter_enabled = true;
if (do_refresh)
- draw_peakmeters(gwps, info->line_number, vp);
+ draw_peakmeters(gwps, info->line_number, &skin_vp->vp);
break;
case SKIN_TOKEN_DRAWRECTANGLE:
if (do_refresh)
@@ -215,13 +213,13 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
#endif
{
#if LCD_DEPTH > 1
- unsigned backup = vp->fg_pattern;
- vp->fg_pattern = rect->start_colour;
+ unsigned backup = skin_vp->vp.fg_pattern;
+ skin_vp->vp.fg_pattern = rect->start_colour;
#endif
gwps->display->fillrect(rect->x, rect->y, rect->width,
rect->height);
#if LCD_DEPTH > 1
- vp->fg_pattern = backup;
+ skin_vp->vp.fg_pattern = backup;
#endif
}
}
@@ -239,7 +237,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
{
struct progressbar *bar = (struct progressbar*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (do_refresh)
- draw_progressbar(gwps, info->line_number, bar);
+ draw_progressbar(gwps, info->skin_vp, info->line_number, bar);
}
break;
case SKIN_TOKEN_IMAGE_DISPLAY:
@@ -582,7 +580,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
{
break;
}
- if (!do_non_text_tags(info->gwps, info, child, info->skin_vp))
+ if (!do_non_text_tags(info->gwps, info, child))
{
static char tempbuf[128];
const char *valuestr = get_token_value(info->gwps, SKINOFFSETTOPTR(skin_buffer, child->data),
@@ -590,10 +588,6 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
sizeof(tempbuf), NULL);
if (valuestr)
{
-#if defined(ONDA_VX747) || defined(ONDA_VX747P)
- /* Doesn't redraw (in sim at least) */
- needs_update = true;
-#endif
#if CONFIG_RTC
if (child->tag->flags&SKIN_RTC_REFRESH)
needs_update = needs_update || info->refresh_type&SKIN_REFRESH_DYNAMIC;
@@ -606,10 +600,6 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
}
break;
case TEXT:
-#if defined(ONDA_VX747) || defined(ONDA_VX747P)
- /* Doesn't redraw (in sim at least) */
- needs_update = true;
-#endif
strlcat(info->cur_align_start, SKINOFFSETTOPTR(skin_buffer, child->data),
info->buf_size - (info->cur_align_start-info->buf));
needs_update = needs_update ||
@@ -943,7 +933,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
struct align_pos * align = &info.align;
bool needs_update;
int cur_pos, start_item, max;
- int nb_lines = viewport_get_nb_lines(SKINOFFSETTOPTR(skin_buffer, viewer->vp));
+ int nb_lines = viewport_get_nb_lines(&skin_viewport->vp);
#if CONFIG_TUNER
if (get_current_activity() == ACTIVITY_FM)
{
@@ -954,8 +944,8 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
else
#endif
{
- struct cuesheet *cue = skin_get_global_state()->id3 ?
- skin_get_global_state()->id3->cuesheet : NULL;
+ struct wps_state *state = get_wps_state();
+ struct cuesheet *cue = state->id3 ? state->id3->cuesheet : NULL;
cur_pos = playlist_get_display_index();
max = playlist_amount()+1;
if (cue)
@@ -989,7 +979,7 @@ void skin_render_playlistviewer(struct playlistviewer* viewer,
/* only update if the line needs to be, and there is something to write */
if (refresh_type && needs_update)
{
- struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, viewer->vp);
+ struct viewport *vp = &skin_viewport->vp;
if (!info.force_redraw)
display->scroll_stop_viewport_rect(vp,
0, info.line_number*display->getcharheight(),
diff --git a/apps/gui/skin_engine/skin_tokens.c b/apps/gui/skin_engine/skin_tokens.c
index 27022b87d1..f6c166b140 100644
--- a/apps/gui/skin_engine/skin_tokens.c
+++ b/apps/gui/skin_engine/skin_tokens.c
@@ -66,11 +66,10 @@
#include "fixedpoint.h"
#endif
#include "list.h"
+#include "wps.h"
#define NOINLINE __attribute__ ((noinline))
-extern struct wps_state wps_state;
-
static const char* get_codectype(const struct mp3entry* id3)
{
if (id3 && id3->codectype < AFMT_NUM_CODECS) {
@@ -115,7 +114,7 @@ char* get_dir(char* buf, int buf_size, const char* path, int level)
return NULL;
len = MIN(last_sep - sep, buf_size - 1);
- strlcpy(buf, sep + 1, len + 1);
+ strmemccpy(buf, sep + 1, len + 1);
return buf;
}
@@ -228,7 +227,7 @@ static const char* get_filename_token(struct wps_token *token, char* filename,
const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
char *filename, char *buf, int buf_size, int limit, int *intval)
{
- struct wps_state *state = &wps_state;
+ struct wps_state *state = get_wps_state();
if (id3)
{
unsigned long length = id3->length;
@@ -540,7 +539,7 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
static struct mp3entry* get_mp3entry_from_offset(int offset, char **filename)
{
struct mp3entry* pid3 = NULL;
- struct wps_state *state = skin_get_global_state();
+ struct wps_state *state = get_wps_state();
struct cuesheet *cue = state->id3 ? state->id3->cuesheet : NULL;
const char *fname = NULL;
if (cue && cue->curr_track_idx + offset < cue->track_count)
@@ -678,7 +677,7 @@ const char *get_token_value(struct gui_wps *gwps,
return NULL;
struct wps_data *data = gwps->data;
- struct wps_state *state = skin_get_global_state();
+ struct wps_state *state = get_wps_state();
struct mp3entry *id3; /* Think very carefully about using this.
maybe get_id3_token() is the better place? */
const char *out_text = NULL;
@@ -1040,37 +1039,19 @@ const char *get_token_value(struct gui_wps *gwps,
case SKIN_TOKEN_PLAYBACK_STATUS:
{
int status = current_playmode();
- /* music */
- int mode = 1; /* stop */
- if (status == STATUS_PLAY)
- mode = 2; /* play */
- if (state->is_fading ||
- (status == STATUS_PAUSE && !status_get_ffmode()))
- mode = 3; /* pause */
- else
- { /* ff / rwd */
- if (status_get_ffmode() == STATUS_FASTFORWARD)
- mode = 4;
- if (status_get_ffmode() == STATUS_FASTBACKWARD)
- mode = 5;
+ switch (status) {
+ case STATUS_STOP:
+ numeric_ret = 1;
+ break;
+ case STATUS_PLAY:
+ numeric_ret = 2;
+ break;
+ default:
+ numeric_ret = status + 1;
+ break;
}
-#ifdef HAVE_RECORDING
- /* recording */
- if (status == STATUS_RECORD)
- mode = 6;
- else if (status == STATUS_RECORD_PAUSE)
- mode = 7;
-#endif
-#if CONFIG_TUNER
- /* radio */
- if (status == STATUS_RADIO)
- mode = 8;
- else if (status == STATUS_RADIO_PAUSE)
- mode = 9;
-#endif
- numeric_ret = mode;
- snprintf(buf, buf_size, "%d", mode-1);
+ snprintf(buf, buf_size, "%d", numeric_ret-1);
numeric_buf = buf;
goto gtv_ret_numeric_tag_info;
}
@@ -1390,7 +1371,7 @@ const char *get_token_value(struct gui_wps *gwps,
case SKIN_TOKEN_SETTING:
{
- const struct settings_list *s = settings+token->value.i;
+ const struct settings_list *s = token->value.xdata;
if (intval)
{
/* Handle contionals */
@@ -1461,7 +1442,7 @@ const char *get_token_value(struct gui_wps *gwps,
goto gtv_ret_numeric_tag_info;
}
}
- cfg_to_string(token->value.i,buf,buf_size);
+ cfg_to_string(s, buf, buf_size);
numeric_buf = buf;
goto gtv_ret_numeric_tag_info;
}
diff --git a/apps/gui/skin_engine/skin_touchsupport.c b/apps/gui/skin_engine/skin_touchsupport.c
index 045bc809c8..b952709562 100644
--- a/apps/gui/skin_engine/skin_touchsupport.c
+++ b/apps/gui/skin_engine/skin_touchsupport.c
@@ -35,8 +35,9 @@
#include "dsp_misc.h"
/** Disarms all touchregions. */
-void skin_disarm_touchregions(struct wps_data *data)
+void skin_disarm_touchregions(struct gui_wps *gwps)
{
+ struct wps_data *data = gwps->data;
char* skin_buffer = get_skin_buffer(data);
struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
while (regions)
@@ -52,9 +53,9 @@ void skin_disarm_touchregions(struct wps_data *data)
* egde_offset is a percentage value for the position of the touch
* inside the bar for regions which arnt WPS_TOUCHREGION_ACTION type.
*/
-int skin_get_touchaction(struct wps_data *data, int* edge_offset,
- struct touchregion **retregion)
+int skin_get_touchaction(struct gui_wps *gwps, int* edge_offset)
{
+ struct wps_data *data = gwps->data;
int returncode = ACTION_NONE;
short x,y;
short vx, vy;
@@ -162,9 +163,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
/* On release, all regions are disarmed. */
if (released)
- skin_disarm_touchregions(data);
- if (retregion && temp)
- *retregion = temp;
+ skin_disarm_touchregions(gwps);
if (temp && temp->press_length == LONG_PRESS)
temp->armed = false;
@@ -301,7 +300,7 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
case ACTION_TOUCH_REPMODE: /* cycle the repeat mode setting */
{
const struct settings_list *rep_setting =
- find_setting(&global_settings.repeat_mode, NULL);
+ find_setting(&global_settings.repeat_mode);
option_select_next_val(rep_setting, false, true);
audio_flush_and_reload_tracks();
returncode = ACTION_REDRAW;
@@ -314,9 +313,9 @@ int skin_get_touchaction(struct wps_data *data, int* edge_offset,
if (bar && edge_offset)
{
int val, count;
- get_setting_info_for_bar(bar->setting_id, &count, &val);
+ get_setting_info_for_bar(bar->setting, &count, &val);
val = *edge_offset * count / 1000;
- update_setting_value_from_touch(bar->setting_id, val);
+ update_setting_value_from_touch(bar->setting, val);
}
}
break;
diff --git a/apps/gui/skin_engine/wps_internals.h b/apps/gui/skin_engine/wps_internals.h
index bf368bc4f3..8ad8325e66 100644
--- a/apps/gui/skin_engine/wps_internals.h
+++ b/apps/gui/skin_engine/wps_internals.h
@@ -31,6 +31,8 @@
#include "core_alloc.h"
#endif
+struct wps_data;
+
struct skin_stats {
size_t buflib_handles;
size_t tree_size;
@@ -42,6 +44,13 @@ struct skin_stats *skin_get_stats(int number, int screen);
#define skin_clear_stats(stats) memset(stats, 0, sizeof(struct skin_stats))
bool skin_backdrop_get_debug(int index, char **path, int *ref_count, size_t *size);
+/*
+ * setup up the skin-data from a format-buffer (isfile = false)
+ * or from a skinfile (isfile = true)
+ */
+bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
+ const char *buf, bool isfile, struct skin_stats *stats);
+
/* Timeout unit expressed in HZ. In WPS, all timeouts are given in seconds
(possibly with a decimal fraction) but stored as integer values.
E.g. 2.5 is stored as 25. This means 25 tenth of a second, i.e. 25 units.
@@ -64,6 +73,7 @@ struct wps_token {
unsigned short i;
long l;
OFFSETTYPE(void*) data;
+ void *xdata;
} value;
enum skin_token_type type; /* enough to store the token type */
@@ -81,7 +91,6 @@ struct skin_token_list {
};
struct gui_img {
- OFFSETTYPE(struct viewport*) vp; /* The viewport to display this image in */
short int x; /* x-pos */
short int y; /* y-pos */
short int num_subimages; /* number of sub-images */
@@ -93,6 +102,7 @@ struct gui_img {
int display;
bool using_preloaded_icons; /* using the icon system instead of a bmp */
bool is_9_segment;
+ bool dither;
};
struct image_display {
@@ -104,7 +114,6 @@ struct image_display {
struct progressbar {
enum skin_token_type type;
- OFFSETTYPE(struct viewport *) vp;
/* regular pb */
short x;
/* >=0: explicitly set in the tag -> y-coord within the viewport
@@ -124,7 +133,7 @@ struct progressbar {
OFFSETTYPE(struct gui_img *) slider;
bool horizontal;
OFFSETTYPE(struct gui_img *) backdrop;
- int setting_id; /* for the setting bar type */
+ const struct settings_list *setting;
};
@@ -189,7 +198,6 @@ struct skin_viewport {
#endif
};
struct viewport_colour {
- OFFSETTYPE(struct viewport *) vp;
unsigned colour;
};
@@ -236,7 +244,6 @@ struct touchregion_lastpress {
#endif
struct playlistviewer {
- OFFSETTYPE(struct viewport *) vp;
bool show_icons;
int start_offset;
OFFSETTYPE(struct skin_element *) line;
@@ -267,7 +274,6 @@ struct skin_albumart {
unsigned char yalign; /* WPS_ALBUMART_ALIGN_TOP, _CENTER, _BOTTOM */
unsigned char state; /* WPS_ALBUMART_NONE, _CHECK, _LOAD */
- OFFSETTYPE(struct viewport *) vp;
int draw_handle;
};
#endif
@@ -313,6 +319,17 @@ struct listitem {
short offset;
};
+struct listitem_viewport_cfg {
+ struct wps_data *data;
+ OFFSETTYPE(char *) label;
+ int width;
+ int height;
+ int xmargin;
+ int ymargin;
+ bool tile;
+ struct skin_viewport selected_item_vp;
+};
+
#ifdef HAVE_SKIN_VARIABLES
struct skin_var {
OFFSETTYPE(const char *) label;
@@ -372,7 +389,7 @@ struct wps_data
#ifndef __PCTOOL__
static inline char* get_skin_buffer(struct wps_data* data)
{
- if (data->buflib_handle >= 0)
+ if (data->buflib_handle > 0)
return core_get_data(data->buflib_handle);
return NULL;
}
@@ -382,30 +399,6 @@ static inline char* get_skin_buffer(struct wps_data* data)
/* wps_data end */
-/* wps_state
- holds the data which belongs to the current played track,
- the track which will be played afterwards, current path to the track
- and some status infos */
-struct wps_state
-{
- struct mp3entry* id3;
- struct mp3entry* nid3;
- int ff_rewind_count;
- bool ff_rewind;
- bool paused;
- bool is_fading;
-};
-
-/* change the ff/rew-status
- if ff_rew = true then we are in skipping mode
- else we are in normal mode */
-/* void wps_state_update_ff_rew(bool ff_rew); Currently unused */
-
-/* change the tag-information of the current played track
- and the following track */
-/* void wps_state_update_id3_nid3(struct mp3entry *id3, struct mp3entry *nid3); Currently unused */
-/* wps_state end*/
-
/* gui_wps
defines a wps with its data, state,
and the screen on which the wps-content should be drawn */
diff --git a/apps/gui/splash.c b/apps/gui/splash.c
index b85e4693aa..d0f1fbb67c 100644
--- a/apps/gui/splash.c
+++ b/apps/gui/splash.c
@@ -29,71 +29,84 @@
#include "talk.h"
#include "splash.h"
#include "viewport.h"
-#include "strtok_r.h"
+#include "strptokspn_r.h"
+#include "scrollbar.h"
+#include "font.h"
+
+static long progress_next_tick = 0;
#define MAXLINES (LCD_HEIGHT/6)
#define MAXBUFFER 512
#define RECT_SPACING 2
#define SPLASH_MEMORY_INTERVAL (HZ)
-static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
+static bool splash_internal(struct screen * screen, const char *fmt, va_list ap,
+ struct viewport *vp, int addl_lines)
{
char splash_buf[MAXBUFFER];
- char *lines[MAXLINES];
-
- char *next;
- char *lastbreak = NULL;
- char *store = NULL;
+ struct splash_lines {
+ const char *str;
+ size_t len;
+ } lines[MAXLINES];
+ const char *next;
+ const char *lastbreak = NULL;
+ const char *store = NULL;
int line = 0;
int x = 0;
int y, i;
- int space_w, w, h;
- struct viewport vp;
+ int space_w, w, chr_h;
int width, height;
int maxw = 0;
+ int fontnum = vp->font;
- viewport_set_defaults(&vp, screen->screen_type);
- struct viewport *last_vp = screen->set_viewport(&vp);
-
- screen->getstringsize(" ", &space_w, &h);
- y = h;
+ char lastbrkchr;
+ size_t len, next_len;
+ const char matchstr[] = "\r\n\f\v\t ";
+ font_getstringsize(" ", &space_w, &chr_h, fontnum);
+ y = chr_h + (addl_lines * chr_h);
vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
va_end(ap);
/* break splash string into display lines, doing proper word wrap */
-
- next = strtok_r(splash_buf, " ", &store);
+ next = strptokspn_r(splash_buf, matchstr, &next_len, &store);
if (!next)
- goto end; /* nothing to display */
+ return false; /* nothing to display */
- lines[0] = next;
+ lines[line].len = next_len;
+ lines[line].str = next;
while (true)
{
- screen->getstringsize(next, &w, NULL);
+ w = font_getstringnsize(next, next_len, NULL, NULL, fontnum);
if (lastbreak)
{
- if (x + (next - lastbreak) * space_w + w
- > vp.width - RECT_SPACING*2)
- { /* too wide, wrap */
+ len = next - lastbreak;
+ int next_w = len * space_w;
+ if (x + next_w + w > vp->width - RECT_SPACING*2 || lastbrkchr != ' ')
+ { /* too wide, or control character wrap */
if (x > maxw)
maxw = x;
- if ((y + h > vp.height) || (line >= (MAXLINES-1)))
+ if ((y + chr_h * 2 > vp->height) || (line >= (MAXLINES-1)))
break; /* screen full or out of lines */
x = 0;
- y += h;
- lines[++line] = next;
+ y += chr_h;
+ lines[++line].len = next_len;
+ lines[line].str = next;
}
else
{
/* restore & calculate spacing */
- *lastbreak = ' ';
- x += (next - lastbreak) * space_w;
+ lines[line].len += next_len + 1;
+ x += next_w;
}
}
x += w;
- lastbreak = next + strlen(next);
- next = strtok_r(NULL, " ", &store);
+
+ lastbreak = next + next_len;
+ lastbrkchr = *lastbreak;
+
+ next = strptokspn_r(NULL, matchstr, &next_len, &store);
+
if (!next)
{ /* no more words */
if (x > maxw)
@@ -111,53 +124,48 @@ static void splash_internal(struct screen * screen, const char *fmt, va_list ap)
width = maxw + 2*RECT_SPACING;
height = y + 2*RECT_SPACING;
- if (width > vp.width)
- width = vp.width;
- if (height > vp.height)
- height = vp.height;
+ if (width > vp->width)
+ width = vp->width;
+ if (height > vp->height)
+ height = vp->height;
- vp.x += (vp.width - width) / 2;
- vp.y += (vp.height - height) / 2;
- vp.width = width;
- vp.height = height;
+ vp->x += (vp->width - width) / 2;
+ vp->y += (vp->height - height) / 2;
+ vp->width = width;
+ vp->height = height;
- vp.flags |= VP_FLAG_ALIGN_CENTER;
+ vp->flags |= VP_FLAG_ALIGN_CENTER;
#if LCD_DEPTH > 1
if (screen->depth > 1)
{
- vp.drawmode = DRMODE_FG;
- /* can't do vp.fg_pattern here, since set_foreground does a bit more on
+ vp->drawmode = DRMODE_FG;
+ /* can't do vp->fg_pattern here, since set_foreground does a bit more on
* greyscale */
screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
}
else
#endif
- vp.drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID);
+ vp->drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID);
screen->fill_viewport();
#if LCD_DEPTH > 1
if (screen->depth > 1)
- /* can't do vp.fg_pattern here, since set_foreground does a bit more on
+ /* can't do vp->fg_pattern here, since set_foreground does a bit more on
* greyscale */
screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
else
#endif
- vp.drawmode = DRMODE_SOLID;
+ vp->drawmode = DRMODE_SOLID;
screen->draw_border_viewport();
- /* prepare putting the text */
- y = RECT_SPACING;
-
/* print the message to screen */
- for (i = 0; i <= line; i++, y+=h)
+ for(i = 0, y = RECT_SPACING; i <= line; i++, y+= chr_h)
{
- screen->putsxy(0, y, lines[i]);
+ screen->putsxyf(0, y, "%.*s", lines[i].len, lines[i].str);
}
- screen->update_viewport();
-end:
- screen->set_viewport(last_vp);
+ return true; /* needs update */
}
void splashf(int ticks, const char *fmt, ...)
@@ -169,9 +177,17 @@ void splashf(int ticks, const char *fmt, ...)
fmt = P2STR((unsigned char *)fmt);
FOR_NB_SCREENS(i)
{
+ struct screen * screen = &(screens[i]);
+ struct viewport vp;
+ viewport_set_defaults(&vp, screen->screen_type);
+ struct viewport *last_vp = screen->set_viewport(&vp);
+
va_start(ap, fmt);
- splash_internal(&(screens[i]), fmt, ap);
+ if (splash_internal(screen, fmt, ap, &vp, 0))
+ screen->update_viewport();
va_end(ap);
+
+ screen->set_viewport(last_vp);
}
if (ticks)
sleep(ticks);
@@ -189,3 +205,59 @@ void splash(int ticks, const char *str)
#endif
splashf(ticks, "%s", P2STR((const unsigned char*)str));
}
+
+/* set delay before progress meter is shown */
+void splash_progress_set_delay(long delay_ticks)
+{
+ progress_next_tick = current_tick + delay_ticks;
+}
+
+/* splash a progress meter */
+void splash_progress(int current, int total, const char *fmt, ...)
+{
+ va_list ap;
+ int vp_flag = VP_FLAG_VP_DIRTY;
+ /* progress update tick */
+ long now = current_tick;
+
+ if (current < total)
+ {
+ if(TIME_BEFORE(now, progress_next_tick))
+ return;
+ /* limit to 20fps */
+ progress_next_tick = now + HZ/20;
+ vp_flag = 0; /* don't mark vp dirty to prevent flashing */
+ }
+
+ /* If fmt is a lang ID then get the corresponding string (which
+ still might contain % place holders). */
+ fmt = P2STR((unsigned char *)fmt);
+ FOR_NB_SCREENS(i)
+ {
+ struct screen * screen = &(screens[i]);
+ struct viewport vp;
+ viewport_set_defaults(&vp, screen->screen_type);
+ struct viewport *last_vp = screen->set_viewport_ex(&vp, vp_flag);
+
+ va_start(ap, fmt);
+ if (splash_internal(screen, fmt, ap, &vp, 1))
+ {
+ int size = screen->getcharheight();
+ int x = RECT_SPACING;
+ int y = vp.height - size - RECT_SPACING;
+ int w = vp.width - RECT_SPACING * 2;
+ int h = size;
+#ifdef HAVE_LCD_COLOR
+ const int sb_flags = HORIZONTAL | FOREGROUND;
+#else
+ const int sb_flags = HORIZONTAL;
+#endif
+ gui_scrollbar_draw(screen, x, y, w, h, total, 0, current, sb_flags);
+
+ screen->update_viewport();
+ }
+ va_end(ap);
+
+ screen->set_viewport(last_vp);
+ }
+}
diff --git a/apps/gui/splash.h b/apps/gui/splash.h
index 76b4c16d0c..f7ff44e00b 100644
--- a/apps/gui/splash.h
+++ b/apps/gui/splash.h
@@ -39,4 +39,15 @@ extern void splashf(int ticks, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);
* it will be voiced
*/
extern void splash(int ticks, const char *str);
+
+/* set a delay before displaying the progress meter the first time */
+extern void splash_progress_set_delay(long delay_ticks);
+/*
+ * Puts a splash message centered on all the screens with a progressbar
+ * - current : current progress increment
+ * - total : total increments
+ * - fmt : what to say *printf style
+ * updates limited internally to 20 fps - call repeatedly to update progress
+ */
+extern void splash_progress(int current, int total, const char *fmt, ...) ATTRIBUTE_PRINTF(3, 4);
#endif /* _GUI_ICON_H_ */
diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c
index fd695bf6b6..8dd66641dd 100644
--- a/apps/gui/statusbar-skinned.c
+++ b/apps/gui/statusbar-skinned.c
@@ -27,7 +27,6 @@
#include "appevents.h"
#include "screens.h"
#include "screen_access.h"
-#include "strlcpy.h"
#include "skin_parser.h"
#include "skin_buffer.h"
#include "skin_engine/skin_engine.h"
@@ -49,11 +48,13 @@
static int update_delay = DEFAULT_UPDATE_DELAY;
static bool sbs_has_title[NB_SCREENS];
-static char* sbs_title[NB_SCREENS];
+static const char* sbs_title[NB_SCREENS];
static enum themable_icons sbs_icon[NB_SCREENS];
static bool sbs_loaded[NB_SCREENS] = { false };
-bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen)
+void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label);
+
+bool sb_set_title_text(const char* title, enum themable_icons icon, enum screen_type screen)
{
sbs_title[screen] = title;
/* Icon_NOICON == -1 which the skin engine wants at position 1, so + 2 */
@@ -305,18 +306,17 @@ void sb_bypass_touchregions(bool enable)
int sb_touch_to_button(int context)
{
- struct touchregion *region;
static int last_context = -1;
int button, offset;
if (bypass_sb_touchregions)
return ACTION_TOUCHSCREEN;
-
+
+ struct gui_wps *gwps = skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN);
if (last_context != context)
- skin_disarm_touchregions(skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN)->data);
+ skin_disarm_touchregions(gwps);
last_context = context;
- button = skin_get_touchaction(skin_get_gwps(CUSTOM_STATUSBAR, SCREEN_MAIN)->data,
- &offset, &region);
-
+
+ button = skin_get_touchaction(gwps, &offset);
switch (button)
{
#ifdef HAVE_VOLUME_IN_LIST
diff --git a/apps/gui/statusbar-skinned.h b/apps/gui/statusbar-skinned.h
index 3ed36f1a84..e8fa14e676 100644
--- a/apps/gui/statusbar-skinned.h
+++ b/apps/gui/statusbar-skinned.h
@@ -30,16 +30,15 @@
#include "icon.h"
#include "skin_engine/skin_engine.h"
-void sb_skin_data_load(enum screen_type screen, const char *buf, bool isfile);
+struct wps_data;
char* sb_create_from_settings(enum screen_type screen);
void sb_skin_init(void) INIT_ATTR;
-void sb_set_info_vp(enum screen_type screen, OFFSETTYPE(char*) label);
struct viewport *sb_skin_get_info_vp(enum screen_type screen);
void sb_skin_update(enum screen_type screen, bool force);
void sb_skin_set_update_delay(int delay);
-bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen);
+bool sb_set_title_text(const char* title, enum themable_icons icon, enum screen_type screen);
void sb_skin_has_title(enum screen_type screen);
const char* sb_get_title(enum screen_type screen);
enum themable_icons sb_get_icon(enum screen_type screen);
diff --git a/apps/gui/usb_screen.c b/apps/gui/usb_screen.c
index 31321ec005..fb59f820b6 100644
--- a/apps/gui/usb_screen.c
+++ b/apps/gui/usb_screen.c
@@ -41,6 +41,7 @@
#include "skin_engine/skin_engine.h"
#include "playlist.h"
#include "misc.h"
+#include "icons.h"
#include "bitmaps/usblogo.h"
@@ -155,7 +156,24 @@ static void usb_screen_fix_viewports(struct screen *screen,
*logo = *parent;
logo->x = parent->x + parent->width - logo_width;
+#ifdef HAVE_LCD_SPLIT
+ switch (statusbar_position(screen))
+ {
+ /* start beyond split */
+ case STATUSBAR_OFF:
+ logo->y = parent->y + LCD_SPLIT_POS;
+ break;
+ case STATUSBAR_TOP:
+ logo->y = parent->y + LCD_SPLIT_POS - STATUSBAR_HEIGHT;
+ break;
+ /* start at the top for maximum space */
+ default:
+ logo->y = parent->y;
+ break;
+ }
+#else
logo->y = parent->y + (parent->height - logo_height) / 2;
+#endif
logo->width = logo_width;
logo->height = logo_height;
diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c
index 9f9cb186f5..e90426a132 100644
--- a/apps/gui/viewport.c
+++ b/apps/gui/viewport.c
@@ -233,7 +233,7 @@ static void viewportmanager_redraw(unsigned short id, void* data)
}
}
-void viewportmanager_init()
+void viewportmanager_init(void)
{
FOR_NB_SCREENS(i)
{
@@ -348,41 +348,3 @@ void viewport_set_defaults(struct viewport *vp,
#endif /* !__PCTOOL__ */
viewport_set_fullscreen(vp, screen);
}
-
-
-int get_viewport_default_colour(enum screen_type screen, bool fgcolour)
-{
- (void)screen; (void)fgcolour;
-#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
- int colour;
- if (fgcolour)
- {
-#if (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
- if (screen == SCREEN_REMOTE)
- colour = REMOTE_FG_FALLBACK;
- else
-#endif
-#if defined(HAVE_LCD_COLOR)
- colour = global_settings.fg_color;
-#else
- colour = FG_FALLBACK;
-#endif
- }
- else
- {
-#if (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
- if (screen == SCREEN_REMOTE)
- colour = REMOTE_BG_FALLBACK;
- else
-#endif
-#if defined(HAVE_LCD_COLOR)
- colour = global_settings.bg_color;
-#else
- colour = BG_FALLBACK;
-#endif
- }
- return colour;
-#else
- return 0;
-#endif /* LCD_DEPTH > 1 || LCD_REMOTE_DEPTH > 1 */
-}
diff --git a/apps/gui/viewport.h b/apps/gui/viewport.h
index 2810be2ac3..c57a58b232 100644
--- a/apps/gui/viewport.h
+++ b/apps/gui/viewport.h
@@ -43,7 +43,6 @@ void viewport_set_defaults(struct viewport *vp,
const enum screen_type screen);
void viewport_set_fullscreen(struct viewport *vp,
const enum screen_type screen);
-int get_viewport_default_colour(enum screen_type screen, bool fgcolour);
#ifndef __PCTOOL__
diff --git a/apps/gui/wps.c b/apps/gui/wps.c
index 7554892451..260730c4a1 100644
--- a/apps/gui/wps.c
+++ b/apps/gui/wps.c
@@ -53,6 +53,7 @@
#include "root_menu.h"
#include "backdrop.h"
#include "quickscreen.h"
+#include "shortcuts.h"
#include "pitchscreen.h"
#include "appevents.h"
#include "viewport.h"
@@ -61,14 +62,15 @@
#include "playlist_viewer.h"
#include "wps.h"
#include "statusbar-skinned.h"
-
-#define RESTORE_WPS_INSTANTLY 0l
-#define RESTORE_WPS_NEXT_SECOND ((long)(HZ+current_tick))
+#include "skin_engine/wps_internals.h"
+#include "open_plugin.h"
#define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */
/* 3% of 30min file == 54s step size */
#define MIN_FF_REWIND_STEP 500
+static struct wps_state wps_state;
+
/* initial setup of wps_data */
static void wps_state_init(void);
static void track_info_callback(unsigned short id, void *param);
@@ -114,7 +116,7 @@ static void update_non_static(void)
skin_update(WPS, i, SKIN_REFRESH_NON_STATIC);
}
-void pause_action(bool may_fade, bool updatewps)
+void pause_action(bool updatewps)
{
/* Do audio first, then update, unless skin were to use its local
status in which case, reverse it */
@@ -131,11 +133,9 @@ void pause_action(bool may_fade, bool updatewps)
- global_settings.pause_rewind * 1000;
audio_ff_rewind(newpos > 0 ? newpos : 0);
}
-
- (void)may_fade;
}
-void unpause_action(bool may_fade, bool updatewps)
+void unpause_action(bool updatewps)
{
/* Do audio first, then update, unless skin were to use its local
status in which case, reverse it */
@@ -143,24 +143,15 @@ void unpause_action(bool may_fade, bool updatewps)
if (updatewps)
update_non_static();
-
- (void)may_fade;
-}
-
-static bool update_onvol_change(enum screen_type screen)
-{
- skin_update(WPS, screen, SKIN_REFRESH_NON_STATIC);
-
- return false;
}
-
#ifdef HAVE_TOUCHSCREEN
-static int skintouch_to_wps(struct wps_data *data)
+static int skintouch_to_wps(void)
{
int offset = 0;
- struct touchregion *region;
- int button = skin_get_touchaction(data, &offset, &region);
+ struct wps_state *gstate = get_wps_state();
+ struct gui_wps *gwps = skin_get_gwps(WPS, SCREEN_MAIN);
+ int button = skin_get_touchaction(gwps, &offset);
switch (button)
{
case ACTION_STD_PREV:
@@ -182,17 +173,17 @@ static int skintouch_to_wps(struct wps_data *data)
return ACTION_WPS_HOTKEY;
#endif
case ACTION_TOUCH_SCROLLBAR:
- skin_get_global_state()->id3->elapsed = skin_get_global_state()->id3->length*offset/1000;
+ gstate->id3->elapsed = gstate->id3->length*offset/1000;
audio_pre_ff_rewind();
- audio_ff_rewind(skin_get_global_state()->id3->elapsed);
+ audio_ff_rewind(gstate->id3->elapsed);
return ACTION_TOUCHSCREEN;
case ACTION_TOUCH_VOLUME:
{
const int min_vol = sound_min(SOUND_VOLUME);
const int max_vol = sound_max(SOUND_VOLUME);
const int step_vol = sound_steps(SOUND_VOLUME);
- global_settings.volume = (offset * (max_vol - min_vol)) / 1000;
- global_settings.volume += min_vol;
+
+ global_settings.volume = from_normalized_volume(offset, min_vol, max_vol, 1000);
global_settings.volume -= (global_settings.volume % step_vol);
setvol();
}
@@ -202,7 +193,7 @@ static int skintouch_to_wps(struct wps_data *data)
}
#endif /* HAVE_TOUCHSCREEN */
-bool ffwd_rew(int button)
+static bool ffwd_rew(int button, bool seek_from_end)
{
unsigned int step = 0; /* current ff/rewind step */
unsigned int max_step = 0; /* maximum ff/rewind step */
@@ -210,7 +201,10 @@ bool ffwd_rew(int button)
int direction = -1; /* forward=1 or backward=-1 */
bool exit = false;
bool usb = false;
+ bool ff_rewind = false;
const long ff_rw_accel = (global_settings.ff_rewind_accel + 3);
+ struct wps_state *gstate = get_wps_state();
+ struct mp3entry *old_id3 = gstate->id3;
if (button == ACTION_NONE)
{
@@ -219,27 +213,37 @@ bool ffwd_rew(int button)
}
while (!exit)
{
+ struct mp3entry *id3 = gstate->id3;
+ if (id3 != old_id3)
+ {
+ ff_rewind = false;
+ ff_rewind_count = 0;
+ old_id3 = id3;
+ }
+ if (id3 && seek_from_end)
+ id3->elapsed = id3->length;
+
switch ( button )
{
case ACTION_WPS_SEEKFWD:
direction = 1;
/* Fallthrough */
case ACTION_WPS_SEEKBACK:
- if (skin_get_global_state()->ff_rewind)
+ if (ff_rewind)
{
if (direction == 1)
{
/* fast forwarding, calc max step relative to end */
- max_step = (skin_get_global_state()->id3->length -
- (skin_get_global_state()->id3->elapsed +
+ max_step = (id3->length -
+ (id3->elapsed +
ff_rewind_count)) *
FF_REWIND_MAX_PERCENT / 100;
}
else
{
/* rewinding, calc max step relative to start */
- max_step = (skin_get_global_state()->id3->elapsed + ff_rewind_count) *
- FF_REWIND_MAX_PERCENT / 100;
+ max_step = (id3->elapsed + ff_rewind_count) *
+ FF_REWIND_MAX_PERCENT / 100;
}
max_step = MAX(max_step, MIN_FF_REWIND_STEP);
@@ -254,8 +258,7 @@ bool ffwd_rew(int button)
}
else
{
- if ( (audio_status() & AUDIO_STATUS_PLAY) &&
- skin_get_global_state()->id3 && skin_get_global_state()->id3->length )
+ if ((audio_status() & AUDIO_STATUS_PLAY) && id3 && id3->length )
{
audio_pre_ff_rewind();
if (direction > 0)
@@ -263,7 +266,7 @@ bool ffwd_rew(int button)
else
status_set_ffmode(STATUS_FASTBACKWARD);
- skin_get_global_state()->ff_rewind = true;
+ ff_rewind = true;
step = 1000 * global_settings.ff_rewind_min_step;
}
@@ -272,19 +275,17 @@ bool ffwd_rew(int button)
}
if (direction > 0) {
- if ((skin_get_global_state()->id3->elapsed + ff_rewind_count) >
- skin_get_global_state()->id3->length)
- ff_rewind_count = skin_get_global_state()->id3->length -
- skin_get_global_state()->id3->elapsed;
+ if ((id3->elapsed + ff_rewind_count) > id3->length)
+ ff_rewind_count = id3->length - id3->elapsed;
}
else {
- if ((int)(skin_get_global_state()->id3->elapsed + ff_rewind_count) < 0)
- ff_rewind_count = -skin_get_global_state()->id3->elapsed;
+ if ((int)(id3->elapsed + ff_rewind_count) < 0)
+ ff_rewind_count = -id3->elapsed;
}
/* set the wps state ff_rewind_count so the progess info
displays corectly */
- skin_get_global_state()->ff_rewind_count = ff_rewind_count;
+ gstate->ff_rewind_count = ff_rewind_count;
FOR_NB_SCREENS(i)
{
@@ -296,10 +297,10 @@ bool ffwd_rew(int button)
break;
case ACTION_WPS_STOPSEEK:
- skin_get_global_state()->id3->elapsed = skin_get_global_state()->id3->elapsed+ff_rewind_count;
- audio_ff_rewind(skin_get_global_state()->id3->elapsed);
- skin_get_global_state()->ff_rewind_count = 0;
- skin_get_global_state()->ff_rewind = false;
+ id3->elapsed = id3->elapsed + ff_rewind_count;
+ audio_ff_rewind(id3->elapsed);
+ gstate->ff_rewind_count = 0;
+ ff_rewind = false;
status_set_ffmode(0);
exit = true;
break;
@@ -317,20 +318,21 @@ bool ffwd_rew(int button)
button = get_action(CONTEXT_WPS|ALLOW_SOFTLOCK,TIMEOUT_BLOCK);
#ifdef HAVE_TOUCHSCREEN
if (button == ACTION_TOUCHSCREEN)
- button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
+ button = skintouch_to_wps();
#endif
- if (button != ACTION_WPS_SEEKFWD &&
- button != ACTION_WPS_SEEKBACK)
+ if (button != ACTION_WPS_SEEKFWD
+ && button != ACTION_WPS_SEEKBACK
+ && button != 0 && !IS_SYSEVENT(button))
button = ACTION_WPS_STOPSEEK;
}
}
return usb;
}
-#if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD)
static void gwps_caption_backlight(struct wps_state *state)
{
- if (state && state->id3)
+#if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD)
+ if (state->id3)
{
#ifdef HAVE_BACKLIGHT
if (global_settings.caption_backlight)
@@ -366,9 +368,10 @@ static void gwps_caption_backlight(struct wps_state *state)
}
#endif
}
+#else
+ (void) state;
+#endif /* def HAVE_BACKLIGHT || def HAVE_REMOTE_LCD */
}
-#endif
-
static void change_dir(int direction)
{
@@ -385,7 +388,7 @@ static void change_dir(int direction)
static void prev_track(unsigned long skip_thresh)
{
- struct wps_state *state = skin_get_global_state();
+ struct wps_state *state = get_wps_state();
if (state->id3->elapsed < skip_thresh)
{
audio_prev();
@@ -406,7 +409,7 @@ static void prev_track(unsigned long skip_thresh)
static void next_track(void)
{
- struct wps_state *state = skin_get_global_state();
+ struct wps_state *state = get_wps_state();
/* take care of if we're playing a cuesheet */
if (state->id3->cuesheet)
{
@@ -423,7 +426,7 @@ static void next_track(void)
static void play_hop(int direction)
{
- struct wps_state *state = skin_get_global_state();
+ struct wps_state *state = get_wps_state();
struct cuesheet *cue = state->id3->cuesheet;
long step = global_settings.skip_length*1000;
long elapsed = state->id3->elapsed;
@@ -442,26 +445,40 @@ static void play_hop(int direction)
{
if (direction < 0)
{
- prev_track(DEFAULT_SKIP_TRESH);
+ prev_track(DEFAULT_SKIP_THRESH);
return;
}
- else if (remaining < DEFAULT_SKIP_TRESH*2)
+ else if (remaining < DEFAULT_SKIP_THRESH*2)
{
next_track();
return;
}
else
- elapsed += (remaining - DEFAULT_SKIP_TRESH*2);
+ elapsed += (remaining - DEFAULT_SKIP_THRESH*2);
}
else if (!global_settings.prevent_skip &&
(!step ||
(direction > 0 && step >= remaining) ||
- (direction < 0 && elapsed < DEFAULT_SKIP_TRESH)))
+ (direction < 0 && elapsed < DEFAULT_SKIP_THRESH)))
{ /* Do normal track skipping */
if (direction > 0)
next_track();
else if (direction < 0)
- prev_track(DEFAULT_SKIP_TRESH);
+ {
+ if (step > 0 && global_settings.rewind_across_tracks && elapsed < DEFAULT_SKIP_THRESH && playlist_check(-1))
+ {
+ bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false;
+ if (!audio_paused)
+ audio_pause();
+ audio_prev();
+ audio_ff_rewind(-step);
+ if (!audio_paused)
+ audio_resume();
+ return;
+ }
+
+ prev_track(DEFAULT_SKIP_THRESH);
+ }
return;
}
else if (direction == 1 && step >= remaining)
@@ -485,7 +502,6 @@ static void play_hop(int direction)
audio_ff_rewind(elapsed);
}
-
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
/*
* If the user is unable to see the wps, because the display is deactivated,
@@ -502,16 +518,19 @@ static void wps_lcd_activation_hook(unsigned short id, void *param)
}
#endif
-static void gwps_leave_wps(void)
+static void gwps_leave_wps(bool theme_enabled)
{
FOR_NB_SCREENS(i)
{
- skin_get_gwps(WPS, i)->display->scroll_stop();
+ struct gui_wps *gwps = skin_get_gwps(WPS, i);
+ gwps->display->scroll_stop();
+ if (theme_enabled)
+ {
#ifdef HAVE_BACKDROP_IMAGE
- skin_backdrop_show(sb_get_backdrop(i));
+ skin_backdrop_show(sb_get_backdrop(i));
#endif
- viewportmanager_theme_undo(i, skin_has_sbs(i, skin_get_gwps(WPS, i)->data));
-
+ viewportmanager_theme_undo(i, skin_has_sbs(gwps));
+ }
}
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
@@ -525,19 +544,30 @@ static void gwps_leave_wps(void)
#endif
}
+static void restore_theme(void)
+{
+ FOR_NB_SCREENS(i)
+ {
+ struct gui_wps *gwps = skin_get_gwps(WPS, i);
+ struct screen *display = gwps->display;
+ display->scroll_stop();
+ viewportmanager_theme_enable(i, skin_has_sbs(gwps), NULL);
+ }
+}
+
/*
* display the wps on entering or restoring */
-static void gwps_enter_wps(void)
+static void gwps_enter_wps(bool theme_enabled)
{
struct gui_wps *gwps;
struct screen *display;
+ if (theme_enabled)
+ restore_theme();
FOR_NB_SCREENS(i)
{
gwps = skin_get_gwps(WPS, i);
display = gwps->display;
display->scroll_stop();
- viewportmanager_theme_enable(i, skin_has_sbs(i, skin_get_gwps(WPS, i)->data), NULL);
-
/* Update the values in the first (default) viewport - in case the user
has modified the statusbar or colour settings */
#if LCD_DEPTH > 1
@@ -563,7 +593,7 @@ static void gwps_enter_wps(void)
}
#ifdef HAVE_TOUCHSCREEN
gwps = skin_get_gwps(WPS, SCREEN_MAIN);
- skin_disarm_touchregions(gwps->data);
+ skin_disarm_touchregions(gwps);
if (gwps->data->touchregions < 0)
touchscreen_set_mode(TOUCHSCREEN_BUTTON);
#endif
@@ -573,16 +603,16 @@ static void gwps_enter_wps(void)
void wps_do_playpause(bool updatewps)
{
- struct wps_state *state = skin_get_global_state();
+ struct wps_state *state = get_wps_state();
if ( state->paused )
{
state->paused = false;
- unpause_action(true, updatewps);
+ unpause_action(updatewps);
}
else
{
state->paused = true;
- pause_action(true, updatewps);
+ pause_action(updatewps);
settings_save();
#if !defined(HAVE_SW_POWEROFF)
call_storage_idle_notifys(true); /* make sure resume info is saved */
@@ -590,6 +620,57 @@ void wps_do_playpause(bool updatewps)
}
}
+static long do_wps_exit(long action, bool bookmark)
+{
+ audio_pause();
+ update_non_static();
+ if (bookmark)
+ bookmark_autobookmark(true);
+ audio_stop();
+
+ ab_reset_markers();
+
+ gwps_leave_wps(true);
+#ifdef HAVE_RECORDING
+ if (action == ACTION_WPS_REC)
+ return GO_TO_RECSCREEN;
+#else
+ (void)action;
+#endif
+ if (global_settings.browse_current)
+ return GO_TO_PREVIOUS_BROWSER;
+ return GO_TO_PREVIOUS;
+}
+
+static long do_party_mode(long action)
+{
+ if (global_settings.party_mode)
+ {
+ switch (action)
+ {
+#ifdef ACTION_WPSAB_SINGLE
+ case ACTION_WPSAB_SINGLE:
+ if (!ab_repeat_mode_enabled())
+ break;
+ /* Note: currently all targets use ACTION_WPS_BROWSE
+ * if mapped to any of below actions this will cause problems */
+#endif
+ case ACTION_WPS_PLAY:
+ case ACTION_WPS_SEEKFWD:
+ case ACTION_WPS_SEEKBACK:
+ case ACTION_WPS_SKIPPREV:
+ case ACTION_WPS_SKIPNEXT:
+ case ACTION_WPS_ABSETB_NEXTDIR:
+ case ACTION_WPS_ABSETA_PREVDIR:
+ case ACTION_WPS_STOP:
+ return ACTION_NONE;
+ break;
+ default:
+ break;
+ }
+ }
+ return action;
+}
/* The WPS can be left in two ways:
* a) call a function, which draws over the wps. In this case, the wps
@@ -597,31 +678,28 @@ void wps_do_playpause(bool updatewps)
* b) return with a value evaluated by root_menu.c, in this case the wps
* is really left, and root_menu will handle the next screen
*
- * In either way, call gwps_leave_wps(), in order to restore the correct
+ * In either way, call gwps_leave_wps(true), in order to restore the correct
* "main screen" backdrops and statusbars
*/
long gui_wps_show(void)
{
long button = 0;
bool restore = true;
- long restoretimer = RESTORE_WPS_INSTANTLY; /* timer to delay screen redraw temporarily */
bool exit = false;
bool bookmark = false;
bool update = false;
- bool vol_changed = false;
+ bool theme_enabled = true;
long last_left = 0, last_right = 0;
- struct wps_state *state = skin_get_global_state();
+ struct wps_state *state = get_wps_state();
-#ifdef AB_REPEAT_ENABLE
ab_repeat_init();
ab_reset_markers();
-#endif
- wps_state_init();
+ wps_state_init();
while ( 1 )
{
+ bool hotkey = false;
bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false;
-
/* did someone else (i.e power thread) change audio pause mode? */
if (state->paused != audio_paused) {
state->paused = audio_paused;
@@ -635,8 +713,53 @@ long gui_wps_show(void)
#endif
}
}
- button = skin_wait_for_action(WPS, CONTEXT_WPS|ALLOW_SOFTLOCK,
- restore ? 1 : HZ/5);
+
+ if (restore)
+ {
+ restore = false;
+#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
+ add_event(LCD_EVENT_ACTIVATION, wps_lcd_activation_hook);
+#endif
+ /* we remove the update delay since it's not very usable in the wps,
+ * e.g. during volume changing or ffwd/rewind */
+ sb_skin_set_update_delay(0);
+ skin_request_full_update(WPS);
+ update = true;
+ gwps_enter_wps(theme_enabled);
+ theme_enabled = true;
+ }
+ else
+ {
+ gwps_caption_backlight(state);
+
+ FOR_NB_SCREENS(i)
+ {
+#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
+ /* currently, all remotes are readable without backlight
+ * so still update those */
+ if (lcd_active() || (i != SCREEN_MAIN))
+#endif
+ {
+ bool full_update = skin_do_full_update(WPS, i);
+ if (update || full_update)
+ {
+ skin_update(WPS, i, full_update ?
+ SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
+ }
+ }
+ }
+ update = false;
+ }
+
+ if (exit)
+ {
+ return do_wps_exit(button, bookmark);
+ }
+
+ if (button && !IS_SYSEVENT(button) )
+ storage_spin();
+
+ button = skin_wait_for_action(WPS, CONTEXT_WPS|ALLOW_SOFTLOCK, HZ/5);
/* Exit if audio has stopped playing. This happens e.g. at end of
playlist or if using the sleep timer. */
@@ -644,46 +767,64 @@ long gui_wps_show(void)
exit = true;
#ifdef HAVE_TOUCHSCREEN
if (button == ACTION_TOUCHSCREEN)
- button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
+ button = skintouch_to_wps();
#endif
+ button = do_party_mode(button); /* block select actions in party mode */
+
/* The iPods/X5/M5 use a single button for the A-B mode markers,
defined as ACTION_WPSAB_SINGLE in their config files. */
#ifdef ACTION_WPSAB_SINGLE
- if (!global_settings.party_mode && ab_repeat_mode_enabled())
+ static int wps_ab_state = 0;
+ if (button == ACTION_WPSAB_SINGLE && ab_repeat_mode_enabled())
{
- static int wps_ab_state = 0;
- if (button == ACTION_WPSAB_SINGLE)
+ switch (wps_ab_state)
{
- switch (wps_ab_state)
- {
- case 0: /* set the A spot */
- button = ACTION_WPS_ABSETA_PREVDIR;
- break;
- case 1: /* set the B spot */
- button = ACTION_WPS_ABSETB_NEXTDIR;
- break;
- case 2:
- button = ACTION_WPS_ABRESET;
- break;
- }
- wps_ab_state = (wps_ab_state+1) % 3;
+ case 0: /* set the A spot */
+ button = ACTION_WPS_ABSETA_PREVDIR;
+ break;
+ case 1: /* set the B spot */
+ button = ACTION_WPS_ABSETB_NEXTDIR;
+ break;
+ case 2:
+ button = ACTION_WPS_ABRESET;
+ break;
}
+ wps_ab_state = (wps_ab_state+1) % 3;
}
-#endif
+#endif /* def ACTION_WPSAB_SINGLE */
+
switch(button)
{
#ifdef HAVE_HOTKEY
case ACTION_WPS_HOTKEY:
+ {
+ hotkey = true;
if (!global_settings.hotkey_wps)
break;
- /* fall through */
-#endif
+ if (get_hotkey(global_settings.hotkey_wps)->flags & HOTKEY_FLAG_NOSBS)
+ {
+ /* leave WPS without re-enabling theme */
+ theme_enabled = false;
+ gwps_leave_wps(theme_enabled);
+ onplay(state->id3->path,
+ FILE_ATTR_AUDIO, CONTEXT_WPS, hotkey);
+ if (!audio_status())
+ {
+ /* re-enable theme since we're returning to SBS */
+ gwps_leave_wps(true);
+ return GO_TO_ROOT;
+ }
+ restore = true;
+ break;
+ }
+ }
+ /* fall through */
+#endif /* def HAVE_HOTKEY */
case ACTION_WPS_CONTEXT:
{
- bool hotkey = button == ACTION_WPS_HOTKEY;
- gwps_leave_wps();
+ gwps_leave_wps(true);
int retval = onplay(state->id3->path,
- FILE_ATTR_AUDIO, CONTEXT_WPS, hotkey);
+ FILE_ATTR_AUDIO, CONTEXT_WPS, hotkey);
/* if music is stopped in the context menu we want to exit the wps */
if (retval == ONPLAY_MAINMENU
|| !audio_status())
@@ -691,39 +832,46 @@ long gui_wps_show(void)
else if (retval == ONPLAY_PLAYLIST)
return GO_TO_PLAYLIST_VIEWER;
else if (retval == ONPLAY_PLUGIN)
- return GO_TO_PLUGIN;
+ {
+ restore_theme();
+ theme_enabled = false;
+ open_plugin_run(ID2P(LANG_OPEN_PLUGIN_SET_WPS_CONTEXT_PLUGIN));
+ }
+
restore = true;
}
break;
case ACTION_WPS_BROWSE:
- gwps_leave_wps();
+ gwps_leave_wps(true);
return GO_TO_PREVIOUS_BROWSER;
break;
/* play/pause */
case ACTION_WPS_PLAY:
- if (global_settings.party_mode)
- break;
wps_do_playpause(true);
break;
- case ACTION_WPS_VOLUP:
- global_settings.volume += sound_steps(SOUND_VOLUME);
- vol_changed = true;
- break;
+ case ACTION_WPS_VOLUP: /* fall through */
case ACTION_WPS_VOLDOWN:
- global_settings.volume -= sound_steps(SOUND_VOLUME);
- vol_changed = true;
+ if (button == ACTION_WPS_VOLUP)
+ adjust_volume(1);
+ else
+ adjust_volume(-1);
+
+ setvol();
+ FOR_NB_SCREENS(i)
+ {
+ skin_update(WPS, i, SKIN_REFRESH_NON_STATIC);
+ }
+ update = false;
break;
/* fast forward
OR next dir if this is straight after ACTION_WPS_SKIPNEXT */
case ACTION_WPS_SEEKFWD:
- if (global_settings.party_mode)
- break;
if (current_tick -last_right < HZ)
{
- if (state->id3->cuesheet)
+ if (state->id3->cuesheet && playlist_check(1))
{
audio_next();
}
@@ -733,37 +881,42 @@ long gui_wps_show(void)
}
}
else
- ffwd_rew(ACTION_WPS_SEEKFWD);
+ ffwd_rew(ACTION_WPS_SEEKFWD, false);
last_right = last_left = 0;
break;
/* fast rewind
OR prev dir if this is straight after ACTION_WPS_SKIPPREV,*/
case ACTION_WPS_SEEKBACK:
- if (global_settings.party_mode)
- break;
- if (current_tick -last_left < HZ)
+ if (current_tick - last_left < HZ)
{
- if (state->id3->cuesheet)
+ if (state->id3->cuesheet && playlist_check(-1))
{
- audio_pre_ff_rewind();
- audio_ff_rewind(0);
+ audio_prev();
}
else
{
change_dir(-1);
}
+ } else if (global_settings.rewind_across_tracks
+ && get_wps_state()->id3->elapsed < DEFAULT_SKIP_THRESH
+ && playlist_check(-1))
+ {
+ if (!audio_paused)
+ audio_pause();
+ audio_prev();
+ ffwd_rew(ACTION_WPS_SEEKBACK, true);
+ if (!audio_paused)
+ audio_resume();
}
else
- ffwd_rew(ACTION_WPS_SEEKBACK);
+ ffwd_rew(ACTION_WPS_SEEKBACK, false);
last_left = last_right = 0;
break;
/* prev / restart */
case ACTION_WPS_SKIPPREV:
- if (global_settings.party_mode)
- break;
last_left = current_tick;
-#ifdef AB_REPEAT_ENABLE
+
/* if we're in A/B repeat mode and the current position
is past the A marker, jump back to the A marker... */
if ( ab_repeat_mode_enabled() && ab_after_A_marker(state->id3->elapsed) )
@@ -771,19 +924,15 @@ long gui_wps_show(void)
ab_jump_to_A_marker();
break;
}
- else
- /* ...otherwise, do it normally */
-#endif
+ else /* ...otherwise, do it normally */
play_hop(-1);
break;
/* next
OR if skip length set, hop by predetermined amount. */
case ACTION_WPS_SKIPNEXT:
- if (global_settings.party_mode)
- break;
last_right = current_tick;
-#ifdef AB_REPEAT_ENABLE
+
/* if we're in A/B repeat mode and the current position is
before the A marker, jump to the A marker... */
if ( ab_repeat_mode_enabled() )
@@ -794,43 +943,33 @@ long gui_wps_show(void)
break;
}
}
- else
- /* ...otherwise, do it normally */
-#endif
+ else /* ...otherwise, do it normally */
play_hop(1);
break;
/* next / prev directories */
/* and set A-B markers if in a-b mode */
case ACTION_WPS_ABSETB_NEXTDIR:
- if (global_settings.party_mode)
- break;
-#if defined(AB_REPEAT_ENABLE)
if (ab_repeat_mode_enabled())
{
ab_set_B_marker(state->id3->elapsed);
ab_jump_to_A_marker();
}
else
-#endif
{
change_dir(1);
}
break;
case ACTION_WPS_ABSETA_PREVDIR:
- if (global_settings.party_mode)
- break;
-#if defined(AB_REPEAT_ENABLE)
if (ab_repeat_mode_enabled())
ab_set_A_marker(state->id3->elapsed);
else
-#endif
{
change_dir(-1);
}
break;
/* menu key functions */
case ACTION_WPS_MENU:
- gwps_leave_wps();
+ gwps_leave_wps(true);
return GO_TO_ROOT;
break;
@@ -838,16 +977,25 @@ long gui_wps_show(void)
#ifdef HAVE_QUICKSCREEN
case ACTION_WPS_QUICKSCREEN:
{
- gwps_leave_wps();
- if (global_settings.shortcuts_replaces_qs)
+ gwps_leave_wps(true);
+ bool enter_shortcuts_menu = global_settings.shortcuts_replaces_qs;
+ if (!enter_shortcuts_menu)
{
- global_status.last_screen = GO_TO_SHORTCUTMENU;
int ret = quick_screen_quick(button);
+ if (ret == QUICKSCREEN_IN_USB)
+ return GO_TO_ROOT;
+ else if (ret == QUICKSCREEN_GOTO_SHORTCUTS_MENU)
+ enter_shortcuts_menu = true;
+ else
+ restore = true;
+ }
+
+ if (enter_shortcuts_menu) /* enter_shortcuts_menu */
+ {
+ global_status.last_screen = GO_TO_SHORTCUTMENU;
+ int ret = do_shortcut_menu(NULL);
return (ret == GO_TO_PREVIOUS ? GO_TO_WPS : ret);
}
- else if (quick_screen_quick(button) > 0)
- return GO_TO_ROOT;
- restore = true;
}
break;
#endif /* HAVE_QUICKSCREEN */
@@ -858,7 +1006,7 @@ long gui_wps_show(void)
#ifdef HAVE_PITCHCONTROL
case ACTION_WPS_PITCHSCREEN:
{
- gwps_leave_wps();
+ gwps_leave_wps(true);
if (1 == gui_syncpitchscreen_run())
return GO_TO_ROOT;
restore = true;
@@ -866,7 +1014,6 @@ long gui_wps_show(void)
break;
#endif /* HAVE_PITCHCONTROL */
-#ifdef AB_REPEAT_ENABLE
/* reset A&B markers */
case ACTION_WPS_ABRESET:
if (ab_repeat_mode_enabled())
@@ -875,18 +1022,15 @@ long gui_wps_show(void)
update = true;
}
break;
-#endif /* AB_REPEAT_ENABLE */
/* stop and exit wps */
case ACTION_WPS_STOP:
- if (global_settings.party_mode)
- break;
bookmark = true;
exit = true;
break;
case ACTION_WPS_LIST_BOOKMARKS:
- gwps_leave_wps();
+ gwps_leave_wps(true);
if (bookmark_load_menu() == BOOKMARK_USB_CONNECTED)
{
return GO_TO_ROOT;
@@ -895,17 +1039,17 @@ long gui_wps_show(void)
break;
case ACTION_WPS_CREATE_BOOKMARK:
- gwps_leave_wps();
+ gwps_leave_wps(true);
bookmark_create_menu();
restore = true;
break;
case ACTION_WPS_ID3SCREEN:
{
- gwps_leave_wps();
+ gwps_leave_wps(true);
if (browse_id3(audio_current_track(),
playlist_get_display_index(),
- playlist_amount()))
+ playlist_amount(), NULL, 1))
return GO_TO_ROOT;
restore = true;
}
@@ -917,7 +1061,7 @@ long gui_wps_show(void)
break;
case ACTION_NONE: /* Timeout, do a partial update */
update = true;
- ffwd_rew(button); /* hopefully fix the ffw/rwd bug */
+ ffwd_rew(button, false); /* hopefully fix the ffw/rwd bug */
break;
#ifdef HAVE_RECORDING
case ACTION_WPS_REC:
@@ -925,7 +1069,7 @@ long gui_wps_show(void)
break;
#endif
case ACTION_WPS_VIEW_PLAYLIST:
- gwps_leave_wps();
+ gwps_leave_wps(true);
return GO_TO_PLAYLIST_VIEWER;
break;
default:
@@ -934,99 +1078,25 @@ long gui_wps_show(void)
case SYS_USB_CONNECTED:
case SYS_CALL_INCOMING:
case BUTTON_MULTIMEDIA_STOP:
- gwps_leave_wps();
+ gwps_leave_wps(true);
return GO_TO_ROOT;
}
update = true;
break;
}
-
- if (vol_changed)
- {
- bool res = false;
- vol_changed = false;
- setvol();
- FOR_NB_SCREENS(i)
- {
- if(update_onvol_change(i))
- res = true;
- }
- if (res) {
- restore = true;
- restoretimer = RESTORE_WPS_NEXT_SECOND;
- }
- }
-
-
- if (restore &&
- ((restoretimer == RESTORE_WPS_INSTANTLY) ||
- TIME_AFTER(current_tick, restoretimer)))
- {
- restore = false;
- restoretimer = RESTORE_WPS_INSTANTLY;
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
- add_event(LCD_EVENT_ACTIVATION, wps_lcd_activation_hook);
-#endif
- /* we remove the update delay since it's not very usable in the wps,
- * e.g. during volume changing or ffwd/rewind */
- sb_skin_set_update_delay(0);
- skin_request_full_update(WPS);
- update = true;
- gwps_enter_wps();
- }
- else
- {
-#if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD)
- gwps_caption_backlight(state);
-#endif
- FOR_NB_SCREENS(i)
- {
-#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
- /* currently, all remotes are readable without backlight
- * so still update those */
- if (lcd_active() || (i != SCREEN_MAIN))
-#endif
- {
- bool full_update = skin_do_full_update(WPS, i);
- if (update || full_update)
- {
- skin_update(WPS, i, full_update ?
- SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
- }
- }
- }
- update = false;
- }
-
- if (exit) {
- audio_pause();
- update_non_static();
- if (bookmark)
- bookmark_autobookmark(true);
- audio_stop();
-#ifdef AB_REPEAT_ENABLE
- ab_reset_markers();
-#endif
- gwps_leave_wps();
-#ifdef HAVE_RECORDING
- if (button == ACTION_WPS_REC)
- return GO_TO_RECSCREEN;
-#endif
- if (global_settings.browse_current)
- return GO_TO_PREVIOUS_BROWSER;
- return GO_TO_PREVIOUS;
- }
-
- if (button && !IS_SYSEVENT(button) )
- storage_spin();
}
return GO_TO_ROOT; /* unreachable - just to reduce compiler warnings */
}
+struct wps_state *get_wps_state(void)
+{
+ return &wps_state;
+}
+
/* this is called from the playback thread so NO DRAWING! */
static void track_info_callback(unsigned short id, void *param)
{
- struct wps_state *state = skin_get_global_state();
+ struct wps_state *state = get_wps_state();
if (id == PLAYBACK_EVENT_TRACK_CHANGE || id == PLAYBACK_EVENT_CUR_TRACK_READY)
{
@@ -1042,14 +1112,13 @@ static void track_info_callback(unsigned short id, void *param)
state->id3 = audio_current_track();
}
#endif
- skin_get_global_state()->nid3 = audio_next_track();
+ state->nid3 = audio_next_track();
skin_request_full_update(WPS);
}
static void wps_state_init(void)
{
- struct wps_state *state = skin_get_global_state();
- state->ff_rewind = false;
+ struct wps_state *state = get_wps_state();
state->paused = false;
if(audio_status() & AUDIO_STATUS_PLAY)
{
@@ -1073,16 +1142,3 @@ static void wps_state_init(void)
add_event(PLAYBACK_EVENT_TRACK_SKIP, track_info_callback);
#endif
}
-
-
-#ifdef IPOD_ACCESSORY_PROTOCOL
-bool is_wps_fading(void)
-{
- return skin_get_global_state()->is_fading;
-}
-
-int wps_get_ff_rewind_count(void)
-{
- return skin_get_global_state()->ff_rewind_count;
-}
-#endif
diff --git a/apps/gui/wps.h b/apps/gui/wps.h
index a463b0e9bb..001c112a4d 100644
--- a/apps/gui/wps.h
+++ b/apps/gui/wps.h
@@ -20,35 +20,30 @@
****************************************************************************/
#ifndef _WPS_H_
#define _WPS_H_
+
#include <stdbool.h>
-#include "config.h"
-#include "screen_access.h"
-
-long gui_wps_show(void);
-
-/* wrapper for the wps to load the skin (.wps/.rwps) files */
-void wps_data_load(enum screen_type, const char *, bool);
-void gui_sync_wps_init(void) INIT_ATTR;
+struct mp3entry;
-/* fade (if enabled) and pause the audio, optionally rewind a little */
-void pause_action(bool may_fade, bool updatewps);
-void unpause_action(bool may_fade, bool updatewps);
+/* Please don't add anything else to here... */
+struct wps_state
+{
+ struct mp3entry *id3;
+ struct mp3entry *nid3;
+ int ff_rewind_count;
+ bool paused;
+};
-/* fades the volume, e.g. on pause or stop */
-void fade(bool fade_in, bool updatewps);
+long gui_wps_show(void);
-bool ffwd_rew(int button);
+/* fade (if enabled) and pause the audio, optionally rewind a little */
+void pause_action(bool updatewps);
+void unpause_action(bool updatewps);
void wps_do_playpause(bool updatewps);
-#ifdef IPOD_ACCESSORY_PROTOCOL
-/* whether the wps is fading the volume due to pausing/stopping */
-bool is_wps_fading(void);
-/* return length of the current ff or rewin action, IAP needs this */
-int wps_get_ff_rewind_count(void);
-#endif /* IPOD_ACCESSORY_PROTOCOL */
+struct wps_state *get_wps_state(void);
/* in milliseconds */
-#define DEFAULT_SKIP_TRESH 3000l
+#define DEFAULT_SKIP_THRESH 3000l
#endif /* _WPS_H_ */
diff --git a/apps/gui/yesno.c b/apps/gui/yesno.c
index a79b8ae644..a0fd908727 100644
--- a/apps/gui/yesno.c
+++ b/apps/gui/yesno.c
@@ -30,6 +30,8 @@
#include "viewport.h"
#include "appevents.h"
+#include <stdio.h>
+#include "splash.h"
struct gui_yesno
{
@@ -38,6 +40,9 @@ struct gui_yesno
struct viewport *vp;
struct screen * display;
+ /* timeout data */
+ long end_tick;
+ enum yesno_res tmo_default_res;
};
static void talk_text_message(const struct text_message * message, bool enqueue)
@@ -80,8 +85,10 @@ static void gui_yesno_draw(struct gui_yesno * yn)
struct viewport *vp = yn->vp;
int nb_lines, vp_lines, line_shift=0;
struct viewport *last_vp;
+ enum yesno_res def_res = yn->tmo_default_res;
+ long end_tick = yn->end_tick;
- last_vp = display->set_viewport(vp);
+ last_vp = display->set_viewport_ex(vp, VP_FLAG_VP_SET_CLEAN);
display->clear_viewport();
nb_lines = yn->main_message->nb_lines;
vp_lines = viewport_get_nb_lines(vp);
@@ -91,20 +98,53 @@ static void gui_yesno_draw(struct gui_yesno * yn)
line_shift += put_message(display, yn->main_message,
line_shift, vp_lines);
+
#ifdef HAVE_TOUCHSCREEN
if (display->screen_type == SCREEN_MAIN)
{
- int w,h;
+ int w,h,tmo_w;
+ int tm_rem = 0;
+ const char *btn_fmt;
int rect_w = vp->width/2, rect_h = vp->height/2;
int old_pattern = vp->fg_pattern;
vp->fg_pattern = LCD_RGBPACK(0,255,0);
display->drawrect(0, rect_h, rect_w, rect_h);
display->getstringsize(str(LANG_SET_BOOL_YES), &w, &h);
- display->putsxy((rect_w-w)/2, rect_h+(rect_h-h)/2, str(LANG_SET_BOOL_YES));
+
+ if (def_res == YESNO_YES)
+ {
+ display->getstringsize(" (0)", &tmo_w, NULL);
+ tm_rem = ((end_tick - current_tick) / 100);
+ btn_fmt = "%s (%d)";
+ }
+ else
+ {
+ btn_fmt = "%s\0%d";
+ tmo_w = 0;
+ }
+
+ display->putsxyf((rect_w-(w+tmo_w))/2, rect_h+(rect_h-h)/2,
+ btn_fmt, str(LANG_SET_BOOL_YES), tm_rem);
+
vp->fg_pattern = LCD_RGBPACK(255,0,0);
display->drawrect(rect_w, rect_h, rect_w, rect_h);
display->getstringsize(str(LANG_SET_BOOL_NO), &w, &h);
- display->putsxy(rect_w + (rect_w-w)/2, rect_h+(rect_h-h)/2, str(LANG_SET_BOOL_NO));
+
+ if (def_res == YESNO_NO)
+ {
+ display->getstringsize(" (0)", &tmo_w, NULL);
+ tm_rem = ((end_tick - current_tick) / 100);
+ btn_fmt = "%s (%d)";
+ }
+ else
+ {
+ btn_fmt = "%s\0%d";
+ tmo_w = 0;
+ }
+
+ display->putsxyf(rect_w + (rect_w-(w+tmo_w))/2, rect_h+(rect_h-h)/2,
+ btn_fmt, str(LANG_SET_BOOL_NO), tm_rem);
+
vp->fg_pattern = old_pattern;
}
#else
@@ -115,6 +155,15 @@ static void gui_yesno_draw(struct gui_yesno * yn)
line_shift++;
display->puts(0, line_shift, str(LANG_CONFIRM_WITH_BUTTON));
display->puts(0, line_shift+1, str(LANG_CANCEL_WITH_ANY));
+
+ if (def_res == YESNO_YES || def_res == YESNO_NO)
+ {
+ int tm_rem = ((end_tick - current_tick) / 100);
+ if (def_res == YESNO_YES)
+ display->putsf(0, line_shift, "%s (%d)", str(LANG_CONFIRM_WITH_BUTTON), tm_rem);
+ else
+ display->putsf(0, line_shift+1, "%s (%d)", str(LANG_CANCEL_WITH_ANY), tm_rem);
+ }
}
#endif
display->update_viewport();
@@ -124,7 +173,7 @@ static void gui_yesno_draw(struct gui_yesno * yn)
/*
* Draws the yesno result
* - yn : the yesno structure
- * - result : the result tha must be displayed :
+ * - result : the result to be displayed :
* YESNO_NO if no
* YESNO_YES if yes
*/
@@ -133,9 +182,10 @@ static bool gui_yesno_draw_result(struct gui_yesno * yn, enum yesno_res result)
const struct text_message * message=yn->result_message[result];
struct viewport *vp = yn->vp;
struct screen * display=yn->display;
+ struct viewport *last_vp = display->set_viewport_ex(vp, VP_FLAG_VP_SET_CLEAN);
+
if(message==NULL)
return false;
- struct viewport *last_vp = display->set_viewport(vp);
display->clear_viewport();
put_message(yn->display, message, 0, viewport_get_nb_lines(vp));
display->update_viewport();
@@ -153,18 +203,44 @@ static void gui_yesno_ui_update(unsigned short id, void *event_data, void *user_
gui_yesno_draw(&yn[i]);
}
-enum yesno_res gui_syncyesno_run(const struct text_message * main_message,
- const struct text_message * yes_message,
- const struct text_message * no_message)
+/* Display a YES_NO prompt to the user
+ *
+ * ticks < HZ will be ignored and the prompt will be blocking
+ * tmo_default_res is the answer that is returned when the timeout expires
+ * a default result of YESNO_TMO will also make the prompt blocking
+ * if tmo_default_res is YESNO_YES or YESNO_NO a seconds countdown will
+ * be present next to the default option
+ *
+ * ticks - timeout if (>=HZ) otherwise ignored
+ * default_res - result returned on timeout YESNO_TMO creates a blocking prompt
+ * main_message - prompt to the user
+ * yes_message - displayed when YESNO_YES is choosen
+ * no_message - displayed when YESNO_NO is choosen
+*/
+enum yesno_res gui_syncyesno_run_w_tmo(int ticks, enum yesno_res tmo_default_res,
+ const struct text_message * main_message,
+ const struct text_message * yes_message,
+ const struct text_message * no_message)
{
int button;
int result=-1;
- bool result_displayed;
+ bool result_displayed = false;
struct gui_yesno yn[NB_SCREENS];
struct viewport vp[NB_SCREENS];
long talked_tick = 0;
+ long end_tick = current_tick + ticks;
+ long button_scan_tmo = HZ/2;
+
+ if (ticks < HZ) /* Display a prompt with NO timeout to the user */
+ {
+ tmo_default_res = YESNO_TMO;
+ }
+
FOR_NB_SCREENS(i)
{
+ yn[i].end_tick = end_tick;
+ yn[i].tmo_default_res = tmo_default_res;
+
yn[i].main_message=main_message;
yn[i].result_message[YESNO_YES]=yes_message;
yn[i].result_message[YESNO_NO]=no_message;
@@ -198,7 +274,11 @@ enum yesno_res gui_syncyesno_run(const struct text_message * main_message,
talked_tick = current_tick;
talk_text_message(main_message, false);
}
- button = get_action(CONTEXT_YESNOSCREEN, HZ*5);
+ FOR_NB_SCREENS(i)
+ gui_yesno_draw(&yn[i]);
+
+ button = get_action(CONTEXT_YESNOSCREEN, button_scan_tmo);
+
switch (button)
{
#ifdef HAVE_TOUCHSCREEN
@@ -222,6 +302,13 @@ enum yesno_res gui_syncyesno_run(const struct text_message * main_message,
result=YESNO_YES;
break;
case ACTION_NONE:
+ if(tmo_default_res != YESNO_TMO && TIME_AFTER(current_tick, end_tick))
+ {
+ splash(HZ/2, ID2P(LANG_TIMEOUT));
+ result = tmo_default_res;
+ break;
+ }
+ /*fall-through*/
case ACTION_UNKNOWN:
case SYS_CHARGER_DISCONNECTED:
case SYS_BATTERY_UPDATE:
@@ -250,6 +337,11 @@ enum yesno_res gui_syncyesno_run(const struct text_message * main_message,
: no_message, false);
talk_force_enqueue_next();
}
+
+
+ exit:
+ remove_event_ex(GUI_EVENT_NEED_UI_UPDATE, gui_yesno_ui_update, &yn[0]);
+
if(result_displayed)
sleep(HZ);
@@ -259,14 +351,19 @@ enum yesno_res gui_syncyesno_run(const struct text_message * main_message,
viewportmanager_theme_undo(i, true);
}
- exit:
- remove_event_ex(GUI_EVENT_NEED_UI_UPDATE, gui_yesno_ui_update, &yn[0]);
#ifdef HAVE_TOUCHSCREEN
touchscreen_set_mode(old_mode);
#endif
return result;
}
+enum yesno_res gui_syncyesno_run(const struct text_message * main_message,
+ const struct text_message * yes_message,
+ const struct text_message * no_message)
+{
+ return gui_syncyesno_run_w_tmo(TIMEOUT_BLOCK, YESNO_TMO,
+ main_message, yes_message, no_message);
+}
/* Function to manipulate all yesno dialogues.
This function needs the output text as an argument. */
diff --git a/apps/gui/yesno.h b/apps/gui/yesno.h
index 61bcf8d3c0..5f67733d79 100644
--- a/apps/gui/yesno.h
+++ b/apps/gui/yesno.h
@@ -27,7 +27,8 @@ enum yesno_res
{
YESNO_YES,
YESNO_NO,
- YESNO_USB
+ YESNO_USB,
+ YESNO_TMO
};
struct text_message
@@ -48,7 +49,13 @@ extern enum yesno_res gui_syncyesno_run(
const struct text_message * main_message,
const struct text_message * yes_message,
const struct text_message * no_message);
-
+
+extern enum yesno_res gui_syncyesno_run_w_tmo(
+ int ticks, enum yesno_res tmo_default_res,
+ const struct text_message * main_message,
+ const struct text_message * yes_message,
+ const struct text_message * no_message);
+
bool yesno_pop(const char* text);
#endif /* _GUI_YESNO_H_ */
diff --git a/apps/hosted/android/keyboard.c b/apps/hosted/android/keyboard.c
index eda951a7c9..b74f67e782 100644
--- a/apps/hosted/android/keyboard.c
+++ b/apps/hosted/android/keyboard.c
@@ -100,7 +100,7 @@ int kbd_input(char* text, int buflen, unsigned short *kbd)
if (accepted)
{
utf8_string = e->GetStringUTFChars(env_ptr, new_string, 0);
- strlcpy(text, utf8_string, buflen);
+ strmemccpy(text, utf8_string, buflen);
e->ReleaseStringUTFChars(env_ptr, new_string, utf8_string);
e->DeleteGlobalRef(env_ptr, new_string);
}
diff --git a/apps/hosted/android/notification.c b/apps/hosted/android/notification.c
index 39c8b07737..a5b60c1013 100644
--- a/apps/hosted/android/notification.c
+++ b/apps/hosted/android/notification.c
@@ -29,6 +29,7 @@
#include "misc.h"
#include "thread.h"
#include "debug.h"
+#include "audio.h"
extern JNIEnv *env_ptr;
extern jclass RockboxService_class;
diff --git a/apps/hosted/android/yesno.c b/apps/hosted/android/yesno.c
index bc8672ad76..af7f5a5c7b 100644
--- a/apps/hosted/android/yesno.c
+++ b/apps/hosted/android/yesno.c
@@ -117,6 +117,17 @@ enum yesno_res gui_syncyesno_run(const struct text_message * main_message,
return ret ? YESNO_YES : YESNO_NO;
}
+enum yesno_res gui_syncyesno_run_w_tmo(int ticks, enum yesno_res tmo_default_res,
+ const struct text_message * main_message,
+ const struct text_message * yes_message,
+ const struct text_message * no_message)
+{
+ /* FIXME: create a prompt with timeout for android */
+ (void)ticks;
+ (void)tmo_default_res;
+ return gui_syncyesno_run(main_message, yes_message, no_message);
+}
+
#endif
/* Function to manipulate all yesno dialogues.
diff --git a/apps/iap/iap-core.c b/apps/iap/iap-core.c
index ae05806ae9..da04a67311 100644
--- a/apps/iap/iap-core.c
+++ b/apps/iap/iap-core.c
@@ -19,8 +19,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-#include <string.h>
+#include "string-extra.h"
#include "panic.h"
#include "iap-core.h"
#include "iap-lingo.h"
@@ -453,7 +453,7 @@ static void iap_malloc(void)
return;
#ifdef IAP_MALLOC_DYNAMIC
- iap_buffer_handle = core_alloc_ex("iap", IAP_MALLOC_SIZE, &iap_buflib_callbacks);
+ iap_buffer_handle = core_alloc_ex(IAP_MALLOC_SIZE, &iap_buflib_callbacks);
if (iap_buffer_handle < 0)
panicf("Could not allocate buffer memory");
iap_buffers = core_get_data(iap_buffer_handle);
diff --git a/apps/iap/iap-lingo2.c b/apps/iap/iap-lingo2.c
index 946e51222d..51f951c6d9 100644
--- a/apps/iap/iap-lingo2.c
+++ b/apps/iap/iap-lingo2.c
@@ -187,6 +187,17 @@ void iap_handlepkt_mode2(const unsigned int len, const unsigned char *buf)
REMOTE_BUTTON(BUTTON_RC_RIGHT);
if(buf[4] & 32) /* frwd */
REMOTE_BUTTON(BUTTON_RC_LEFT);
+ if(buf[4] & 64) /* menu */
+ REMOTE_BUTTON(BUTTON_RC_MENU);
+ if(buf[4] & 128) /* select */
+ REMOTE_BUTTON(BUTTON_RC_SELECT);
+ }
+ else if(len >= 6 && buf[5] != 0)
+ {
+ if(buf[5] & 1) /* up */
+ REMOTE_BUTTON(BUTTON_RC_UP);
+ if (buf[5] & 2) /* down */
+ REMOTE_BUTTON(BUTTON_RC_DOWN);
}
/* power on released */
diff --git a/apps/iap/iap-lingo4.c b/apps/iap/iap-lingo4.c
index 4ec5c462a1..eb629407f2 100644
--- a/apps/iap/iap-lingo4.c
+++ b/apps/iap/iap-lingo4.c
@@ -24,6 +24,7 @@
#include "filetree.h"
#include "wps.h"
#include "playback.h"
+#include "string-extra.h"
/*
* This macro is meant to be used inside an IAP mode message handler.
@@ -87,7 +88,7 @@ static void get_playlist_name(unsigned char *dest,
}
}
if (playlist_file != NULL) {
- strlcpy(dest, playlist_file->d_name, max_length);
+ strmemccpy(dest, playlist_file->d_name, max_length);
}
closedir(dp);
}
@@ -1218,7 +1219,7 @@ void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf)
{
memcpy(cur_dbrecord, buf + 3, 5);
- int paused = (is_wps_fading() || (audio_status() & AUDIO_STATUS_PAUSE));
+ int paused = !!(audio_status() & AUDIO_STATUS_PAUSE);
uint32_t index;
uint32_t trackcount;
index = get_u32(&cur_dbrecord[1]);
@@ -1430,7 +1431,6 @@ void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf)
unsigned int number_of_playlists = nbr_total_playlists();
uint32_t trackcount;
trackcount = playlist_amount();
- size_t len;
if ((buf[3] == 0x05) && ((start_index + read_count ) > trackcount))
{
@@ -1465,22 +1465,21 @@ void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf)
switch(buf[3])
{
case 0x05:
- len = strlcpy((char *)&data[7], id3.title,64);
+ strmemccpy((char *)&data[7], id3.title,64);
break;
case 0x02:
- len = strlcpy((char *)&data[7], id3.artist,64);
+ strmemccpy((char *)&data[7], id3.artist,64);
break;
case 0x03:
- len = strlcpy((char *)&data[7], id3.album,64);
+ strmemccpy((char *)&data[7], id3.album,64);
break;
case 0x04:
case 0x06:
- len = strlcpy((char *)&data[7], "Not Supported",14);
+ strmemccpy((char *)&data[7], "Not Supported",14);
break;
}
break;
}
- (void)len; /* Shut up, compiler */
put_u32(&data[3], start_index+counter);
iap_send_pkt(data, 7 + strlen(data+7) + 1);
yield();
@@ -2003,7 +2002,7 @@ void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf)
*
*/
{
- int paused = (is_wps_fading() || (audio_status() & AUDIO_STATUS_PAUSE));
+ int paused = !!(audio_status() & AUDIO_STATUS_PAUSE);
uint32_t index;
uint32_t trackcount;
index = get_u32(&buf[3]);
@@ -2821,7 +2820,7 @@ void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf)
*
*/
{
- int paused = (is_wps_fading() || (audio_status() & AUDIO_STATUS_PAUSE));
+ int paused = !!(audio_status() & AUDIO_STATUS_PAUSE);
long tracknum = get_u32(&buf[3]);
audio_pause();
@@ -2977,7 +2976,7 @@ void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf)
{
memcpy(cur_dbrecord, buf + 3, 5);
- int paused = (is_wps_fading() || (audio_status() & AUDIO_STATUS_PAUSE));
+ int paused = !!(audio_status() & AUDIO_STATUS_PAUSE);
unsigned int number_of_playlists = nbr_total_playlists();
uint32_t index;
uint32_t trackcount;
diff --git a/apps/keymaps/keymap-agptekrocker.c b/apps/keymaps/keymap-agptekrocker.c
index 1fb8465b0a..5ca834ab51 100644
--- a/apps/keymaps/keymap-agptekrocker.c
+++ b/apps/keymaps/keymap-agptekrocker.c
@@ -139,15 +139,16 @@ static const struct button_mapping button_context_yesno[] = {
}; /* button_context_settings_yesno */
static const struct button_mapping button_context_quickscreen[] = {
- { ACTION_QS_TOP, BUTTON_UP|BUTTON_REL, BUTTON_NONE },
- { ACTION_QS_TOP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
- { ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REL, BUTTON_NONE },
- { ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
- { ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE },
- { ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
- { ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE },
- { ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
- { ACTION_STD_CANCEL, BUTTON_SELECT, BUTTON_NONE },
+ { ACTION_QS_TOP, BUTTON_UP|BUTTON_REL, BUTTON_NONE },
+ { ACTION_QS_TOP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REL, BUTTON_NONE },
+ { ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE },
+ { ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE },
+ { ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
+ { ACTION_STD_CANCEL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
LAST_ITEM_IN_LIST
}; /* button_context_quickscreen */
@@ -220,7 +221,7 @@ static const struct button_mapping button_context_bmark[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-clip.c b/apps/keymaps/keymap-clip.c
index 3c92f03a07..59ee080364 100644
--- a/apps/keymaps/keymap-clip.c
+++ b/apps/keymaps/keymap-clip.c
@@ -84,9 +84,9 @@ static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_ID3SCREEN, BUTTON_SELECT|BUTTON_DOWN, BUTTON_SELECT },
#ifdef HAVE_HOTKEY /* down|repeat doesn't work in the file browser */
- { ACTION_WPS_HOTKEY, BUTTON_DOWN, BUTTON_NONE },
+ { ACTION_WPS_HOTKEY, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_DOWN },
#endif
- { ACTION_WPS_VIEW_PLAYLIST, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_WPS_VIEW_PLAYLIST, BUTTON_DOWN|BUTTON_REL, BUTTON_DOWN },
#ifndef HAS_BUTTON_HOLD /* Clip+ */
{ ACTION_STD_KEYLOCK, BUTTON_HOME|BUTTON_SELECT, BUTTON_NONE },
@@ -179,7 +179,7 @@ static const struct button_mapping button_context_quickscreen[] = {
{ ACTION_NONE, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_POWER|BUTTON_REL, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_HOME, BUTTON_NONE },
- { ACTION_STD_CANCEL, BUTTON_SELECT, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
{ ACTION_QS_TOP, BUTTON_UP|BUTTON_REL, BUTTON_NONE },
{ ACTION_QS_TOP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REL, BUTTON_NONE },
@@ -212,9 +212,11 @@ static const struct button_mapping button_context_pitchscreen[] = {
{ ACTION_PS_NUDGE_LEFTOFF, BUTTON_LEFT|BUTTON_REL, BUTTON_NONE },
{ ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE },
- { ACTION_PS_TOGGLE_MODE, BUTTON_HOME|BUTTON_REL, BUTTON_HOME },
- { ACTION_PS_RESET, BUTTON_SELECT, BUTTON_NONE },
+ { ACTION_PS_TOGGLE_MODE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
+ { ACTION_PS_RESET, BUTTON_HOME|BUTTON_REPEAT, BUTTON_HOME },
+ { ACTION_PS_RESET, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
{ ACTION_PS_EXIT, BUTTON_POWER, BUTTON_NONE },
+ { ACTION_PS_EXIT, BUTTON_HOME|BUTTON_REL, BUTTON_HOME },
{ ACTION_PS_SLOWER, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_PS_FASTER, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
@@ -397,7 +399,7 @@ static const struct button_mapping button_context_usb_hid_mode_mouse[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-erosq.c b/apps/keymaps/keymap-erosq.c
index d486423a53..054da96201 100644
--- a/apps/keymaps/keymap-erosq.c
+++ b/apps/keymaps/keymap-erosq.c
@@ -130,6 +130,7 @@ static const struct button_mapping button_context_quickscreen[] = {
{ ACTION_QS_DOWN, BUTTON_NEXT|BUTTON_REL, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE },
+ { ACTION_STD_CONTEXT,BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU },
LAST_ITEM_IN_LIST
}; /* button_context_quickscreen */
@@ -193,7 +194,7 @@ static const struct button_mapping button_context_bmark[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-fiiom3k.c b/apps/keymaps/keymap-fiiom3k.c
index d0fbbb2e98..1ccf7e956f 100644
--- a/apps/keymaps/keymap-fiiom3k.c
+++ b/apps/keymaps/keymap-fiiom3k.c
@@ -175,7 +175,8 @@ static const struct button_mapping button_context_quickscreen[] = {
{ACTION_QS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE},
{ACTION_QS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE},
{ACTION_QS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE},
- {ACTION_STD_CANCEL, BUTTON_SELECT, BUTTON_NONE},
+ {ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT},
+ {ACTION_STD_CANCEL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT},
{ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE},
{ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE},
{ACTION_STD_CANCEL, BUTTON_MENU, BUTTON_NONE},
@@ -214,10 +215,8 @@ static const struct button_mapping button_context_yesnoscreen[] = {
}; /* button_context_yesnoscreen */
static const struct button_mapping button_context_recscreen[] = {
- {ACTION_REC_PAUSE, BUTTON_SELECT, BUTTON_NONE},
{ACTION_REC_PAUSE, BUTTON_PLAY, BUTTON_NONE},
- {ACTION_REC_NEWFILE, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT},
- {ACTION_REC_NEWFILE, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY},
+ {ACTION_REC_NEWFILE, BUTTON_SELECT, BUTTON_NONE},
{ACTION_STD_MENU, BUTTON_MENU, BUTTON_NONE},
{ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE},
{ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE},
@@ -323,21 +322,14 @@ static const struct button_mapping button_context_usb_hid_mode_browser[] = {
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
- {
- case CONTEXT_WPS|CONTEXT_LOCKED:
- return button_context_wps_locked;
- default:
- context &= ~CONTEXT_LOCKED;
- break;
- }
-
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
default:
case CONTEXT_STD:
return button_context_standard;
case CONTEXT_WPS:
+ if (context & CONTEXT_LOCKED)
+ return button_context_wps_locked;
return button_context_wps;
case CONTEXT_TREE:
case CONTEXT_MAINMENU:
diff --git a/apps/keymaps/keymap-fiiom3klinux.c b/apps/keymaps/keymap-fiiom3klinux.c
index e404d8bfb0..79a7687501 100644
--- a/apps/keymaps/keymap-fiiom3klinux.c
+++ b/apps/keymaps/keymap-fiiom3klinux.c
@@ -192,7 +192,7 @@ static const struct button_mapping button_context_yesnoscreen[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_LIST:
return button_context_list;
diff --git a/apps/keymaps/keymap-fuzeplus.c b/apps/keymaps/keymap-fuzeplus.c
index 6601316469..052f11085e 100644
--- a/apps/keymaps/keymap-fuzeplus.c
+++ b/apps/keymaps/keymap-fuzeplus.c
@@ -128,7 +128,8 @@ static const struct button_mapping button_context_keyboard[] = {
}; /* button_context_keyboard */
static const struct button_mapping button_context_quickscreen[] = {
- { ACTION_STD_CANCEL, BUTTON_SELECT, BUTTON_NONE },
+ { ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
+ { ACTION_STD_CANCEL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
{ ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_PLAYPAUSE, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_BOTTOMRIGHT, BUTTON_NONE },
@@ -406,7 +407,7 @@ static const struct button_mapping button_context_usb_hid_mode_mouse[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-ipod.c b/apps/keymaps/keymap-ipod.c
index e3a17fffba..aea0c444a2 100644
--- a/apps/keymaps/keymap-ipod.c
+++ b/apps/keymaps/keymap-ipod.c
@@ -132,7 +132,7 @@ static const struct button_mapping button_context_quickscreen[] = {
{ ACTION_QS_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_QS_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
- { ACTION_STD_CANCEL, BUTTON_SELECT, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
{ ACTION_QS_VOLDOWN, BUTTON_SCROLL_BACK, BUTTON_NONE },
{ ACTION_QS_VOLDOWN, BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_VOLUP, BUTTON_SCROLL_FWD, BUTTON_NONE },
@@ -161,7 +161,7 @@ static const struct button_mapping button_context_pitchscreen[] = {
static const struct button_mapping button_context_keyboard[] = {
{ ACTION_KBD_LEFT, BUTTON_LEFT, BUTTON_NONE },
- { ACTION_KBD_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_KBD_LEFT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_SELECT, BUTTON_SELECT, BUTTON_NONE },
@@ -204,7 +204,7 @@ const struct button_mapping button_context_recscreen[] = {
{ ACTION_FM_STOP, BUTTON_PLAY | BUTTON_REPEAT, BUTTON_PLAY },
{ ACTION_FM_MODE, BUTTON_SELECT, BUTTON_NONE },
{ ACTION_FM_EXIT, BUTTON_MENU | BUTTON_REL, BUTTON_MENU },
- { ACTION_FM_PLAY, BUTTON_PLAY | BUTTON_REL, BUTTON_PLAY },
+ { ACTION_FM_PLAY, BUTTON_PLAY | BUTTON_REL, BUTTON_PLAY },
{ ACTION_SETTINGS_INC, BUTTON_SCROLL_FWD, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT,BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_SCROLL_BACK, BUTTON_NONE },
@@ -309,11 +309,20 @@ static const struct button_mapping button_context_usb_hid_mode_mouse[] = {
*****************************************************************************/
static const struct button_mapping remote_button_context_standard[] = {
+ { ACTION_STD_PREV, BUTTON_RC_UP, BUTTON_NONE },
+ { ACTION_STD_PREVREPEAT, BUTTON_RC_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_NEXT, BUTTON_RC_DOWN, BUTTON_NONE },
+ { ACTION_STD_NEXTREPEAT, BUTTON_RC_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+
{ ACTION_STD_PREV, BUTTON_RC_LEFT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_RC_RIGHT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_RC_STOP, BUTTON_NONE },
{ ACTION_STD_OK, BUTTON_RC_PLAY, BUTTON_NONE },
+ { ACTION_STD_MENU, BUTTON_RC_MENU|BUTTON_REL, BUTTON_RC_MENU },
+ { ACTION_STD_QUICKSCREEN, BUTTON_RC_MENU|BUTTON_REPEAT, BUTTON_RC_MENU },
+ { ACTION_STD_CONTEXT, BUTTON_RC_SELECT|BUTTON_REPEAT, BUTTON_RC_SELECT },
+
LAST_ITEM_IN_LIST
}; /* remote_button_context_standard */
@@ -322,7 +331,7 @@ static const struct button_mapping remote_button_context_wps[] = {
{ ACTION_WPS_VOLDOWN, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_RC_VOL_UP, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
-
+ // RC_UP and RC_DOWN?
{ ACTION_WPS_PLAY, BUTTON_RC_PLAY|BUTTON_REL, BUTTON_RC_PLAY },
{ ACTION_WPS_STOP, BUTTON_RC_PLAY|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_SKIPNEXT, BUTTON_RC_RIGHT|BUTTON_REL, BUTTON_RC_RIGHT },
@@ -331,6 +340,12 @@ static const struct button_mapping remote_button_context_wps[] = {
{ ACTION_WPS_SKIPPREV, BUTTON_RC_LEFT|BUTTON_REL, BUTTON_RC_LEFT },
{ ACTION_WPS_SEEKBACK, BUTTON_RC_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_RC_LEFT|BUTTON_REL, BUTTON_RC_LEFT|BUTTON_REPEAT },
+ { ACTION_WPS_BROWSE, BUTTON_RC_SELECT|BUTTON_REL, BUTTON_RC_SELECT },
+ { ACTION_WPS_CONTEXT, BUTTON_RC_SELECT|BUTTON_REPEAT, BUTTON_RC_SELECT },
+ { ACTION_WPS_HOTKEY, BUTTON_RC_SELECT|BUTTON_PLAY, BUTTON_NONE },
+ { ACTION_WPS_MENU, BUTTON_RC_MENU|BUTTON_REL, BUTTON_RC_MENU },
+ { ACTION_WPS_QUICKSCREEN, BUTTON_RC_MENU|BUTTON_REPEAT, BUTTON_RC_MENU },
+
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* remote_button_context_wps */
@@ -338,23 +353,57 @@ static const struct button_mapping remote_button_context_wps[] = {
static const struct button_mapping remote_button_context_tree[] = {
{ ACTION_TREE_WPS, BUTTON_RC_PLAY|BUTTON_REL, BUTTON_RC_PLAY },
{ ACTION_TREE_STOP, BUTTON_RC_PLAY|BUTTON_REPEAT, BUTTON_RC_PLAY },
-
+ { ACTION_TREE_HOTKEY, BUTTON_RC_SELECT|BUTTON_PLAY, BUTTON_NONE },
+
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* remote_button_context_tree */
+static const struct button_mapping remote_button_context_quickscreen[] = {
+ { ACTION_QS_TOP, BUTTON_RC_MENU, BUTTON_NONE },
+ { ACTION_QS_TOP, BUTTON_RC_MENU|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_DOWN, BUTTON_RC_PLAY, BUTTON_NONE },
+ { ACTION_QS_DOWN, BUTTON_RC_PLAY|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_LEFT, BUTTON_RC_LEFT, BUTTON_NONE },
+ { ACTION_QS_LEFT, BUTTON_RC_LEFT|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_RIGHT, BUTTON_RC_RIGHT, BUTTON_NONE },
+ { ACTION_QS_RIGHT, BUTTON_RC_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_RC_SELECT|BUTTON_REL, BUTTON_RC_SELECT },
+ { ACTION_QS_VOLDOWN, BUTTON_RC_VOL_DOWN, BUTTON_NONE },
+ { ACTION_QS_VOLDOWN, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_QS_VOLUP, BUTTON_RC_VOL_UP, BUTTON_NONE },
+ { ACTION_QS_VOLUP, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
+
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_quickscreen */
+
#if CONFIG_TUNER
static const struct button_mapping remote_button_context_radio[] = {
+ { ACTION_FM_MENU, BUTTON_RC_SELECT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_FM_STOP, BUTTON_RC_PLAY | BUTTON_REPEAT, BUTTON_NONE },
- { ACTION_FM_PLAY, BUTTON_RC_PLAY | BUTTON_REL, BUTTON_RC_PLAY },
+ { ACTION_FM_MODE, BUTTON_RC_SELECT, BUTTON_NONE },
+ { ACTION_FM_EXIT, BUTTON_RC_MENU | BUTTON_REL, BUTTON_RC_MENU },
+
+ { ACTION_FM_PLAY, BUTTON_RC_PLAY | BUTTON_REL, BUTTON_RC_PLAY },
+ { ACTION_SETTINGS_INC, BUTTON_RC_UP, BUTTON_NONE },
+ { ACTION_SETTINGS_INCREPEAT,BUTTON_RC_UP|BUTTON_REPEAT, BUTTON_NONE },
+ { ACTION_SETTINGS_DEC, BUTTON_RC_DOWN, BUTTON_NONE },
+ { ACTION_SETTINGS_DECREPEAT,BUTTON_RC_DOWN|BUTTON_REPEAT,BUTTON_NONE },
+
{ ACTION_STD_NEXT, BUTTON_RC_RIGHT|BUTTON_REL, BUTTON_RC_RIGHT },
{ ACTION_STD_NEXTREPEAT, BUTTON_RC_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_PREV, BUTTON_RC_LEFT|BUTTON_REL, BUTTON_RC_LEFT },
{ ACTION_STD_PREVREPEAT, BUTTON_RC_LEFT|BUTTON_REPEAT, BUTTON_NONE },
-
+
LAST_ITEM_IN_LIST
}; /* remote_button_context_radio */
#endif
+static const struct button_mapping remote_button_context_yesno[] = {
+ { ACTION_YESNO_ACCEPT, BUTTON_RC_SELECT, BUTTON_NONE },
+ { ACTION_STD_CANCEL, BUTTON_RC_PLAY, BUTTON_NONE },
+ LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
+}; /* button_context_yesno */
+
static const struct button_mapping* get_context_mapping_remote( int context )
{
context ^= CONTEXT_REMOTE;
@@ -364,13 +413,18 @@ static const struct button_mapping* get_context_mapping_remote( int context )
case CONTEXT_WPS:
return remote_button_context_wps;
case CONTEXT_TREE:
+ case CONTEXT_MAINMENU:
case CONTEXT_CUSTOM|CONTEXT_TREE:
return remote_button_context_tree;
+ case CONTEXT_QUICKSCREEN:
+ return remote_button_context_quickscreen;
#if CONFIG_TUNER
case CONTEXT_FM:
return remote_button_context_radio;
#endif
+ case CONTEXT_YESNOSCREEN:
+ return remote_button_context_yesno;
default:
return remote_button_context_standard;
}
diff --git a/apps/keymaps/keymap-ma.c b/apps/keymaps/keymap-ma.c
index aaf7df0c01..aca006d071 100644
--- a/apps/keymaps/keymap-ma.c
+++ b/apps/keymaps/keymap-ma.c
@@ -188,7 +188,7 @@ static const struct button_mapping button_context_yesnoscreen[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
/* anything that uses button_context_standard */
case CONTEXT_LIST:
diff --git a/apps/keymaps/keymap-nwz.c b/apps/keymaps/keymap-nwz.c
index 028fbf1bfd..36675566d3 100644
--- a/apps/keymaps/keymap-nwz.c
+++ b/apps/keymaps/keymap-nwz.c
@@ -112,7 +112,8 @@ static const struct button_mapping button_context_keyboard[] = {
}; /* button_context_keyboard */
static const struct button_mapping button_context_quickscreen[] = {
- { ACTION_STD_CANCEL, BUTTON_PLAY, BUTTON_NONE },
+ { ACTION_STD_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
+ { ACTION_STD_CANCEL, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
{ ACTION_QS_TOP, BUTTON_UP, BUTTON_NONE },
@@ -356,7 +357,7 @@ static const struct button_mapping button_context_usb_hid_mode_mouse[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-nwza860.c b/apps/keymaps/keymap-nwza860.c
index d455e23b62..899796552e 100644
--- a/apps/keymaps/keymap-nwza860.c
+++ b/apps/keymaps/keymap-nwza860.c
@@ -74,7 +74,8 @@ static const struct button_mapping button_context_keyboard[] = {
}; /* button_context_keyboard */
static const struct button_mapping button_context_quickscreen[] = {
- { ACTION_STD_CANCEL, BUTTON_PLAY, BUTTON_NONE },
+ { ACTION_STD_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
+ { ACTION_STD_CANCEL, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE },
LAST_ITEM_IN_LIST
diff --git a/apps/keymaps/keymap-ondavx777.c b/apps/keymaps/keymap-ondavx777.c
index ed23350666..c4b68f1ef2 100644
--- a/apps/keymaps/keymap-ondavx777.c
+++ b/apps/keymaps/keymap-ondavx777.c
@@ -127,7 +127,7 @@ static const struct button_mapping button_context_usb_hid[] = {
const struct button_mapping* target_get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-rk27xx-generic.c b/apps/keymaps/keymap-rk27xx-generic.c
index d837c608fc..4c07384810 100644
--- a/apps/keymaps/keymap-rk27xx-generic.c
+++ b/apps/keymaps/keymap-rk27xx-generic.c
@@ -164,7 +164,7 @@ static const struct button_mapping button_context_usb_hid_mode_mouse[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-shanlingq1.c b/apps/keymaps/keymap-shanlingq1.c
index 4caaa36fd2..f8fefe5ff3 100644
--- a/apps/keymaps/keymap-shanlingq1.c
+++ b/apps/keymaps/keymap-shanlingq1.c
@@ -69,7 +69,7 @@ static const struct button_mapping button_context_yesno[] = {
const struct button_mapping* target_get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
default:
case CONTEXT_STD:
diff --git a/apps/keymaps/keymap-touchscreen.c b/apps/keymaps/keymap-touchscreen.c
index 555cf42f79..07710be78d 100644
--- a/apps/keymaps/keymap-touchscreen.c
+++ b/apps/keymaps/keymap-touchscreen.c
@@ -383,7 +383,7 @@ const struct button_mapping* get_context_mapping(int context)
return target_get_context_mapping(context & ~CONTEXT_CUSTOM2);
}
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-xduoox20.c b/apps/keymaps/keymap-xduoox20.c
index b08db90cfd..fa4076e27d 100644
--- a/apps/keymaps/keymap-xduoox20.c
+++ b/apps/keymaps/keymap-xduoox20.c
@@ -184,7 +184,7 @@ static const struct button_mapping button_context_yesnoscreen[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_LIST:
return button_context_list;
diff --git a/apps/keymaps/keymap-xduoox3.c b/apps/keymaps/keymap-xduoox3.c
index bbe4c88772..bf588411eb 100644
--- a/apps/keymaps/keymap-xduoox3.c
+++ b/apps/keymaps/keymap-xduoox3.c
@@ -86,10 +86,12 @@ static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_BROWSE, BUTTON_HOME|BUTTON_REL, BUTTON_HOME },
{ ACTION_WPS_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
- { ACTION_WPS_MENU, BUTTON_OPTION|BUTTON_REL, BUTTON_OPTION },
- { ACTION_WPS_QUICKSCREEN, BUTTON_OPTION|BUTTON_REPEAT, BUTTON_OPTION },
{ ACTION_WPS_HOTKEY, BUTTON_HOME|BUTTON_REPEAT, BUTTON_HOME },
+ { ACTION_WPS_MENU, BUTTON_OPTION|BUTTON_REL, BUTTON_OPTION },
+ { ACTION_WPS_QUICKSCREEN, BUTTON_OPTION|BUTTON_REPEAT, BUTTON_OPTION },
+ { ACTION_WPS_PITCHSCREEN, BUTTON_OPTION|BUTTON_HOME|BUTTON_REPEAT, BUTTON_NONE },
+
{ ACTION_WPS_ABSETB_NEXTDIR, BUTTON_PWRALT|BUTTON_NEXT, BUTTON_POWER },
{ ACTION_WPS_ABSETA_PREVDIR, BUTTON_PWRALT|BUTTON_PREV, BUTTON_POWER },
{ ACTION_WPS_ABRESET, BUTTON_PWRALT|BUTTON_PLAY, BUTTON_POWER },
diff --git a/apps/keymaps/keymap-xduoox3ii.c b/apps/keymaps/keymap-xduoox3ii.c
index d99c8240a1..c8724ec1f0 100644
--- a/apps/keymaps/keymap-xduoox3ii.c
+++ b/apps/keymaps/keymap-xduoox3ii.c
@@ -184,7 +184,7 @@ static const struct button_mapping button_context_yesnoscreen[] = {
/* get_context_mapping returns a pointer to one of the above defined arrays depending on the context */
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_LIST:
return button_context_list;
diff --git a/apps/keymaps/keymap-ypr0.c b/apps/keymaps/keymap-ypr0.c
index 2d6be5b7ec..6e493ddf61 100644
--- a/apps/keymaps/keymap-ypr0.c
+++ b/apps/keymaps/keymap-ypr0.c
@@ -255,7 +255,7 @@ static const struct button_mapping button_context_radio[] = {
const struct button_mapping* get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-ypr1.c b/apps/keymaps/keymap-ypr1.c
index d47047912b..67f42f07c6 100644
--- a/apps/keymaps/keymap-ypr1.c
+++ b/apps/keymaps/keymap-ypr1.c
@@ -132,7 +132,7 @@ static const struct button_mapping button_context_radio[] = {
const struct button_mapping* target_get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/keymaps/keymap-zen.c b/apps/keymaps/keymap-zen.c
index b0f24af459..04b65b3980 100644
--- a/apps/keymaps/keymap-zen.c
+++ b/apps/keymaps/keymap-zen.c
@@ -145,7 +145,8 @@ static const struct button_mapping button_context_keyboard[] = {
}; /* button_context_keyboard */
static const struct button_mapping button_context_quickscreen[] = {
- { ACTION_STD_CANCEL, BUTTON_SELECT, BUTTON_NONE },
+ { ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
+ { ACTION_STD_CANCEL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
{ ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_PLAYPAUSE, BUTTON_NONE },
{ ACTION_QS_TOP, BUTTON_UP, BUTTON_NONE },
diff --git a/apps/keymaps/keymap-zenxfi2.c b/apps/keymaps/keymap-zenxfi2.c
index c98a4a8405..ba25592246 100644
--- a/apps/keymaps/keymap-zenxfi2.c
+++ b/apps/keymaps/keymap-zenxfi2.c
@@ -137,7 +137,7 @@ static const struct button_mapping button_context_radio[] = {
const struct button_mapping* target_get_context_mapping(int context)
{
- switch (context)
+ switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD:
return button_context_standard;
diff --git a/apps/lang/chinese-simp.lang b/apps/lang/chinese-simp.lang
index 3d1d0ecaa3..b7702ee3c7 100644
--- a/apps/lang/chinese-simp.lang
+++ b/apps/lang/chinese-simp.lang
@@ -13,6 +13,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# LANGUAGE_UNITS_FIRST
+#
# Simplified Chinese language file, translated by:
# - Ye Wei
# - Xinlu Huang
diff --git a/apps/lang/chinese-trad.lang b/apps/lang/chinese-trad.lang
index 02e14645e0..e7ee7ae607 100644
--- a/apps/lang/chinese-trad.lang
+++ b/apps/lang/chinese-trad.lang
@@ -13,6 +13,8 @@
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
+# LANGUAGE_UNITS_FIRST
+#
# Traditional Chinese language file, translated by:
# - Wenbin Leo
# - Xinlu Huang
diff --git a/apps/lang/english-us.lang b/apps/lang/english-us.lang
index bf5e9e93ce..5a3eb38ba3 100644
--- a/apps/lang/english-us.lang
+++ b/apps/lang/english-us.lang
@@ -1694,12 +1694,6 @@
*: "Random"
</voice>
</phrase>
-### The 'desc' field for 'LANG_AUDIOSCROBBLER' differs from the english!
-### the previously used desc is commented below:
-### desc: "Last.fm Log" in the playback menu
-### The <source> section for 'LANG_AUDIOSCROBBLER:*' differs from the english!
-### the previously used one is commented below:
-### Last.fm Logger
<phrase>
id: LANG_AUDIOSCROBBLER
desc: "Last.fm Logger" in Plugin/apps/scrobbler
@@ -2272,20 +2266,25 @@
charging: "Backlight (While Plugged In)"
</voice>
</phrase>
+### The <source> section for 'LANG_BACKLIGHT_ON_BUTTON_HOLD:*' differs from the english!
+### the previously used one is commented below:
+### Backlight on Lock
+### The <dest> section for 'LANG_BACKLIGHT_ON_BUTTON_HOLD:*' is missing! Copying from english!
+### The <voice> section for 'LANG_BACKLIGHT_ON_BUTTON_HOLD:*' is missing! Copying from english!
<phrase>
id: LANG_BACKLIGHT_ON_BUTTON_HOLD
desc: in lcd settings
user: core
<source>
- *: none
+ *: "Backlight on Lock"
hold_button: "Backlight on Hold"
</source>
<dest>
- *: none
+ *: "Backlight on Lock"
hold_button: "Backlight on Hold"
</dest>
<voice>
- *: none
+ *: "Backlight on Lock"
hold_button: "Backlight on hold"
</voice>
</phrase>
@@ -5341,19 +5340,19 @@
</phrase>
<phrase>
id: LANG_SET_AS_REC_DIR
- desc: used in the onplay menu to set a recording dir
+ desc: deprecated
user: core
<source>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</source>
<dest>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</dest>
<voice>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</voice>
</phrase>
<phrase>
@@ -6055,18 +6054,21 @@
user: core
<source>
*: none
- multivolume: "HD1"
+ hibylinux: "USB:"
+ multivolume: "HD1:"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "mSD:"
xduoox3: "mSD2:"
</source>
<dest>
*: none
+ hibylinux: "USB:"
multivolume: "HD1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "mSD:"
xduoox3: "mSD2:"
</dest>
<voice>
*: none
+ hibylinux: "U S B"
multivolume: "H D 1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "micro S D"
xduoox3: "micro S D 2"
@@ -6158,58 +6160,58 @@
</phrase>
<phrase>
id: LANG_INSERT
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert"
+ *: ""
</source>
<dest>
- *: "Insert"
+ *: ""
</dest>
<voice>
- *: "Insert"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_FIRST
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Next"
+ *: ""
</source>
<dest>
- *: "Insert Next"
+ *: ""
</dest>
<voice>
- *: "Insert Next"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_LAST
- desc: in onplay menu. append a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Last"
+ *: ""
</source>
<dest>
- *: "Insert Last"
+ *: ""
</dest>
<voice>
- *: "Insert Last"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_SHUFFLED
- desc: in onplay menu. insert a track/playlist randomly into dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Shuffled"
+ *: ""
</source>
<dest>
- *: "Insert Shuffled"
+ *: ""
</dest>
<voice>
- *: "Insert Shuffled"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -6382,16 +6384,16 @@
</phrase>
<phrase>
id: LANG_CATALOG_ADD_TO
- desc: in onplay playlist catalogue submenu
+ desc: deprecated
user: core
<source>
- *: "Add to Playlist"
+ *: ""
</source>
<dest>
- *: "Add to Playlist"
+ *: ""
</dest>
<voice>
- *: "Add to Playlist"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -10882,16 +10884,16 @@
</phrase>
<phrase>
id: LANG_INSERT_LAST_SHUFFLED
- desc: in onplay menu. insert a playlist randomly at end of dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Last Shuffled"
+ *: ""
</source>
<dest>
- *: "Insert Last Shuffled"
+ *: ""
</dest>
<voice>
- *: "Insert Last Shuffled"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11489,16 +11491,16 @@
</phrase>
<phrase>
id: LANG_SET_AS_START_DIR
- desc: used in the onplay menu to set a starting browser dir
+ desc: deprecated
user: core
<source>
- *: "Start File Browser Here"
+ *: ""
</source>
<dest>
- *: "Start File Browser Here"
+ *: ""
</dest>
<voice>
- *: "Start File Browser Here"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11618,16 +11620,16 @@
</phrase>
<phrase>
id: LANG_SET_AS_PLAYLISTCAT_DIR
- desc: used in the onplay menu to set a playlist catalogue dir
+ desc: deprecated
user: core
<source>
- *: "Set As Playlist Catalogue Directory"
+ *: ""
</source>
<dest>
- *: "Set As Playlist Catalog Directory"
+ *: ""
</dest>
<voice>
- *: "Set As Playlist Catalog Directory"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11694,16 +11696,16 @@
</phrase>
<phrase>
id: LANG_AUTOMATIC
- desc: generic automatic
+ desc: deprecated
user: core
<source>
- *: "Automatic"
+ *: ""
</source>
<dest>
- *: "Automatic"
+ *: ""
</dest>
<voice>
- *: "Automatic"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -12554,10 +12556,10 @@
*: "Exempt Seek"
</source>
<dest>
- *: "Seek"
+ *: "Exempt Seek"
</dest>
<voice>
- *: "Seek"
+ *: "Exempt Seek"
</voice>
</phrase>
<phrase>
@@ -12627,10 +12629,10 @@
*: "Exempt Play"
</source>
<dest>
- *: "Play"
+ *: "Exempt Play"
</dest>
<voice>
- *: "Play"
+ *: "Exempt Play"
</voice>
</phrase>
<phrase>
@@ -12916,10 +12918,10 @@
*: "Exempt Skip"
</source>
<dest>
- *: "Skip"
+ *: "Exempt Skip"
</dest>
<voice>
- *: "Skip"
+ *: "Exempt Skip"
</voice>
</phrase>
<phrase>
@@ -13879,10 +13881,10 @@
*: "Disable Locked Reminders"
</source>
<dest>
- *: "Disable Notify"
+ *: "Disable Locked Reminders"
</dest>
<voice>
- *: "Disable Notify"
+ *: "Disable Locked Reminders"
</voice>
</phrase>
<phrase>
@@ -14605,16 +14607,16 @@
</phrase>
<phrase>
id: LANG_CLEAR_PLAYLIST
- desc: in the pictureflow main menu
+ desc: deprecated
user: core
<source>
- *: "Clear playlist"
+ *: ""
</source>
<dest>
- *: "Clear playlist"
+ *: ""
</dest>
<voice>
- *: "Clear playlist"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -14911,7 +14913,7 @@
</phrase>
<phrase>
id: LANG_DIRECT
- desc: in the pictureflow settings
+ desc: in the pictureflow settings, also a volume adjustment mode
user: core
<source>
*: "Direct"
@@ -16099,7 +16101,6 @@
*: "Descending"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_ALBUM_ART
desc: in Settings
@@ -16114,7 +16115,6 @@
*: "Album Art"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_PREFER_EMBEDDED
desc: in Settings
@@ -16129,7 +16129,6 @@
*: "Prefer Embedded"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_PREFER_IMAGE_FILE
desc: in Settings
@@ -16144,7 +16143,6 @@
*: "Prefer Image File"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_FM_SYNC_RDS_TIME
desc: in radio screen and Settings
@@ -16162,7 +16160,6 @@
rds: "Sync RDS Time"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_SORT_ALBUMS_BY
desc: in Settings
@@ -16177,7 +16174,6 @@
*: "Sort albums by"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_ARTIST_PLUS_NAME
desc: in Settings
@@ -16192,7 +16188,6 @@
*: "Artist And Name"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_ARTIST_PLUS_YEAR
desc: in Settings
@@ -16207,7 +16202,6 @@
*: "Artist And Year"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_YEAR_SORT_ORDER
desc: in Settings
@@ -16222,7 +16216,6 @@
*: "Year sort order"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_SHOW_YEAR_IN_ALBUM_TITLE
desc: in Settings
@@ -16237,7 +16230,6 @@
*: "Show year in album title"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_WAIT_FOR_CACHE
desc: in Settings
@@ -16252,7 +16244,6 @@
*: "Cache needs to finish updating first!"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_TRACK_INFO
desc: Track Info Title
@@ -16267,7 +16258,6 @@
*: "Track Info"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_PLAY
desc: play selected file/directory, in playlist context menu
@@ -16282,7 +16272,6 @@
*: "Play"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_PLAY_SHUFFLED
desc: play selected files in shuffled order, in playlist context menu
@@ -16297,7 +16286,6 @@
*: "Play Shuffled"
</voice>
</phrase>
-### This phrase is missing entirely, copying from english!
<phrase>
id: LANG_KEEP_CURRENT_TRACK_ON_REPLACE
desc: used in the playlist settings menu
@@ -16312,3 +16300,273 @@
*: "Keep Current Track When Replacing Playlist"
</voice>
</phrase>
+<phrase>
+ id: LANG_CLEAR_SETTINGS_ON_HOLD
+ desc: in the system sub menu
+ user: core
+ <source>
+ *: none
+ clear_settings_on_hold,iriverh10: "Clear settings when reset button is held during startup"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Clear settings when hold switch is on during startup"
+ </source>
+ <dest>
+ *: none
+ clear_settings_on_hold,iriverh10: "Clear settings when reset button is held during startup"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Clear settings when hold switch is on during startup"
+ </dest>
+ <voice>
+ *: none
+ clear_settings_on_hold,iriverh10: "Clear settings when reset button is held during startup"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Clear settings when hold switch is on during startup"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_REWIND_ACROSS_TRACKS
+ desc: in playback settings menu
+ user: core
+ <source>
+ *: "Rewind Across Tracks"
+ </source>
+ <dest>
+ *: "Rewind Across Tracks"
+ </dest>
+ <voice>
+ *: "Rewind across tracks"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SET_AS
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Set As..."
+ </source>
+ <dest>
+ *: "Set As..."
+ </dest>
+ <voice>
+ *: "Set As..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAYLIST_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Playlist Directory"
+ </source>
+ <dest>
+ *: "Playlist Directory"
+ </dest>
+ <voice>
+ *: "Playlist Directory"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_START_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Start Directory"
+ </source>
+ <dest>
+ *: "Start Directory"
+ </dest>
+ <voice>
+ *: "Start Directory"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_RECORDING_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: none
+ recording: "Recording Directory"
+ </source>
+ <dest>
+ *: none
+ recording: "Recording Directory"
+ </dest>
+ <voice>
+ *: none
+ recording: "Recording Directory"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_TO_PL
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add to Playlist..."
+ </source>
+ <dest>
+ *: "Add to Playlist..."
+ </dest>
+ <voice>
+ *: "Add to Playlist..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_TO_EXISTING_PL
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add to Existing Playlist"
+ </source>
+ <dest>
+ *: "Add to Existing Playlist"
+ </dest>
+ <voice>
+ *: "Add to Existing Playlist"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAYING_NEXT
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Playing Next..."
+ </source>
+ <dest>
+ *: "Playing Next..."
+ </dest>
+ <voice>
+ *: "Playing Next..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_NEXT
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Next"
+ </source>
+ <dest>
+ *: "Play Next"
+ </dest>
+ <voice>
+ *: "Play Next"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_SHUFFLED
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add Shuffled"
+ </source>
+ <dest>
+ *: "Add Shuffled"
+ </dest>
+ <voice>
+ *: "Add Shuffled"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_LAST
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Last"
+ </source>
+ <dest>
+ *: "Play Last"
+ </dest>
+ <voice>
+ *: "Play Last"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_LAST_SHUFFLED
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Last Shuffled"
+ </source>
+ <dest>
+ *: "Play Last Shuffled"
+ </dest>
+ <voice>
+ *: "Play Last Shuffled"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_VOLUME_ADJUST_MODE
+ desc: in system settings
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Volume Adjustment Mode"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Volume Adjustment Mode"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Volume Adjustment Mode"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_VOLUME_ADJUST_NORM_STEPS
+ desc: in system settings
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Number of Volume Steps"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Number of Volume Steps"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Number of Volume Steps"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PERCEPTUAL
+ desc: in system settings -> volume adjustment mode
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Perceptual"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Perceptual"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Perceptual"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SHOW_TRACKS_WHILE_BROWSING
+ desc: in PictureFlow Main Menu
+ user: core
+ <source>
+ *: "Show Tracks While Browsing"
+ </source>
+ <dest>
+ *: "Show Tracks While Browsing"
+ </dest>
+ <voice>
+ *: "Show Tracks While Browsing"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_GOTO_LAST_ALBUM
+ desc: in PictureFlow Main Menu
+ user: core
+ <source>
+ *: "Go to Last Album"
+ </source>
+ <dest>
+ *: "Go to Last Album"
+ </dest>
+ <voice>
+ *: "Go to Last Album"
+ </voice>
+</phrase>
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 75849714e6..3773d138d4 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -2347,15 +2347,15 @@
desc: in lcd settings
user: core
<source>
- *: none
+ *: "Backlight on Lock"
hold_button: "Backlight on Hold"
</source>
<dest>
- *: none
+ *: "Backlight on Lock"
hold_button: "Backlight on Hold"
</dest>
<voice>
- *: none
+ *: "Backlight on Lock"
hold_button: "Backlight on hold"
</voice>
</phrase>
@@ -3645,22 +3645,22 @@
user: core
<source>
*: none
+ rtc: "ON = Set"
gigabeat*,iaudiom5,iaudiox5,ipod*,iriverh10,iriverh10_5gb,mrobe100,sansac200*,sansaclip*,sansaconnect,sansae200*,sansafuze*: "SELECT = Set"
gogearsa9200,samsungyh*: "PLAY = Set"
iriverh100,iriverh120,iriverh300: "NAVI = Set"
mpiohd300: "ENTER = Set"
mrobe500: "HEART = Set"
- rtc: "ON = Set"
vibe500: "OK = Set"
</source>
<dest>
*: none
+ rtc: "ON = Set"
gigabeat*,iaudiom5,iaudiox5,ipod*,iriverh10,iriverh10_5gb,mrobe100,sansac200*,sansaclip*,sansaconnect,sansae200*,sansafuze*: "SELECT = Set"
gogearsa9200,samsungyh*: "PLAY = Set"
iriverh100,iriverh120,iriverh300: "NAVI = Set"
mpiohd300: "ENTER = Set"
mrobe500: "HEART = Set"
- rtc: "ON = Set"
vibe500: "OK = Set"
</dest>
<voice>
@@ -3674,6 +3674,7 @@
user: core
<source>
*: none
+ rtc: "OFF = Revert"
gigabeatfx,mrobe500: "POWER = Revert"
gigabeats,sansafuzeplus: "BACK = Revert"
gogearsa9200: "LEFT = Revert"
@@ -3682,12 +3683,12 @@
iriverh10,iriverh10_5gb,sansae200*,sansafuze*: "PREV = Revert"
iriverh100,iriverh120,iriverh300: "STOP = Revert"
mrobe100: "DISPLAY = Revert"
- rtc: "OFF = Revert"
samsungyh*: "REW = Revert"
vibe500: "CANCEL = Revert"
</source>
<dest>
*: none
+ rtc: "OFF = Revert"
gigabeatfx,mrobe500: "POWER = Revert"
gigabeats,sansafuzeplus: "BACK = Revert"
gogearsa9200: "LEFT = Revert"
@@ -3696,7 +3697,6 @@
iriverh10,iriverh10_5gb,sansae200*,sansafuze*: "PREV = Revert"
iriverh100,iriverh120,iriverh300: "STOP = Revert"
mrobe100: "DISPLAY = Revert"
- rtc: "OFF = Revert"
samsungyh*: "REW = Revert"
vibe500: "CANCEL = Revert"
</dest>
@@ -5411,19 +5411,19 @@
</phrase>
<phrase>
id: LANG_SET_AS_REC_DIR
- desc: used in the onplay menu to set a recording dir
+ desc: deprecated
user: core
<source>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</source>
<dest>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</dest>
<voice>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</voice>
</phrase>
<phrase>
@@ -6125,18 +6125,21 @@
user: core
<source>
*: none
- multivolume: "HD1"
+ hibylinux: "USB:"
+ multivolume: "HD1:"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "mSD:"
xduoox3: "mSD2:"
</source>
<dest>
*: none
- multivolume: "HD1"
+ hibylinux: "USB:"
+ multivolume: "HD1:"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "MSD:"
xduoox3: "mSD2:"
</dest>
<voice>
*: none
+ hibylinux: "U S B"
multivolume: "H D 1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "micro S D"
xduoox3: "micro S D 2"
@@ -6228,58 +6231,58 @@
</phrase>
<phrase>
id: LANG_INSERT
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert"
+ *: ""
</source>
<dest>
- *: "Insert"
+ *: ""
</dest>
<voice>
- *: "Insert"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_FIRST
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Next"
+ *: ""
</source>
<dest>
- *: "Insert Next"
+ *: ""
</dest>
<voice>
- *: "Insert Next"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_LAST
- desc: in onplay menu. append a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Last"
+ *: ""
</source>
<dest>
- *: "Insert Last"
+ *: ""
</dest>
<voice>
- *: "Insert Last"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_SHUFFLED
- desc: in onplay menu. insert a track/playlist randomly into dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Shuffled"
+ *: ""
</source>
<dest>
- *: "Insert Shuffled"
+ *: ""
</dest>
<voice>
- *: "Insert Shuffled"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -6452,16 +6455,16 @@
</phrase>
<phrase>
id: LANG_CATALOG_ADD_TO
- desc: in onplay playlist catalogue submenu
+ desc: deprecated
user: core
<source>
- *: "Add to Playlist"
+ *: ""
</source>
<dest>
- *: "Add to Playlist"
+ *: ""
</dest>
<voice>
- *: "Add to Playlist"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -10980,16 +10983,16 @@
</phrase>
<phrase>
id: LANG_INSERT_LAST_SHUFFLED
- desc: in onplay menu. insert a playlist randomly at end of dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Last Shuffled"
+ *: ""
</source>
<dest>
- *: "Insert Last Shuffled"
+ *: ""
</dest>
<voice>
- *: "Insert Last Shuffled"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11587,16 +11590,16 @@
</phrase>
<phrase>
id: LANG_SET_AS_START_DIR
- desc: used in the onplay menu to set a starting browser dir
+ desc: deprecated
user: core
<source>
- *: "Start File Browser Here"
+ *: ""
</source>
<dest>
- *: "Start File Browser Here"
+ *: ""
</dest>
<voice>
- *: "Start File Browser Here"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11702,16 +11705,16 @@
</phrase>
<phrase>
id: LANG_SET_AS_PLAYLISTCAT_DIR
- desc: used in the onplay menu to set a playlist catalogue dir
+ desc: deprecated
user: core
<source>
- *: "Set As Playlist Catalogue Directory"
+ *: ""
</source>
<dest>
- *: "Set As Playlist Catalogue Directory"
+ *: ""
</dest>
<voice>
- *: "Set As Playlist Catalogue Directory"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11792,16 +11795,16 @@
</phrase>
<phrase>
id: LANG_AUTOMATIC
- desc: generic automatic
+ desc: deprecated
user: core
<source>
- *: "Automatic"
+ *: ""
</source>
<dest>
- *: "Automatic"
+ *: ""
</dest>
<voice>
- *: "Automatic"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -15107,16 +15110,16 @@
</phrase>
<phrase>
id: LANG_CLEAR_PLAYLIST
- desc: in the pictureflow main menu
+ desc: deprecated
user: core
<source>
- *: "Clear playlist"
+ *: ""
</source>
<dest>
- *: "Clear playlist"
+ *: ""
</dest>
<voice>
- *: "Clear playlist"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -15163,7 +15166,7 @@
</phrase>
<phrase>
id: LANG_DIRECT
- desc: in the pictureflow settings
+ desc: in the pictureflow settings, also a volume adjustment mode
user: core
<source>
*: "Direct"
@@ -16374,21 +16377,267 @@
user: core
<source>
*: none
- ipod3g: none
- ipod*: "Clear settings when hold switch is on during startup"
+ ipodcolor,ipodnano1g,ipodvideo,ipod4g,ipodmini1g,ipodmini2g: "Clear settings when hold switch is on during startup"
clear_settings_on_hold, iriverh10: "Clear settings when reset button is held during startup"
</source>
<dest>
*: none
- ipod3g: none
- ipod*: "Clear settings when hold switch is on during startup"
+ ipodcolor,ipodnano1g,ipodvideo,ipod4g,ipodmini1g,ipodmini2g: "Clear settings when hold switch is on during startup"
clear_settings_on_hold, iriverh10: "Clear settings when reset button is held during startup"
</dest>
<voice>
*: none
- ipod3g: none
- ipod*: "Clear settings when hold switch is on during startup"
+ ipodcolor,ipodnano1g,ipodvideo,ipod4g,ipodmini1g,ipodmini2g: "Clear settings when hold switch is on during startup"
clear_settings_on_hold, iriverh10: "Clear settings when reset button is held during startup"
</voice>
</phrase>
-
+<phrase>
+ id: LANG_REWIND_ACROSS_TRACKS
+ desc: in playback settings menu
+ user: core
+ <source>
+ *: "Rewind Across Tracks"
+ </source>
+ <dest>
+ *: "Rewind Across Tracks"
+ </dest>
+ <voice>
+ *: "Rewind across tracks"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SET_AS
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Set As..."
+ </source>
+ <dest>
+ *: "Set As..."
+ </dest>
+ <voice>
+ *: "Set As..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAYLIST_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Playlist Directory"
+ </source>
+ <dest>
+ *: "Playlist Directory"
+ </dest>
+ <voice>
+ *: "Playlist Directory"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_START_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Start Directory"
+ </source>
+ <dest>
+ *: "Start Directory"
+ </dest>
+ <voice>
+ *: "Start Directory"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_RECORDING_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: none
+ recording: "Recording Directory"
+ </source>
+ <dest>
+ *: none
+ recording: "Recording Directory"
+ </dest>
+ <voice>
+ *: none
+ recording: "Recording Directory"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_TO_PL
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add to Playlist..."
+ </source>
+ <dest>
+ *: "Add to Playlist..."
+ </dest>
+ <voice>
+ *: "Add to Playlist..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_TO_EXISTING_PL
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add to Existing Playlist"
+ </source>
+ <dest>
+ *: "Add to Existing Playlist"
+ </dest>
+ <voice>
+ *: "Add to Existing Playlist"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAYING_NEXT
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Playing Next..."
+ </source>
+ <dest>
+ *: "Playing Next..."
+ </dest>
+ <voice>
+ *: "Playing Next..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_NEXT
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Next"
+ </source>
+ <dest>
+ *: "Play Next"
+ </dest>
+ <voice>
+ *: "Play Next"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_SHUFFLED
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add Shuffled"
+ </source>
+ <dest>
+ *: "Add Shuffled"
+ </dest>
+ <voice>
+ *: "Add Shuffled"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_LAST
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Last"
+ </source>
+ <dest>
+ *: "Play Last"
+ </dest>
+ <voice>
+ *: "Play Last"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_LAST_SHUFFLED
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Last Shuffled"
+ </source>
+ <dest>
+ *: "Play Last Shuffled"
+ </dest>
+ <voice>
+ *: "Play Last Shuffled"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_VOLUME_ADJUST_MODE
+ desc: in system settings
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Volume Adjustment Mode"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Volume Adjustment Mode"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Volume Adjustment Mode"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_VOLUME_ADJUST_NORM_STEPS
+ desc: in system settings
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Number of Volume Steps"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Number of Volume Steps"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Number of Volume Steps"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PERCEPTUAL
+ desc: in system settings -> volume adjustment mode
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Perceptual"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Perceptual"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Perceptual"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SHOW_TRACKS_WHILE_BROWSING
+ desc: in PictureFlow Main Menu
+ user: core
+ <source>
+ *: "Show Tracks While Browsing"
+ </source>
+ <dest>
+ *: "Show Tracks While Browsing"
+ </dest>
+ <voice>
+ *: "Show Tracks While Browsing"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_GOTO_LAST_ALBUM
+ desc: in PictureFlow Main Menu
+ user: core
+ <source>
+ *: "Go to Last Album"
+ </source>
+ <dest>
+ *: "Go to Last Album"
+ </dest>
+ <voice>
+ *: "Go to Last Album"
+ </voice>
+</phrase>
diff --git a/apps/lang/italiano.lang b/apps/lang/italiano.lang
index 0688ca7846..b6b97df22f 100644
--- a/apps/lang/italiano.lang
+++ b/apps/lang/italiano.lang
@@ -5324,19 +5324,17 @@
</phrase>
<phrase>
id: LANG_SET_AS_REC_DIR
- desc: used in the onplay menu to set a recording dir
+ desc: deprecated
user: core
<source>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</source>
<dest>
- *: none
- recording: "Imposta come cartella di registrazione"
+ *: ""
</dest>
<voice>
- *: none
- recording: "Imposta come cartella di registrazione"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -6038,18 +6036,21 @@
user: core
<source>
*: none
- multivolume: "HD1"
+ hibylinux: "USB:"
+ multivolume: "HD1:"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "mSD:"
xduoox3: "mSD2:"
</source>
<dest>
*: none
+ hibylinux: "USB:"
multivolume: "HD1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "MSD:"
xduoox3: "MSD2:"
</dest>
<voice>
*: none
+ hibylinux: "U S B"
multivolume: "HD 1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "Micro S D"
xduoox3: "Micro SD 2"
@@ -6141,58 +6142,58 @@
</phrase>
<phrase>
id: LANG_INSERT
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert"
+ *: ""
</source>
<dest>
- *: "Inserisci"
+ *: ""
</dest>
<voice>
- *: "Inserisci"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_FIRST
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Next"
+ *: ""
</source>
<dest>
- *: "Inserisci come prossima"
+ *: ""
</dest>
<voice>
- *: "Inserisci come prossima"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_LAST
- desc: in onplay menu. append a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Last"
+ *: ""
</source>
<dest>
- *: "Inserisci Come Ultima"
+ *: ""
</dest>
<voice>
- *: "Inserisci Come Ultima"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_SHUFFLED
- desc: in onplay menu. insert a track/playlist randomly into dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Shuffled"
+ *: ""
</source>
<dest>
- *: "Mescola E Inserisci"
+ *: ""
</dest>
<voice>
- *: "Mescola E Inserisci"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -6365,16 +6366,16 @@
</phrase>
<phrase>
id: LANG_CATALOG_ADD_TO
- desc: in onplay playlist catalogue submenu
+ desc: deprecated
user: core
<source>
- *: "Add to Playlist"
+ *: ""
</source>
<dest>
- *: "Aggiungi alla playlist"
+ *: ""
</dest>
<voice>
- *: "Aggiungi alla playlist"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -6763,7 +6764,7 @@
*: "<No Info>"
</source>
<dest>
- *: "<No Info>"
+ *: "<Nessuna0 Info>"
</dest>
<voice>
*: "Nessuna Informazione"
@@ -10848,16 +10849,16 @@
</phrase>
<phrase>
id: LANG_INSERT_LAST_SHUFFLED
- desc: in onplay menu. insert a playlist randomly at end of dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Last Shuffled"
+ *: ""
</source>
<dest>
- *: "Mescola E Inserisci Come Ultima"
+ *: ""
</dest>
<voice>
- *: "Mescola E Inserisci Come Ultima"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11455,16 +11456,16 @@
</phrase>
<phrase>
id: LANG_SET_AS_START_DIR
- desc: used in the onplay menu to set a starting browser dir
+ desc: deprecated
user: core
<source>
- *: "Start File Browser Here"
+ *: ""
</source>
<dest>
- *: "Avvia Sfoglia File Da Qui"
+ *: ""
</dest>
<voice>
- *: "Avvia Sfoglia File Da Qui"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11570,16 +11571,16 @@
</phrase>
<phrase>
id: LANG_SET_AS_PLAYLISTCAT_DIR
- desc: used in the onplay menu to set a playlist catalogue dir
+ desc: deprecated
user: core
<source>
- *: "Set As Playlist Catalogue Directory"
+ *: ""
</source>
<dest>
- *: "Imposta Come Cartella Catalogo Playlist"
+ *: ""
</dest>
<voice>
- *: "Imposta Come Cartella Catalogo Playlist"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11660,16 +11661,16 @@
</phrase>
<phrase>
id: LANG_AUTOMATIC
- desc: generic automatic
+ desc: deprecated
user: core
<source>
- *: "Automatic"
+ *: ""
</source>
<dest>
- *: "Automatico"
+ *: ""
</dest>
<voice>
- *: "Automatico"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -12510,7 +12511,7 @@
</phrase>
<phrase>
id: LANG_DIRECT
- desc: in the pictureflow settings
+ desc: in the pictureflow settings, also a volume adjustment mode
user: core
<source>
*: "Direct"
@@ -13069,16 +13070,16 @@
</phrase>
<phrase>
id: LANG_PROPERTIES_ALBUM
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Album]"
+ *: ""
</source>
<dest>
- *: "[Album]"
+ *: ""
</dest>
<voice>
- *: "Album"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -13198,16 +13199,16 @@
</phrase>
<phrase>
id: LANG_PROPERTIES_ARTIST
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Artist]"
+ *: ""
</source>
<dest>
- *: "[Artista]"
+ *: ""
</dest>
<voice>
- *: "Artista"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -13257,16 +13258,16 @@
</phrase>
<phrase>
id: LANG_PROPERTIES_TITLE
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Title]"
+ *: ""
</source>
<dest>
- *: "[Titolo]"
+ *: ""
</dest>
<voice>
- *: "Titolo"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -13532,16 +13533,16 @@
</phrase>
<phrase>
id: LANG_PROPERTIES_DURATION
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Duration]"
+ *: ""
</source>
<dest>
- *: "[Durata]"
+ *: ""
</dest>
<voice>
- *: "Durata"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -14879,16 +14880,16 @@
</phrase>
<phrase>
id: LANG_CLEAR_PLAYLIST
- desc: in the pictureflow main menu
+ desc: deprecated
user: core
<source>
- *: "Clear playlist"
+ *: ""
</source>
<dest>
- *: "Svuota playlist"
+ *: ""
</dest>
<voice>
- *: "Svuota playlist"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -15507,16 +15508,16 @@
</phrase>
<phrase>
id: LANG_CLEAR_LIST_AND_PLAY_NEXT
- desc: in onplay menu. Replace current playlist with selected tracks
+ desc: deprecated
user: core
<source>
- *: "Clear List & Play Next"
+ *: ""
</source>
<dest>
- *: "Cancella Lista e Riproduci Successivo"
+ *: ""
</dest>
<voice>
- *: "Cancella Lista e Riproduci Successivo"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -15637,16 +15638,16 @@
</phrase>
<phrase>
id: LANG_CLEAR_LIST_AND_PLAY_SHUFFLED
- desc: in onplay menu. Replace current playlist with selected tracks in random order.
+ desc: deprecated
user: core
<source>
- *: "Clear List & Play Shuffled"
+ *: ""
</source>
<dest>
- *: "Cancella Lista e Riproduci in Ordine Casuale"
+ *: ""
</dest>
<voice>
- *: "Cancella Lista e Riproduci in Ordine Casuale"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -15874,128 +15875,128 @@
</phrase>
<phrase>
id: LANG_PROPERTIES_ALBUMARTIST
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Album Artist]"
+ *: ""
</source>
<dest>
- *: "[Artista Album]"
+ *: ""
</dest>
<voice>
- *: "Artista Album"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_GENRE
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Genre]"
+ *: ""
</source>
<dest>
- *: "[Genere]"
+ *: ""
</dest>
<voice>
- *: "Genere"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_COMMENT
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Comment]"
+ *: ""
</source>
<dest>
- *: "[Commento]"
+ *: ""
</dest>
<voice>
- *: "Commento"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_COMPOSER
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Composer]"
+ *: ""
</source>
<dest>
- *: "[Compositore]"
+ *: ""
</dest>
<voice>
- *: "Compositore"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_YEAR
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Year]"
+ *: ""
</source>
<dest>
- *: "[Anno]"
+ *: ""
</dest>
<voice>
- *: "Anno"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_TRACKNUM
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Tracknum]"
+ *: ""
</source>
<dest>
- *: "[Numtraccia]"
+ *: ""
</dest>
<voice>
- *: "Numero traccia"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_DISCNUM
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Discnum]"
+ *: ""
</source>
<dest>
- *: "[Numdisco]"
+ *: ""
</dest>
<voice>
- *: "Numero disco"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_FREQUENCY
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Frequency]"
+ *: ""
</source>
<dest>
- *: "[Frequenza]"
+ *: ""
</dest>
<voice>
- *: "Frequenza"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_BITRATE
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Bitrate]"
+ *: ""
</source>
<dest>
- *: "[Bitrate]"
+ *: ""
</dest>
<voice>
- *: "Bitrate"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -16239,3 +16240,329 @@
*: "La cache deve prima completare l'aggiornamento!"
</voice>
</phrase>
+<phrase>
+ id: LANG_TRACK_INFO
+ desc: Track Info Title
+ user: core
+ <source>
+ *: "Track Info"
+ </source>
+ <dest>
+ *: "Info Traccia"
+ </dest>
+ <voice>
+ *: "Info Traccia"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY
+ desc: play selected file/directory, in playlist context menu
+ user: core
+ <source>
+ *: "Play"
+ </source>
+ <dest>
+ *: "Riproduci"
+ </dest>
+ <voice>
+ *: "Riproduci"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_SHUFFLED
+ desc: play selected files in shuffled order, in playlist context menu
+ user: core
+ <source>
+ *: "Play Shuffled"
+ </source>
+ <dest>
+ *: "Riproduci Casualmente"
+ </dest>
+ <voice>
+ *: "Riproduci Casualmente"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_KEEP_CURRENT_TRACK_ON_REPLACE
+ desc: used in the playlist settings menu
+ user: core
+ <source>
+ *: "Keep Current Track When Replacing Playlist"
+ </source>
+ <dest>
+ *: "Mantieni La Traccia Corrente Quando Sostituisci La Playlist"
+ </dest>
+ <voice>
+ *: "Mantieni La Traccia Corrente Quando Sostituisci La Playlist"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_CLEAR_SETTINGS_ON_HOLD
+ desc: in the system sub menu
+ user: core
+ <source>
+ *: none
+ clear_settings_on_hold,iriverh10: "Clear settings when reset button is held during startup"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Clear settings when hold switch is on during startup"
+ </source>
+ <dest>
+ *: none
+ clear_settings_on_hold,iriverh10: "Cancella le impostazioni quando si tiene premuto il pulsante reset durante l'avvio"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Cancella le impostazioni quando l'interruttore di blocco è attivo durante l'avvio"
+ </dest>
+ <voice>
+ *: none
+ clear_settings_on_hold,iriverh10: "Cancella le impostazioni quando si tiene premuto il pulsante reset durante l'avvio"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Cancella le impostazioni quando l'interruttore di blocco è attivo durante l'avvio"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_REWIND_ACROSS_TRACKS
+ desc: in playback settings menu
+ user: core
+ <source>
+ *: "Rewind Across Tracks"
+ </source>
+ <dest>
+ *: "Riavvolgi tra le tracce"
+ </dest>
+ <voice>
+ *: "Riavvolgi tra le tracce"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SET_AS
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Set As..."
+ </source>
+ <dest>
+ *: "Imposta Come..."
+ </dest>
+ <voice>
+ *: "Imposta Come..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAYLIST_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Playlist Directory"
+ </source>
+ <dest>
+ *: "Cartella Playlist"
+ </dest>
+ <voice>
+ *: "Cartella Playlist"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_START_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Start Directory"
+ </source>
+ <dest>
+ *: "Cartella Iniziale"
+ </dest>
+ <voice>
+ *: "Cartella Iniziale"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_RECORDING_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: none
+ recording: "Recording Directory"
+ </source>
+ <dest>
+ *: none
+ recording: "Cartella Di Registrazione"
+ </dest>
+ <voice>
+ *: none
+ recording: "Cartella Di Registrazione"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_TO_PL
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add to Playlist..."
+ </source>
+ <dest>
+ *: "Aggiungi alla Playlist..."
+ </dest>
+ <voice>
+ *: "Aggiungi alla Playlist..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_TO_EXISTING_PL
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add to Existing Playlist"
+ </source>
+ <dest>
+ *: "Aggiungi alla Playlist Esistente"
+ </dest>
+ <voice>
+ *: "Aggiungi alla Playlist Esistente"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAYING_NEXT
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Playing Next..."
+ </source>
+ <dest>
+ *: "Riproduzione Brano Successivo..."
+ </dest>
+ <voice>
+ *: "Riproduzione Brano Successivo..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_NEXT
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Next"
+ </source>
+ <dest>
+ *: "Riproduci Successivo"
+ </dest>
+ <voice>
+ *: "Riproduci Successivo"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_SHUFFLED
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add Shuffled"
+ </source>
+ <dest>
+ *: "Aggiungi Casualmente"
+ </dest>
+ <voice>
+ *: "Aggiungi Casualmente"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_LAST
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Last"
+ </source>
+ <dest>
+ *: "Riproduci Ultimo"
+ </dest>
+ <voice>
+ *: "Riproduci Ultimo"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_LAST_SHUFFLED
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Last Shuffled"
+ </source>
+ <dest>
+ *: "Riproduci Ultimo Casualmente"
+ </dest>
+ <voice>
+ *: "Riproduci Ultimo Casualmente"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_VOLUME_ADJUST_MODE
+ desc: in system settings
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Volume Adjustment Mode"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Modalità Aggiustamento Volume"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Modalità Aggiustamento Volume"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_VOLUME_ADJUST_NORM_STEPS
+ desc: in system settings
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Number of Volume Steps"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Numero di Passi per il Volume"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Numero di Passi per il Volume"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PERCEPTUAL
+ desc: in system settings -> volume adjustment mode
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Perceptual"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Percettivo"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Percettivo"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SHOW_TRACKS_WHILE_BROWSING
+ desc: in PictureFlow Main Menu
+ user: core
+ <source>
+ *: "Show Tracks While Browsing"
+ </source>
+ <dest>
+ *: "Mostra tracce durante la navigazione"
+ </dest>
+ <voice>
+ *: "Mostra tracce durante la navigazione"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_GOTO_LAST_ALBUM
+ desc: in PictureFlow Main Menu
+ user: core
+ <source>
+ *: "Go to Last Album"
+ </source>
+ <dest>
+ *: "Vai all'Ultimo Album"
+ </dest>
+ <voice>
+ *: "Vai all'Ultimo Album"
+ </voice>
+</phrase>
diff --git a/apps/lang/nederlands.lang b/apps/lang/nederlands.lang
index 5fbd93df81..83139cc6de 100644
--- a/apps/lang/nederlands.lang
+++ b/apps/lang/nederlands.lang
@@ -4250,31 +4250,16 @@
</phrase>
<phrase>
id: LANG_ALARM_MOD_KEYS
- desc: Shown key functions in alarm menu (for the RTC alarm mod).
+ desc: deprecated
user: core
<source>
- *: none
- alarm: "PLAY=Set OFF=Cancel"
- gigabeats: "SELECT=Set POWER=Cancel"
- ipod*: "SELECT=Set MENU=Cancel"
- iriverh10,iriverh10_5gb: "SELECT=Set PREV=Cancel"
- mpiohd300: "ENTER=Set MENU=Cancel"
- sansafuzeplus: "SELECT=Set BACK=Cancel"
- vibe500: "OK=Set C=Cancel"
+ *: ""
</source>
<dest>
- *: none
- alarm: "PLAY=Instellen, OFF=Annuleren"
- gigabeats: "SELECT=Instellen, POWER=Annuleren"
- ipod*: "SELECT=Instellen, MENU=Annuleren"
- iriverh10,iriverh10_5gb: "SELECT=Instellen, PREV=Annuleren"
- mpiohd300: "ENTER=Instellen, MENU=Annuleren"
- sansafuzeplus: "SELECT=Instellen, BACK=Annuleren"
- vibe500: "OK=Instellen, C=Annuleren"
+ *: ""
</dest>
<voice>
- *: none
- alarm,ipod*: ""
+ *: ""
</voice>
</phrase>
<phrase>
@@ -7580,10 +7565,10 @@
</phrase>
<phrase>
id: LANG_AUDIOSCROBBLER
- desc: "Last.fm Log" in the playback menu
+ desc: "Last.fm Logger" in Plugin/apps/scrobbler
user: core
<source>
- *: "Last.fm Log"
+ *: "Last.fm Logger"
</source>
<dest>
*: "Last.fm-logboek"
@@ -14430,58 +14415,58 @@
</phrase>
<phrase>
id: LANG_PROPERTIES_ARTIST
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Artist]"
+ *: ""
</source>
<dest>
- *: "[Artiest]"
+ *: ""
</dest>
<voice>
- *: "Artiest"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_TITLE
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Title]"
+ *: ""
</source>
<dest>
- *: "[Titel]"
+ *: ""
</dest>
<voice>
- *: "Titel"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_ALBUM
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Album]"
+ *: ""
</source>
<dest>
- *: "[Album]"
+ *: ""
</dest>
<voice>
- *: "Album"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_DURATION
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Duration]"
+ *: ""
</source>
<dest>
- *: "[Looptijd]"
+ *: ""
</dest>
<voice>
- *: "Looptijd"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -14683,7 +14668,7 @@
lowmem: none
</dest>
<voice>
- *: "CPU Boost"
+ *: "CPU-boost"
lowmem: none
</voice>
</phrase>
@@ -15744,16 +15729,16 @@
</phrase>
<phrase>
id: LANG_CLEAR_LIST_AND_PLAY_NEXT
- desc: in onplay menu. Replace current playlist with selected tracks
+ desc: deprecated
user: core
<source>
- *: "Clear List & Play Next"
+ *: ""
</source>
<dest>
- *: "Lijst Wissen en Volgende Afspelen"
+ *: ""
</dest>
<voice>
- *: "Lijst Wissen en Volgende Afspelen"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -15814,16 +15799,16 @@
</phrase>
<phrase>
id: LANG_CLEAR_LIST_AND_PLAY_SHUFFLED
- desc: in onplay menu. Replace current playlist with selected tracks in random order.
+ desc: deprecated
user: core
<source>
- *: "Clear List & Play Shuffled"
+ *: ""
</source>
<dest>
- *: "Lijst Wissen en in Geschude Volgorde Afspelen"
+ *: ""
</dest>
<voice>
- *: "Lijst Wissen en in Geschude Volgorde Afspelen"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -15898,128 +15883,128 @@
</phrase>
<phrase>
id: LANG_PROPERTIES_ALBUMARTIST
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Album Artist]"
+ *: ""
</source>
<dest>
- *: "[Album Artiest]"
+ *: ""
</dest>
<voice>
- *: "Album Artiest"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_GENRE
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Genre]"
+ *: ""
</source>
<dest>
- *: "[Genre]"
+ *: ""
</dest>
<voice>
- *: "Genre"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_COMMENT
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Comment]"
+ *: ""
</source>
<dest>
- *: "[Commentaar]"
+ *: ""
</dest>
<voice>
- *: "Commentaar"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_COMPOSER
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Composer]"
+ *: ""
</source>
<dest>
- *: "[Componist]"
+ *: ""
</dest>
<voice>
- *: "Componist"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_YEAR
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Year]"
+ *: ""
</source>
<dest>
- *: "[Jaar]"
+ *: ""
</dest>
<voice>
- *: "Jaar"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_TRACKNUM
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Tracknum]"
+ *: ""
</source>
<dest>
- *: "[Tracknum]"
+ *: ""
</dest>
<voice>
- *: "Tracknummer"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_DISCNUM
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Discnum]"
+ *: ""
</source>
<dest>
- *: "[Schijfnum]"
+ *: ""
</dest>
<voice>
- *: "Schijfnummer"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_FREQUENCY
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Frequency]"
+ *: ""
</source>
<dest>
- *: "[Frequentie]"
+ *: ""
</dest>
<voice>
- *: "Frequentie"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_BITRATE
- desc: in properties plugin
+ desc: deprecated
user: core
<source>
- *: "[Bitrate]"
+ *: ""
</source>
<dest>
- *: "[Bitsnelheid]"
+ *: ""
</dest>
<voice>
- *: "Bitsnelheid"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -16120,3 +16105,222 @@
*: "Aflopend"
</voice>
</phrase>
+<phrase>
+ id: LANG_ALBUM_ART
+ desc: in Settings
+ user: core
+ <source>
+ *: "Album Art"
+ </source>
+ <dest>
+ *: "Albumhoezen"
+ </dest>
+ <voice>
+ *: "Albumhoezen"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PREFER_EMBEDDED
+ desc: in Settings
+ user: core
+ <source>
+ *: "Prefer Embedded"
+ </source>
+ <dest>
+ *: "Liever Ingesloten"
+ </dest>
+ <voice>
+ *: "Liever Ingesloten"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PREFER_IMAGE_FILE
+ desc: in Settings
+ user: core
+ <source>
+ *: "Prefer Image File"
+ </source>
+ <dest>
+ *: "Liever Afbeeldingsbestand"
+ </dest>
+ <voice>
+ *: "Liever Afbeeldingsbestand"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_FM_SYNC_RDS_TIME
+ desc: in radio screen and Settings
+ user: core
+ <source>
+ *: none
+ rds: "Sync RDS Time"
+ </source>
+ <dest>
+ *: none
+ rds: "RDS-tijd Synchroniseren"
+ </dest>
+ <voice>
+ *: none
+ rds: "RDS Tijd Synchroniseren"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SORT_ALBUMS_BY
+ desc: in Settings
+ user: core
+ <source>
+ *: "Sort albums by"
+ </source>
+ <dest>
+ *: "Sorteer albums op"
+ </dest>
+ <voice>
+ *: "Sorteer albums op"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ARTIST_PLUS_NAME
+ desc: in Settings
+ user: core
+ <source>
+ *: "Artist + Name"
+ </source>
+ <dest>
+ *: "Artiest + Naam"
+ </dest>
+ <voice>
+ *: "Artiest En Naam"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ARTIST_PLUS_YEAR
+ desc: in Settings
+ user: core
+ <source>
+ *: "Artist + Year"
+ </source>
+ <dest>
+ *: "Artiest + Jaar"
+ </dest>
+ <voice>
+ *: "Artiest En Jaar"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_YEAR_SORT_ORDER
+ desc: in Settings
+ user: core
+ <source>
+ *: "Year sort order"
+ </source>
+ <dest>
+ *: "Sorteervolgorde jaar"
+ </dest>
+ <voice>
+ *: "Sorteer volgorde jaar"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SHOW_YEAR_IN_ALBUM_TITLE
+ desc: in Settings
+ user: core
+ <source>
+ *: "Show year in album title"
+ </source>
+ <dest>
+ *: "Jaar in albumtitel weergeven"
+ </dest>
+ <voice>
+ *: "Jaar in albumtitel weergeven"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_WAIT_FOR_CACHE
+ desc: in Settings
+ user: core
+ <source>
+ *: "Cache needs to finish updating first!"
+ </source>
+ <dest>
+ *: "Cache moet eerst de update voltooien!"
+ </dest>
+ <voice>
+ *: "Cache moet eerst de update voltooien!"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_TRACK_INFO
+ desc: Track Info Title
+ user: core
+ <source>
+ *: "Track Info"
+ </source>
+ <dest>
+ *: "Nummer Info"
+ </dest>
+ <voice>
+ *: "Nummer Info"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY
+ desc: play selected file/directory, in playlist context menu
+ user: core
+ <source>
+ *: "Play"
+ </source>
+ <dest>
+ *: "Speel"
+ </dest>
+ <voice>
+ *: "Speel"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_SHUFFLED
+ desc: play selected files in shuffled order, in playlist context menu
+ user: core
+ <source>
+ *: "Play Shuffled"
+ </source>
+ <dest>
+ *: "Geschud Afspelen"
+ </dest>
+ <voice>
+ *: "Geschud Afspelen"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_KEEP_CURRENT_TRACK_ON_REPLACE
+ desc: used in the playlist settings menu
+ user: core
+ <source>
+ *: "Keep Current Track When Replacing Playlist"
+ </source>
+ <dest>
+ *: "Huidige Track Behouden bij het Vervangen van een Afspeellijst"
+ </dest>
+ <voice>
+ *: "Huidige Track Behouden bij het Vervangen van een Afspeellijst"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_CLEAR_SETTINGS_ON_HOLD
+ desc: in the system sub menu
+ user: core
+ <source>
+ *: none
+ clear_settings_on_hold,iriverh10: "Clear settings when reset button is held during startup"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Clear settings when hold switch is on during startup"
+ </source>
+ <dest>
+ *: none
+ clear_settings_on_hold,iriverh10: "Instellingen wissen wanneer de resetknop wordt ingedrukt tijdens het opstarten"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Instellingen wissen wanneer de houd-schakelaar aan staat tijdens het opstarten"
+ </dest>
+ <voice>
+ *: none
+ clear_settings_on_hold,iriverh10: "Instellingen wissen wanneer de resetknop wordt ingedrukt tijdens het opstarten"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Instellingen wissen wanneer de houd schakelaar aan staat tijdens het opstarten"
+ </voice>
+</phrase>
diff --git a/apps/lang/polski.lang b/apps/lang/polski.lang
index 4cef4ba59a..849566d60d 100644
--- a/apps/lang/polski.lang
+++ b/apps/lang/polski.lang
@@ -5330,19 +5330,17 @@
</phrase>
<phrase>
id: LANG_SET_AS_REC_DIR
- desc: used in the onplay menu to set a recording dir
+ desc: deprecated
user: core
<source>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</source>
<dest>
- *: none
- recording: "Ustaw jako katalog nagrywania"
+ *: ""
</dest>
<voice>
- *: none
- recording: "Ustaw jako katalog nagrywania"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -6044,18 +6042,21 @@
user: core
<source>
*: none
- multivolume: "HD1"
+ hibylinux: "USB:"
+ multivolume: "HD1:"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "mSD:"
xduoox3: "mSD2:"
</source>
<dest>
*: none
+ hibylinux: "USB:"
multivolume: "HD1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "mSD:"
xduoox3: "mSD2:"
</dest>
<voice>
*: none
+ hibylinux: "U S B"
multivolume: "ha de 1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "mikro es de"
xduoox3: "mikro es de 2"
@@ -6147,58 +6148,58 @@
</phrase>
<phrase>
id: LANG_INSERT
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert"
+ *: ""
</source>
<dest>
- *: "Wstaw"
+ *: ""
</dest>
<voice>
- *: "Wstaw"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_FIRST
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Next"
+ *: ""
</source>
<dest>
- *: "Wstaw następne"
+ *: ""
</dest>
<voice>
- *: "Wstaw następne"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_LAST
- desc: in onplay menu. append a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Last"
+ *: ""
</source>
<dest>
- *: "Wstaw ostatnie"
+ *: ""
</dest>
<voice>
- *: "Wstaw ostatnie"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_SHUFFLED
- desc: in onplay menu. insert a track/playlist randomly into dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Shuffled"
+ *: ""
</source>
<dest>
- *: "Wstaw losowo"
+ *: ""
</dest>
<voice>
- *: "Wstaw losowo"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -6371,16 +6372,16 @@
</phrase>
<phrase>
id: LANG_CATALOG_ADD_TO
- desc: in onplay playlist catalogue submenu
+ desc: deprecated
user: core
<source>
- *: "Add to Playlist"
+ *: ""
</source>
<dest>
- *: "Dołącz do listy"
+ *: ""
</dest>
<voice>
- *: "Dołącz do listy odtwarzania"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -10691,16 +10692,16 @@
</phrase>
<phrase>
id: LANG_INSERT_LAST_SHUFFLED
- desc: in onplay menu. insert a playlist randomly at end of dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Last Shuffled"
+ *: ""
</source>
<dest>
- *: "Wstaw losowo na koniec"
+ *: ""
</dest>
<voice>
- *: "Wstaw losowo na koniec"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11475,16 +11476,16 @@
</phrase>
<phrase>
id: LANG_SET_AS_START_DIR
- desc: used in the onplay menu to set a starting browser dir
+ desc: deprecated
user: core
<source>
- *: "Start File Browser Here"
+ *: ""
</source>
<dest>
- *: "Rozpocznij przeglądanie plików tutaj"
+ *: ""
</dest>
<voice>
- *: "Rozpocznij przeglądanie plików tutaj"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -11590,16 +11591,16 @@
</phrase>
<phrase>
id: LANG_SET_AS_PLAYLISTCAT_DIR
- desc: used in the onplay menu to set a playlist catalogue dir
+ desc: deprecated
user: core
<source>
- *: "Set As Playlist Catalogue Directory"
+ *: ""
</source>
<dest>
- *: "Ustaw jako katalog list odtwarzania"
+ *: ""
</dest>
<voice>
- *: "Ustaw jako katalog list odtwarzania"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -13299,16 +13300,16 @@
</phrase>
<phrase>
id: LANG_CLEAR_PLAYLIST
- desc: in the pictureflow main menu
+ desc: deprecated
user: core
<source>
- *: "Clear playlist"
+ *: ""
</source>
<dest>
- *: "Wyczyść listę odtwarzania"
+ *: ""
</dest>
<voice>
- *: "Wyczyść listę odtwarzania"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -14899,16 +14900,16 @@
</phrase>
<phrase>
id: LANG_DIRECT
- desc: in the pictureflow settings
+ desc: in the pictureflow settings, also a volume adjustment mode
user: core
<source>
*: "Direct"
</source>
<dest>
- *: "Bezpośrednie"
+ *: "Bezpośrednio"
</dest>
<voice>
- *: "Bezpośrednie"
+ *: "Bezpośrednio"
</voice>
</phrase>
<phrase>
@@ -16301,3 +16302,273 @@
*: "Zachowaj bieżący utwór podczas zastępowania listy odtwarzania"
</voice>
</phrase>
+<phrase>
+ id: LANG_CLEAR_SETTINGS_ON_HOLD
+ desc: in the system sub menu
+ user: core
+ <source>
+ *: none
+ clear_settings_on_hold,iriverh10: "Clear settings when reset button is held during startup"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Clear settings when hold switch is on during startup"
+ </source>
+ <dest>
+ *: none
+ clear_settings_on_hold,iriverh10: "Wyczyść ustawienia, gdy przycisk resetowania będzie przytrzymany podczas uruchamiania"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Wyczyść ustawienia, gdy przełącznik blokady będzie włączony podczas uruchamiania"
+ </dest>
+ <voice>
+ *: none
+ clear_settings_on_hold,iriverh10: "Wyczyść ustawienia, gdy przycisk resetowania będzie przytrzymany podczas uruchamiania"
+ ipod4g,ipodcolor,ipodmini1g,ipodmini2g,ipodnano1g,ipodvideo: "Wyczyść ustawienia, gdy przełącznik blokady będzie włączony podczas uruchamiania"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_REWIND_ACROSS_TRACKS
+ desc: in playback settings menu
+ user: core
+ <source>
+ *: "Rewind Across Tracks"
+ </source>
+ <dest>
+ *: "Przewiń poprzez utwory"
+ </dest>
+ <voice>
+ *: "Przewiń poprzez utwory"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SET_AS
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Set As..."
+ </source>
+ <dest>
+ *: "Ustaw jako..."
+ </dest>
+ <voice>
+ *: "Ustaw jako..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAYLIST_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Playlist Directory"
+ </source>
+ <dest>
+ *: "Katalog list odtwarzania"
+ </dest>
+ <voice>
+ *: "Katalog list odtwarzania"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_START_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Start Directory"
+ </source>
+ <dest>
+ *: "Katalog startowy"
+ </dest>
+ <voice>
+ *: "Katalog startowy"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_RECORDING_DIR
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: none
+ recording: "Recording Directory"
+ </source>
+ <dest>
+ *: none
+ recording: "Katalog nagrywania"
+ </dest>
+ <voice>
+ *: none
+ recording: "Katalog nagrywania"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_TO_PL
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add to Playlist..."
+ </source>
+ <dest>
+ *: "Dodaj do listy odtwarzania..."
+ </dest>
+ <voice>
+ *: "Dodaj do listy odtwarzania..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_TO_EXISTING_PL
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add to Existing Playlist"
+ </source>
+ <dest>
+ *: "Dodaj do istniejącej listy odtwarzania"
+ </dest>
+ <voice>
+ *: "Dodaj do istniejącej listy odtwarzania"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAYING_NEXT
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Playing Next..."
+ </source>
+ <dest>
+ *: "Odtwarzanie następnego..."
+ </dest>
+ <voice>
+ *: "Odtwarzanie następnego..."
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_NEXT
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Next"
+ </source>
+ <dest>
+ *: "Odtwórz następny"
+ </dest>
+ <voice>
+ *: "Odtwórz następny"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_ADD_SHUFFLED
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Add Shuffled"
+ </source>
+ <dest>
+ *: "Dodaj losowy"
+ </dest>
+ <voice>
+ *: "Dodaj losowy"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_LAST
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Last"
+ </source>
+ <dest>
+ *: "Odtwórz ostatni"
+ </dest>
+ <voice>
+ *: "Odtwórz ostatni"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PLAY_LAST_SHUFFLED
+ desc: used in the onplay menu
+ user: core
+ <source>
+ *: "Play Last Shuffled"
+ </source>
+ <dest>
+ *: "Odtwórz ostatni losowy"
+ </dest>
+ <voice>
+ *: "Odtwórz ostatni losowy"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_VOLUME_ADJUST_MODE
+ desc: in system settings
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Volume Adjustment Mode"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Tryb regulacji głośności"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Tryb regulacji głośności"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_VOLUME_ADJUST_NORM_STEPS
+ desc: in system settings
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Number of Volume Steps"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Liczba kroków głośności"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Liczba kroków głośności"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_PERCEPTUAL
+ desc: in system settings -> volume adjustment mode
+ user: core
+ <source>
+ *: none
+ perceptual_volume: "Perceptual"
+ </source>
+ <dest>
+ *: none
+ perceptual_volume: "Percepcyjny"
+ </dest>
+ <voice>
+ *: none
+ perceptual_volume: "Percepcyjny"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_SHOW_TRACKS_WHILE_BROWSING
+ desc: in PictureFlow Main Menu
+ user: core
+ <source>
+ *: "Show Tracks While Browsing"
+ </source>
+ <dest>
+ *: "Pokazuj utwory podczas przeglądania"
+ </dest>
+ <voice>
+ *: "Pokazuj utwory podczas przeglądania"
+ </voice>
+</phrase>
+<phrase>
+ id: LANG_GOTO_LAST_ALBUM
+ desc: in PictureFlow Main Menu
+ user: core
+ <source>
+ *: "Go to Last Album"
+ </source>
+ <dest>
+ *: "Przejdź do ostatniego albumu"
+ </dest>
+ <voice>
+ *: "Przejdź do ostatniego albumu"
+ </voice>
+</phrase>
diff --git a/apps/lang/srpski.lang b/apps/lang/srpski.lang
index 8e64e3f938..e9b97e9777 100644
--- a/apps/lang/srpski.lang
+++ b/apps/lang/srpski.lang
@@ -1476,7 +1476,7 @@
*: "Replaygain"
</dest>
<voice>
- *: "Replaygain"
+ *: "Риплејгејн"
</voice>
</phrase>
<phrase>
@@ -3386,7 +3386,7 @@
<voice>
*: none
battery_types: "Алкална"
- xduoox3: "Новија (2000 милиампер часова)"
+ xduoox3: "Новија двехиљаде милиампер часова"
</voice>
</phrase>
<phrase>
@@ -3406,7 +3406,7 @@
<voice>
*: none
battery_types: "Никл метал хидридна"
- xduoox3: "Старија (1500 милиампер часова)"
+ xduoox3: "Старија хиљадупетсто милиампер часова"
</voice>
</phrase>
<phrase>
@@ -4940,7 +4940,7 @@
</dest>
<voice>
*: none
- recording: "MPEG Layer 3"
+ recording: "Епмег лејер три"
</voice>
</phrase>
<phrase>
@@ -4957,7 +4957,7 @@
</dest>
<voice>
*: none
- recording: "PCM Wave"
+ recording: "пи си ем вејв"
</voice>
</phrase>
<phrase>
@@ -4974,7 +4974,7 @@
</dest>
<voice>
*: none
- recording: "WavPack"
+ recording: "вавпак"
</voice>
</phrase>
<phrase>
@@ -4991,7 +4991,7 @@
</dest>
<voice>
*: none
- recording: "AIFF"
+ recording: "еј ај еф еф"
</voice>
</phrase>
<phrase>
@@ -5305,19 +5305,19 @@
</phrase>
<phrase>
id: LANG_SET_AS_REC_DIR
- desc: used in the onplay menu to set a recording dir
+ desc: deprecated
user: core
<source>
*: none
- recording: "Set As Recording Directory"
+ recording: ""
</source>
<dest>
*: none
- recording: "Постави као директоријум за снимање"
+ recording: ""
</dest>
<voice>
*: none
- recording: "Постави као директоријум за снимање"
+ recording: ""
</voice>
</phrase>
<phrase>
@@ -6010,7 +6010,7 @@
<voice>
*: "Интерни"
hibylinux: "мајкро Ес Де"
- xduoox3: "мајкро Ес Де 1"
+ xduoox3: "мајкро Ес Де један"
</voice>
</phrase>
<phrase>
@@ -6031,9 +6031,9 @@
</dest>
<voice>
*: none
- multivolume: "Ха Де 1"
+ multivolume: "Ха Де један"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "мајкро Ес Де"
- xduoox3: "мајкро Ес Де 2"
+ xduoox3: "мајкро Ес Де два"
</voice>
</phrase>
<phrase>
@@ -6122,58 +6122,58 @@
</phrase>
<phrase>
id: LANG_INSERT
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert"
+ *: ""
</source>
<dest>
- *: "Уметни"
+ *: ""
</dest>
<voice>
- *: "Уметни"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_FIRST
- desc: in onplay menu. insert a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Next"
+ *: ""
</source>
<dest>
- *: "Уметни наредну"
+ *: ""
</dest>
<voice>
- *: "Уметни наредну"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_LAST
- desc: in onplay menu. append a track/playlist into dynamic playlist.
+ desc: deprecated
user: core
<source>
- *: "Insert Last"
+ *: ""
</source>
<dest>
- *: "Уметни последњу"
+ *: ""
</dest>
<voice>
- *: "Уметни последњу"
+ *: ""
</voice>
</phrase>
<phrase>
id: LANG_INSERT_SHUFFLED
- desc: in onplay menu. insert a track/playlist randomly into dynamic playlist
+ desc: deprecated
user: core
<source>
- *: "Insert Shuffled"
+ *: ""
</source>
<dest>
- *: "Уметни промешано"
+ *: ""
</dest>
<voice>
- *: "Уметни промешано"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -6346,16 +6346,16 @@
</phrase>
<phrase>
id: LANG_CATALOG_ADD_TO
- desc: in onplay playlist catalogue submenu
+ desc: deprecated
user: core
<source>
- *: "Add to Playlist"
+ *: ""
</source>
<dest>
- *: "Додај у плејлисту"
+ *: ""
</dest>
<voice>
- *: "Додај у плејлисту"
+ *: ""
</voice>
</phrase>
<phrase>
@@ -9581,7 +9581,7 @@
</dest>
<voice>
*: none
- recording: "величина"
+ recording: "Величина"
</voice>
</phrase>
<phrase>
@@ -9674,7 +9674,7 @@
</dest>
<voice>
*: none
- recording: "време дељења"
+ recording: "Време дељења"
</voice>
</phrase>
<phrase>
@@ -9705,7 +9705,7 @@
</dest>
<voice>
*: none
- recording: "клип"
+ recording: "КЛИП"
</voice>
</phrase>
<phrase>
@@ -9735,11 +9735,11 @@
</source>
<dest>
*: none
- recording: "Фајл:"
+ recording: "Име фајла:"
</dest>
<voice>
*: none
- recording: "фајл"
+ recording: "Име фајла"
</voice>
</phrase>
<phrase>
@@ -9797,7 +9797,7 @@
</source>
<dest>
*: none
- agc: "AGC"
+ agc: "АРП"
</dest>
<voice>
*: none