Compare commits

...

154 commits

Author SHA1 Message Date
Christian Soffke
f0d99391de plugins: random folder advance: misc improvements
fixes:
- traverse_dir was called recursively using two
  MAX_PATH local buffers => possible stack overflow
- The import function inserted additional, incorrect,
  entries when the whole line buffer was filled
- "Dirs not found" message overlapped number
  of folders when generating folder list
- Final number of scanned folders wasn't displayed
- Wouldn't stop inserting when maximum number
  of files in playlist was already reached
- Prevent buffer overflow when importing
- Don't write to fd after opening failed
- Use whole buffer with read_line, instead
  of subtracting 1. Remove hard coded sizes
- CRs don't need to be removed in import function
  (already handled by read_line)

features:
- Use insert context for *much* faster insertion
  of large # of folders, and nicer progress display
- Use UI viewport
- Add progress indicator when saving or loading
- Display number of folders in edit list title
- Go back to plugin's main menu from edit list
- Only ask to save changes if list is dirty
- Warn before erasing modified playlist
- Flag successfully created playlist as modified
- Make folder scan wait for dircache
- Shorten menu item names
- Put "Play Shuffled" menu item first
- Remember selection when returning from submenus
- Go to WPS after ACTION_TREE_WPS
- Exit menu when pressing Back
- Perform an initial scan, if no data file exists
  yet, when "Play Shuffled" or "Edit" is selected

Change-Id: I7df76f8fb8387888ce491d8b74b01b481e9997d3
2026-01-16 16:49:38 +01:00
Solomon Peachy
fcb2289274 voice: when building from vstrings targetid needs to come from within
Change-Id: I2a1c6a249523ec7a1d339e7b08f1686dad1d0270
2026-01-15 09:20:06 -05:00
Solomon Peachy
dd0d9549ab Fix red in 75edff7880 due to various bootloaders
Bootloaders don't have support for queue_peek or other advanced
queue functionality, so USB-enabled bootloaders can't play these games.

Change-Id: Ib807b57b84433e7a2ad019648a6c588ab424c6cd
2026-01-14 16:56:51 -05:00
mojyack
75edff7880 usb: fix random "null ctrl req" panic when switching usb config
Change-Id: I7839edb99461abfbff03460d63343691085ef34f
2026-01-14 16:23:07 -05:00
Christian Soffke
d395520cd0 fix yellow 2e9c2da
Eliminate static pointer

Change-Id: Id26363771439dbd1f08c661ae2ff4277e0e8f288
2026-01-14 17:49:42 +01:00
Christian Soffke
2e9c2dafb2 fix use of out-of-scope stack memory in 18dfd8f691
when calling do_menu recursively

Change-Id: I949cf1cedd80746a7e29b67804470365987046f3
2026-01-14 17:11:50 +01:00
Christian Soffke
c296c2781a fix regression 18dfd8f691
The WPS, or certain screens accessed directly from it,
may have displayed a title when they shouldn't have.

Change-Id: I655f58aa7c4ff3ff996d9798fdbe06c14f09c27b
2026-01-14 15:33:56 +01:00
Christian Soffke
4541c94292 metadata: vorbis: fix warning when building sim on aarch64 linux
b64_codes is unsigned on some systems unless explicitly
declared as signed.

"b64_codes[index] < 0 comparison is always false due
to limited range of data type [-Werror=type-limits]"

Introduced in 849e8ab

Change-Id: I6a86e898c2ed8995f7346060f9b9b58ea6ab1e95
2026-01-14 15:11:34 +01:00
Christian Soffke
58616e685d gui: yesno: don't force redraw when leaving screen
Change-Id: Ic37ee29318535952e9420c2f58e24bbb27183120
2026-01-13 20:07:03 -05:00
Christian Soffke
18dfd8f691 Reduce list title glitches when switching between menus
Each time viewportmanager_theme_enable (or _undo) is called,
the SBS title is reset, even if the theme remains enabled.
Thus switching from one menu to another, if do_menu is called
again, briefly results in an empty title before the correct
one is displayed. Even unchanged titles will unnecessarily
flash for a moment. Other theme elements that are drawn using
conditions based on the title, may also appear glitchy.

This patch adds a way to make the status bar title persist by
copying it to a static buffer. Persistent titles are not reset
by toggle_theme (although scrolling will be stopped in
viewportmanager_theme_undo), so that the theme can immediately
display the appropriate title in do_menu, simplelist_show_list,
the yesno screen, or plugins that want to keep the theme enabled.

Change-Id: I1ec8f233b730321793eb7d3cad51496ee1b35440
2026-01-13 20:06:33 -05:00
Christian Soffke
399230e9ec Use SBS title in delete confirmation screens
When deleting files or directories, you will now see
the path's basename in the previously empty title of
an SBS, making it a bit easier to immediately know
whether you've selected the correct item.

Matching titles were also added everywhere else that
confirm_delete_yesno is used.

The full path of the item is still displayed below,
and continues to scroll, so that themes without a
title, such as the default cabbiev2, will look the
same.

Change-Id: I32422cfbbf6e680f58456237380176617789cac3
2026-01-13 20:05:43 -05:00
Solomon Peachy
d1c3e3b08b Partial revert of 04c45933e
mmc_sleepnow() was accidentally removed from the imx233 sdmmc code,
causing the sansa fuze+ build to fail.

Change-Id: I935f7f4fe99e7353a84dc26e81d85ee55afa0de3
2026-01-13 19:42:34 -05:00
Solomon Peachy
7518b8c309 debug: only show usb_charging_maxcurrent() if HAVE_USBSTACK is defined.
HAVE_USB_CHARGING_ENABLE isn't enough, as the ihp3xx targets have an odd
combination of USB charging but rely on an external ATA bridge.

Change-Id: I2cba5f218971ac23cde8dca34faa06bbb44a2448
2026-01-13 19:28:54 -05:00
Solomon Peachy
4850684149 Fix red introduced in 41d5ca3c48
Later GCC versions are apparently more permissive than older versions
when it comes to variable declarations not part of a block (ie {} that
immediately follows a case statement.

This resulted in every non-simulator device target failing to build,
along with sim build on older compilers.  I should have caught this in
the review; mea culpa.

Change-Id: Id32e085e34601cca7be273ed45711a4b8ee182a0
2026-01-13 17:28:36 -05:00
Aidan MacDonald
bc32d43c17 echoplayer: add charger detection and USB current limit setting
Note that USB current limiting is more or less wishful
thinking; only the charge current is limited, but the
system could easily draw more than 100 mA by itself.

Change-Id: I1083b015f0abea5a39a602ca8d7b142d3613b46b
2026-01-13 17:00:12 -05:00
Aidan MacDonald
cd20bc7d16 debug_menu: show USB charging current limit on battery screen
Change-Id: I5cbcdba5724616e85cde1cf9e422c8ccdb34592b
2026-01-13 17:00:00 -05:00
Aidan MacDonald
350e2b9b02 firmware: add missing 'void' in usb_charging_maxcurrent() definition
Change-Id: I5d1dbb9176160ae98a8ab20ac3436610cf8b805d
2026-01-13 16:59:49 -05:00
Aidan MacDonald
04c45933e8 firmware: get rid of unused "xxx_sleep()" storage driver function
storage_sleepnow() is the one that is actually implemented
by storage drivers. storage_sleep() sends a Q_STORAGE_SLEEP
event to the storage thread, which will normally end up
calling the driver's sleepnow() function.

Change-Id: Ib6523073348431dcc75c0f10ef99060c6960efd8
2026-01-13 16:59:39 -05:00
Arin Kim
41d5ca3c48 skin: add new %pP tag (playlist progress as percentage)
This new tag returns the position in the playlist as a percent. The main usecase for this is to use it as a bar tag, allowing themes to visually present playlist progress.

Change-Id: I0eb001e7458d97b8a0db39f3980d9c283bc8806b
2026-01-13 16:59:00 -05:00
Solomon Peachy
1c429e2209 settings: double internal size of "path list" from 80 to 160 bytes
* Autoresume path list
 * Database scan path list

Gives us a bit more headroom

Change-Id: Icb78d6f46dd39658334ddc3d8dc44863b0e138b4
2026-01-13 15:07:22 -05:00
Aidan MacDonald
450687bc3d stm32h743: fix incorrectly defined SRAM3 size
Change-Id: Ia31e22fb2c6e7becf380abf440b03a73ec383582
2026-01-13 13:42:51 -05:00
Aidan MacDonald
adb5e2e44f arm: handle unaligned addresses in Cortex-M cache ops
For commit-type operations it's useful to be able to pass
unaligned addresses, so round the address/size to ensure
all cache lines in the address range are hit.

Change-Id: Ibb23050ecf11b6ef6ab1dd517990a68ef62ecfa9
2026-01-13 16:20:45 +00:00
Solomon Peachy
74d86ab965 manual: Document the 'database scan paths' setting
Change-Id: I3a6505655461c13fac4f2246277b811757bdd180
2026-01-13 07:55:04 -05:00
Solomon Peachy
d9289e7f5c rbutil: Use lang-enum.txt in voicestrings.zip if present
With this change, the code that looks for the VOICE_INVALID_VOICE_FILE
and VOICE_LANG_NAME to produce standalone clips will finally work.

Change-Id: I65ec592a1d3a6c83f92efadec72657c42552b41a
2026-01-12 20:22:43 -05:00
Aidan MacDonald
55f2e2d5d5 echoplayer: fix incorrect loop bounds in lcd_update_rect()
Change-Id: I96b3d235db4a988374967131caba0344c655e5d3
2026-01-12 19:41:08 -05:00
mojyack
c41242615e usb: designware: allow maxpktsize >= 1024
Change-Id: I25a1bc2be8e5b4028a360d80411d4e0182a50c99
2026-01-12 17:00:23 -05:00
mojyack
3dff77460d usb: arc: fix unable to receive 64 bytes long control packet
by adding QH_ZLT_SEL to control endpoints

Change-Id: I27ccf6a6db302688f1df2e6fd1d3fe98c20323cf
2026-01-12 16:59:34 -05:00
mojyack
1319426749 usb: hid: move hid definitions to usb_hid_def.h
Change-Id: I5883d27b96dcedfc0d0149961228a170b8d8e744
2026-01-12 16:57:36 -05:00
Aidan MacDonald
97dce282b4 echoplayer: add USB support
Enable high speed USB for the Echo R1. Includes reasonably
complete support for full speed USB on the STM32H743 since
that was necessary to debug why it wasn't working at first
(which turned out to be a bug in memcpy, not a hardware or
driver issue).

Change-Id: Ie713195b22ba88c79b9b0d6eb289cb9ccd2763c2
2026-01-12 19:13:23 +00:00
Aidan MacDonald
671320b5d1 echoplayer: implement basic power-on / power-off logic
Use cpu_power_on as a GPIO to keep the main power supply
enabled when running from battery.

Change-Id: Ic79283a0cc640585a0297e11f9dcc2264ec9af26
2026-01-12 13:01:35 -05:00
Aidan MacDonald
e29780fe09 firmware: fix thread_exit handling on ARM Cortex-M
The "mov lr, pc" instruction doesn't link a proper return
address in Thumb mode: bit 0 will be unset, leading to a
UsageFault exception when returning from the thread's main
function.

Cortex-M has the "blx" instruction to automatically branch
and link the correct return address, so use that.

Change-Id: I4c0ca55b1b2204286343f906f0b53be0c0ddc392
2026-01-12 15:37:29 +00:00
Aidan MacDonald
af4ff3e270 firmware: split ARM classic & Cortex-M thread implementations
The implementations diverge enough that it is too confusing
to support them in the same source file; split them so it
is easier to understand.

Change-Id: Ic2f91c75e8a9bb605241441f2caed841585f5b87
2026-01-12 15:37:27 +00:00
Solomon Peachy
2db798ff6d FS#13755: Updated Moldavian and Romanian translations (Mihai Alexandru Vasiliu)
Change-Id: I631393e17de68ea80e5f9b7ccc8793d1273b07d5
2026-01-12 08:26:16 -05:00
Nyx Guan
b9089640a3 Add Nyx Guan to CREDITS
Change-Id: I23245e46c3ab0173da513a483724ce51819fdaca
2026-01-10 21:31:49 -05:00
Aidan MacDonald
d15ccd771d echoplayer: add function to enable 1V8 regulator
This supply is shared by the USB PHY and the audio codec,
so it needs to be reference counted to allow them to be
powered up & down independently (and not just leave the
1V8 regulator enabled all the time).

Change-Id: Ib99b41c2a94b9f0c378153b33c6f91b4370ee998
2026-01-10 21:29:23 +00:00
Aidan MacDonald
80e1c2b27e usb-designware: allow setting USB speed in DCFG register
This allows targets to select full speed operation instead
of the default high-speed mode, which is mainly interesting
for debugging USB communication.

Change-Id: I405ff63c6660ca03ea04282a12b59dac06ca46f5
2026-01-10 21:29:23 +00:00
Aidan MacDonald
5dd2756b14 usb-designware: allow setting FDMOD bit to force device mode
If the PHY doesn't correctly report the ID pin state,
then the DWC2 core may operate in host mode by default.

Defining USB_DW_FORCE_DEVICE_MODE in the target config
will set the FDMOD bit in the GUSBCFG register to force
the core into device mode regardless of what the PHY
reports.

Change-Id: If2391aaa4a7c65ba6c90dd56074faeb3ed1ac2ca
2026-01-10 21:29:10 +00:00
Aidan MacDonald
361cd46a08 usb-designware: fix incorrect cache discard with DMA disabled
Two cache discards for targets with POST_DMA_FLUSH were
not properly guarded by USB_DW_ARCH_SLAVE, which causes
data loss when DMA is disabled.

Change-Id: If14ffdc5662f77b3ff57a04c5b9f94d4cac7e514
2026-01-10 21:28:01 +00:00
Aidan MacDonald
047871c58a stm32h7: detect unsupported SDMMC transfers to ITCM
Change-Id: I4916829155d334148bf9683a9a66a125ef90a1f4
2026-01-10 10:06:57 -05:00
Christian Soffke
3da69af83c font: logf: fix pointer in buflibmove_callback
Buffer contents are only moved after the callback
returns, so we need to log the path before it has
been updated to prevent reading garbage.

Change-Id: I187fbd56484249c456155ffcbdde9e44e766dde8
2026-01-10 07:11:51 +01:00
Mauricio Garrido
752467dee4 3ds: Various fixes, optimizations.
This commit does the following changes:

- Fix mkdir implementation not reporting EEXIST error.
- Fix database build feature.
- Small speed-up when parsing directories and files.
- Fix buffering thread hogging cpu and preventing other threads to run.
- Fix sdl plugins not compiling by re-adding ctru specific cflags in sdl.make.

Change-Id: I507c0dcc85cdbcc607ab9c9c6d0b42e6a80caa5a
2026-01-09 20:54:44 -05:00
Solomon Peachy
0777add596 voice: Support generating voice files from contents of voicestrings.zip
Every build includes .rockbox/lang/voicestrings.zip, which contains
everything needed to build a voice file for that build.

This is already used by the rockbox utility, but now it is possible to
achieve the same using purely cmdline tools.

If the new voice-enum.txt file is present in the voicestrings.zip file,
this new flow produces bit-for-bit identical voice as the existing 'make
voice' flow.

Change-Id: Ieb24bc261a75b0e531c1889c49402217f7d14302
2026-01-09 20:50:09 -05:00
Solomon Peachy
0abfb3ff78 voice: Include a simple string enumeration in voicestrings.zip
This maps the numerical IDs contained within the binary .vstrings files
to their logical LANG_* and VOICE_* names.

While not strictly needed to produce voice files, it adds the final
piece to be able to use vstrings files to produce the same voice files
as the existing 'make voice' flow that directly parses the language files.

The 'make voice' flow intentionally divert a few of the generated clips
into standalone files:

 * "invalid voice file"
 * <spoken language name>
 * <short pause>

For this to be possible, we need to know which specific entries in
vstrings map to the ones we care about, and without this enumeration
(which can change on a per-target or even per-build basis) this is
effectively impossible.

The produced lang-enum.txt is simple, with one entry per line of the
format: number:name

Note that nothing uses this new file yet; that will come in subsequent
commits.

Change-Id: Iec3fccbb6d503dd7e2d529aad318009a489b1d77
2026-01-09 20:47:34 -05:00
William Wilgus
032a38df4e lua -- remove direct rb-> libc calls infavor of macro substitution WIP
there are no functional changes in this patch
it just makes it easier to build lua in core app
or plugin form

-Update moved some things around messing up compilation on Native targets
due to *errno

Change-Id: I0921df62d72a87516ad95c68e986b5931c35345e
2026-01-08 22:32:23 -05:00
William Wilgus
ded29fd751 lua plugin remove strfrtime in favor of strfrtm.lua
saves 2.2k on the bin

also supplies gmtime, and a test script to check the returned time/dates

Change-Id: Ib83b11d89bdf44a50830ff51c72ac6395b675603
2026-01-08 21:39:54 -05:00
Sebastian Leonhardt
873163c671 iMX233 RTC init: make clock source (32kHz/24MHz) explicit for targets
Change-Id: Ib4fa56ad8ee28f3799b6c6c3c058d156353dd15c
2026-01-08 13:48:44 -05:00
Aidan MacDonald
2f2b90535a firmware: use C versions of memcpy and memmove for ARM Cortex-M
The ARM assembly versions of memcpy and memmove try to
directly modify the PC based on the number of bytes to
be copied as an "optimization"; but this only works if
instructions are guaranteed to be 4 bytes wide.

This trick is completely broken on Cortex-M, since an
instruction can be 2-4 bytes wide: for example a memcpy
of 4 bytes ends up storing 32 bytes worth of garbage to
the target address!

Use the C memcpy/memmove implementations for Cortex-M
instead; fixing the ASM version is more trouble than
it's worth.

Change-Id: I695587fd585ec25ef276f2dbc61e2290b7015e13
2026-01-08 16:41:59 +00:00
Aidan MacDonald
6f4b6a8078 make: remove asm.make and use asm/SOURCES directly
asm.make replaces source files listed in asm/SOURCES with
a corresponding .c or .S file under firmware/asm/${ARCH}.
This makes it difficult to handle differences within one
architecture, eg. different instruction sets or versions
of the architecture.

Get rid of asm.make, and instead use the preprocessor to
select the architecture-specific sources directly from
asm/SOURCES. This is slightly more verbose but is more
flexible.

Change-Id: Id2a484794d5d951b7ba7b54a552de6960414fa45
2026-01-08 16:41:57 +00:00
Vencislav Atanasov
e2196c4566 Run the LBA48 check only if the target has support for reading of SysCfg
This fixes a regression introduced in ad6cc2f0 for the ipodnano4g bootloader.

Change-Id: Iacf079adbfa85399b248a4c4ac35b93155a1d87b
2026-01-08 10:12:57 -05:00
Vencislav Atanasov
e3372f495e Add a dummy nand_get_info for ipodnano3g and ipodnano4g
All non-simulator and non-hostfs targets are required to implement storage_get_info() since 04dc052a

Change-Id: I87febd12e101797d9cbbffc0e2e46efc2dace9da
2026-01-08 10:12:51 -05:00
Solomon Peachy
98a182a19f genlang: More fixes
* "english.list" started the VOICE_* enumeration at the wrong number
 * vstrings file had the wrong string count

There is still one remaining issue; Currently the vstrings header is
generated with a section size that is consistently 6 bytes shorter than
the actual data. However, the non-voice .lng file has correct size.

Change-Id: I01f9622399cf3f3ac4c62ddea1deeb19a7b028ba
2026-01-08 09:35:12 -05:00
Solomon Peachy
24220d13e5 genlang: Correct the 'size' in the binary vstrings sub-header
It was only taking into account LANG_* strings, and ignoring VOICE_*

Fortunately rbutil currently ignores this field as it's not needed.

Change-Id: If58230cd047abe7a80ebab7eca9147e510b034ea
2026-01-06 23:09:49 -05:00
Aidan MacDonald
1f39ae52e3 codecs: fix compile error on ARM Cortex-M DEBUG app builds
Some of the inline assembly generates "impossible constraint"
errors in this function, but only when DEBUG is enabled.

Change-Id: I3b1135a8a55436bd3068ef560ebcef64a5184a05
2026-01-05 15:33:16 -05:00
Aidan MacDonald
e6e56ceb51 firmware: make lc_open_from_mem() optional
Define HAVE_LC_OPEN_FROM_MEM if the target implements
lc_open_from_mem(). Make HAVE_CODEC_BUFFERING depend
on this feature.

Change-Id: If5f70db58963dcdc33848b860c028841ac380ab2
2026-01-05 13:42:52 -05:00
Aidan MacDonald
cb2b2a5021 simulator: remove lc_open_from_mem() implementation
This was not actually used in practice because codec
buffering was switched off in playback.c.

Change-Id: Ic337db4a6f20972fe8a6480e7b182b5857294e9b
2026-01-05 13:42:52 -05:00
Aidan MacDonald
d791d26b6b apps: remove lc_open_from_mem() from plugin API
No plugin uses it and it doesn't work on hosted targets,
which limits its utility.

Change-Id: I5f29eec4dd11ffceb7be3e4d26e536483058055f
2026-01-05 13:42:23 -05:00
Aidan MacDonald
3d281c2ea3 apps: cleanly disable codec buffering when not supported
Move HAVE_CODEC_BUFFERING to config.h, and disable all
related code on targets that don't support the feature,
ie. hosted targets that can't implement lc_open_from_mem().

Change-Id: I0d2a43900cd05b1a80c3cee519f8ad7b26e39fe7
2026-01-05 13:15:49 -05:00
Aidan MacDonald
3d0888875e firmware: introduce CONFIG_BINFMT
Add CONFIG_BINFMT to select the binary format used for
plugins/codecs and define two options for the existing
implementations (native ".rock" format or dlopen-based).

Split the load_code.h header into two separate headers
to make it look less messy.

Change-Id: Ibd66773160df35a8c6f29a617d12c961bdabf317
2026-01-05 13:14:30 -05:00
Hairo R. Carela
8b6491db57 rbutil: fix stray rbutil.log creation when using a suffix
When instaling rockbox rbutil.log was still created in /sdcard/.rockbox

Change-Id: Iea987623a206d8c8f663e8ef0ee26a103ccc285f
2026-01-05 11:54:27 -04:00
Nyx Guan
012245c51f tagtree/tagcache add new clause operator contains_oneof
new operators @~, *~
contains_oneof and not_contains_oneof

genre @~ "metal|core"
black metal, death metal, grindcore, mathcore

genre ~ "jazz" & genre *~ "rock|pop|fusion"
included: jazz, free jazz, cool jazz, etc.
excluded: jazz rock, jazz pop, jazz fusion

Change-Id: If9590c8607b58373a98f5c9ea537f54df78d5a2f
2026-01-04 22:55:40 -05:00
Solomon Peachy
b31becd4bc lang: Actually remove the deleted translations from SOURCES
Change-Id: I3cca83c2c999cbd99361606ef3fafc341d5b1395
2026-01-04 17:43:41 -05:00
Solomon Peachy
87f135b349 Retire the Afrikaans and Walliser German "translations"
They have not been touched in over 20 years, and have effectively
bitrotted to the point where they are effectively untranslated.

Any interest in these translations would have to effectively start from
scratch anyway, so let's stop pretending the status quo is useful.

Change-Id: I13e1ae920883f5babb232f0592076be24c8122d4
2026-01-04 17:25:51 -05:00
Solomon Peachy
2c30a6e243 voice: Switch default Turkish Piper TTS voice from fettah to dfki
The former was removed from the upstream repositories "at the request of
contributors", leaving only the latter.

Change-Id: I4afe827be9037915d6d13b4d7ec0713509b88da3
2026-01-04 17:24:53 -05:00
Aidan MacDonald
2e532129d7 echoplayer: add storage & RTC demo in bootloader
Change-Id: I146e2205182239ed9d0176c23e3d0ad05e72a3be
2026-01-04 10:27:30 -05:00
Aidan MacDonald
6a8989f347 echoplayer: enable SD card using sdmmc_host
Enable pullups on SDMMC CMD/DATx lines and set output
speed to medium. Using HIGH and VERYHIGH speeds seems
to cause data corruption, with frequent CRC failures.

Change-Id: I732d19e03a2a857453755b68b6749497eafaef70
2026-01-04 10:27:15 -05:00
Aidan MacDonald
141b4a223f stm32h7: implement sdmmc_host-based SDMMC controller driver
Change-Id: I26c47c630ea364de043a224b549d7867fb1e5794
2026-01-04 09:31:05 -05:00
Aidan MacDonald
38db211a48 stm32h743: add SDMMC registers and RCC_AHB3RSTR register
Change-Id: I134a10e4b9116b85ec4327cc76c539c8340973cf
2026-01-04 09:31:05 -05:00
Aidan MacDonald
ed1f34af75 system: add membarrier() function for compiler memory barrier
Change-Id: I27be9b635bdabee523e56dd0c2245812cb7647eb
2026-01-04 09:08:22 -05:00
Aidan MacDonald
87bf6b4ebb firmware: add sdmmc_host storage driver
sdmmc_host is a portable driver for targets with SD/MMC
storage. It handles all the logic needed to initialize
and access SD/MMC devices which is common to all targets.

Targets only need to implement functions to issue SD/MMC
commands, manage clocks & power, and managing the insert
state of the card (if it is hotswappable). This vastly
reduces the work needed to get a new SD/MMC based target
up & running.

At present it's only written for and tested with SD cards,
as I don't have access to an MMC-based target to test on.

Change-Id: I6a0d7747113c11a3697ae20cbb551bef8bfd1292
2026-01-04 09:07:06 -05:00
Solomon Peachy
385483d6c5 manual: Don't lead a paragraph with '\\'
(Turns out that tex4ht is a lot pickier than latex)

Change-Id: I4fa320a14ca6fd136fb8abc31120ebecb17a23e3
2026-01-03 23:18:53 -05:00
Marc Aarts
1f97ae73a5 Use user preferred touchscreen mode in 'Main Menu Config' plugin instead of defaulting to 'button' mode.
Motivation:

1. 'Absolute point' mode works fine in this plugin.
2. This plugin is part of the Rockbox menus. If the user setting is not 'button' mode, it is unexpected to have only this menu work in a different mode compared to all other menus.

Change-Id: Iec91d3cd875e8a80e835a4a58d87a6ec84529def
2026-01-03 20:25:13 -05:00
Sebastian Leonhardt
a0bd48bfd7 Creative ZENV: fix keymap
(remove overlooked reference to BUTTON_MENU)


Change-Id: I63e8f19726dc04c57e45fa4ad704fe83951ed987
2026-01-03 20:03:24 -05:00
Hairo R. Carela
d695c3b95b rgnano: rbutil support and manual updates
Needs some testing in windows but except for uninstalling everything should work.

Change-Id: I55691d4cae9b37921f08177edaadc88854fef948
2026-01-03 20:03:12 -05:00
mojyack
e3bb80384d usb: do not call usb_core_do_set_config(0) inside bus reset isr
Change-Id: Ic06719ef92cd1fae42c7155ab72029466826a59b
2026-01-03 19:58:38 -05:00
mojyack
6db1e937e9 usb: set config to 0 on bus reset and exit
Change-Id: I4ee0e33f031388d17b30bbe591fe9b7d6386e940
2026-01-03 19:58:07 -05:00
mojyack
03fbd2784d usb: preparation to support multiple usb configs
- existing class drivers are placed to config 1
- drivers_connected==true is replaced with usb_config!=0
- supports config transition between nonzero configs
- STALL if request set_config was invalid

Change-Id: Ia775ae2dcb7d0cc08d2f3ee5ca41683837b04259
2026-01-03 19:57:33 -05:00
Aidan MacDonald
ea49358cc6 playlist: fix missing cleanup on OOM in playlist_resume()
Introduced by 3892773bd7, my fault for hitting merge
too quickly...

Change-Id: I18bbc3259a67664753a608a0175c59ee5a4241e0
2026-01-04 00:05:16 +00:00
mojyack
3892773bd7 playlist: fix deadlock when calling playlist_restore() on certain timing
for example:
<audio> audio_thread
<audio> -audio_playback_handler
<audio> --audio_start_playback
<audio> ---audio_fill_file_buffer
<audio> ----playlist_peek
<main>  -playlist_resume { playlist_write_lock(playlist) }
<main>  --alloc_tempbuf
<main>  ---core_alloc_ex
<main>  ----buflib_alloc_ex
<main>  -----buflib_compact_and_shrink
<main>  ------playback.c:shrink_callback
<main>  -------audio_queue_send(Q_AUDIO_STOP)
<main>  (waiting for audio queue reply)
<audio> -----get_track_filename { playlist_write_lock(playlist) }
<audio> (waiting for playlist lock)

resolve this by not locking playlist until temporary buffer is allocated

Change-Id: I55a856780d17455b13e2515e096095ae0e9c86c2
2026-01-03 18:56:57 -05:00
Solomon Peachy
ef47ffe250 Fix the last of the issues introduced in 350a2250b
Change-Id: I4b58f5d9d1c4649080826a9cf1b438e13ed7ce81
2026-01-03 14:42:54 -05:00
Solomon Peachy
247d2020fa Mechanical correction for Ukrainian translation
Change-Id: Iaf1476e81c6145cd33ec35267027cb172732f5a5
2026-01-03 14:03:57 -05:00
Solomon Peachy
ae1bcbf913 FS#13743 - Small fix for Ukrainian translation (Pavlo Rudy)
Change-Id: I250bd30cfceaf7c210626c18697ede2ccd90d5bd
2026-01-03 14:02:08 -05:00
Solomon Peachy
5bbd4d63f0 Fix build errors+warnings introduced in 350a2250b1
Change-Id: Ia5f2079ccc99da30e0058b0d9ce5bb8369201804
2026-01-03 13:59:53 -05:00
mojyack
eccce5b267 docs: add myself to CREDITS and COMMITTERS
Change-Id: I8d4d29a9bdd7d6eb75d4240e6aebc026aa959e2b
2026-01-03 13:30:08 -05:00
mojyack
350a2250b1 usb: implement endpoint allocation
this commit has following changes:
- introduce `usb_drv_ep_spec` table to udc drivers, which represents
  endpoint characteristics.
- introduce 'ep_allocs' table to class drivers, which represents what
  endpoint type does the class driver want.
- implement endpoint matching logic to usb core.

this is a required step to implement usb config switching, because we
need to create config descriptors without actually initializing endpoints.

Change-Id: I11c324cd35189ab636744488f6259d0cdb2179f0
2026-01-03 13:23:53 -05:00
Hairo R. Carela
f13f80c506 rbutil: more path suffix support
This commit adds suffix support for some missing components:
- Info widget
- Voice/talk files generation
- Backup
- Uninstall

Also fixes a crash in the uninstall window when there's no bootloader to select.

Change-Id: Ie97505a8cbd12dddf160bdebae2c04e738c373e5
2026-01-02 22:41:03 -05:00
Solomon Peachy
8aec8ee686 configure: Filter out "-Wl,-z,noexecstack" for winsim builds
Change-Id: I0222627729fbd475dfa7f4955b534f76ca780ccf
2026-01-02 07:51:44 -05:00
Aidan MacDonald
20d31c114a arm: use optimized find_first_set_bit() on Cortex-M
Use the optimized version based on __buitlin_ctz() which GCC
will compile to two instructions (rbit, ctz) on Cortex-M4/M7;
faster and smaller than the handcoded assembly version.

Change-Id: I33f69ff829b048f1e53fc7ead1bd6ac3c5bd7a4c
2026-01-01 11:25:43 -05:00
Aidan MacDonald
4ceb9e22d6 echoplayer: drive LCD parallel bus using STM32 LTDC
This is much, much faster than using SPI and is able to
offload the CPU completely.

Change-Id: Ia4c0289775296fe41d594ba849bd057e8482306e
2026-01-01 11:16:23 -05:00
Aidan MacDonald
e98dc7936c stm32h743: add LCD-TFT controller registers
Change-Id: Icefbe3c7f10a38c424105586b0bccf6941972cb1
2026-01-01 11:16:23 -05:00
Aidan MacDonald
801f386d9d stm32h743: add AXI GPV registers
Change-Id: Ie048e60701405e9aeafa6aa066cd88b3354e11c2
2026-01-01 11:16:23 -05:00
Aidan MacDonald
ddb2dfa267 stm32h7: simplify bootloader linker scripts
Remove ifdefs for load to RAM, it won't be usable once
the bootloader is able to load Rockbox.

Change-Id: Ia0c9261d2073261f4089ce1804d7a3483c959d6e
2026-01-01 11:15:14 -05:00
Aidan MacDonald
5137ef49e3 stm32h7: support setting bus frequency in SPI driver
Change-Id: I71edf28fdc24d8a00d27aa727815f99e788b675a
2026-01-01 09:17:17 -05:00
Aidan MacDonald
a4b0af2a44 stm32h7: add function to get frequency of a clock
Change-Id: Ice60bc0e443a134ebb8ec03015fef98991ef9b05
2026-01-01 09:17:17 -05:00
Aidan MacDonald
a9b75fc4c4 stm32h7: support clock enable/disable in SPI driver
Change-Id: Id4baa340e1b67fb265628add9191acb08e3a0615
2026-01-01 09:17:17 -05:00
Aidan MacDonald
ddb3bb354c stm32h7: add clock enable/disable callbacks
Change-Id: I4c135ba9cbed2c8e607c5f191bb9d82638f9b6b3
2026-01-01 09:15:56 -05:00
Aidan MacDonald
23448a13d1 stm32h7: refactor clock init to target-specific callback
Given the myriad of clocking options the STM32H7 family
provides, it is easiest to let targets simply implement
what they need.

Change-Id: I9cceed40a2d638998e8b583651f73557d2ffbd46
2026-01-01 09:15:56 -05:00
Aidan MacDonald
37b90baa5f stm32h7: handle SPI transfers via interrupts
Change-Id: I6e60f4222f4d99019e72377de7c3b689a77ac548
2025-12-31 22:03:51 -05:00
Aidan MacDonald
7eed19dbaa stm32h743: add NVIC IRQ numbers
Change-Id: If50655268180f38ed4114c35779d32f25a3631b5
2025-12-31 22:03:51 -05:00
Aidan MacDonald
b0b4c6bf2f stm32h743: split SPI IRQ handlers
No sense in pessimizing this; each SPI instance has a dedicated
interrupt line.

Change-Id: I2243626c960873738e5d9cf4e60d2f9e635514e7
2025-12-31 22:03:51 -05:00
Aidan MacDonald
8d279aa48d stm32h7: simplify generic SPI driver
Supporting large transfers (>64k) isn't really needed;
the main use case right now is interfacing with an LCD
controller.

Change-Id: I901e5ddb1b4efa9aa650b3e5074537ba785c6d41
2025-12-31 21:15:43 -05:00
Mauricio Garrido
09a31fff91 3ds: Enable plugins for the 3ds platform.
This commit enables plugins for the 3ds platform.
And adds 3ds specific pad configurations for each plugin.

Change-Id: Ie28fef4da32ed4cd2caa6c9fa3b2fe312ee009ef
2025-12-31 21:13:34 -05:00
Roman Artiukhin
7d067ca798 imageviewer: jpegp: improve downscale quality
Use simple area-averaging for smoother images.

Change-Id: I7ac2db05262500041286404c97a615e4b3a43194
2025-12-31 21:11:51 -05:00
Hairo R. Carela
64e0ced696 rbutil: path suffix support for devices with non-standard paths
Only for themes, fonts and voice files, includes rgnano implementation to test (can be in its own commit if needed, with the required manual updates and changes to install rockbox itself with rbutil).

Change-Id: I2481e6a3224912a298cf4c86011226e466490e08
2025-12-31 21:11:10 -05:00
Aidan MacDonald
7418e65138 echoplayer: add 'debug' and 'flash' targets to makefile
This replaces the gdb & openocd config in utils/stm32tools
and is easier to use. Remove the srst workaround; it seems
this was caused by the D1/D3 domains not being powered up
while the CPU was in sleep mode.

Change-Id: I28cc0273b3004c6e3146bb2447f0655cad8bb1c2
2025-12-31 08:10:40 -05:00
Aidan MacDonald
025f3def04 stm32h743: make debugger attach more reliable
Add an optional sequence in the startup code to disable clock
gating when the CPU goes to sleep. Normally the D1 and D3 domain
clocks can be automatically gated when the CPU is asleep, and
because the debug infrastructure is clocked from these domains,
the debugger cannot attach when those clocks are stopped.

Setting some bits in DBGMCU_CR prevents this problem, but will
increase power consumption, hence it isn't enabled by default.

Change-Id: Iba87750371a493adf72655aab86a908ef2702cef
2025-12-31 08:10:20 -05:00
Aidan MacDonald
4b9b2c510e stm32h743: add DBGMCU registers
Change-Id: I47aecaad9a6c0fc0f8c4d2807585909b4bb5d7d6
2025-12-31 07:30:00 -05:00
Aidan MacDonald
8514c1c9a8 echoplayer: convert STM32H7 register access to RegGen
Change-Id: Ie16d7340a9f047e44cf510bc776030570edb3966
2025-12-31 07:30:00 -05:00
Aidan MacDonald
d8b0bc5797 firmware: convert ARM Cortex-M register access to RegGen
Change-Id: I225fb53da84946876d6c4af08af5f80197e71e95
2025-12-31 07:30:00 -05:00
Solomon Peachy
cc9ce232ab Translation updates:
* Latvian (Renalds Belaks)
 * Hungarian (Gyúróczki Norbert)

Change-Id: I85b15a925000ac5f8e63b368a7d0938224693a6c
2025-12-31 06:58:48 -05:00
Solomon Peachy
a8ff5597bd FS#13739: Updated Vietnamese Translation (Chu Khanh Hanh)
Change-Id: I5bc0086e9a6c144203456dcd5652e3dd1e9f8bda
2025-12-30 23:18:04 -05:00
Mauricio Garrido
0b3e0d1432 3ds: Small changes to port sources.
This commit does the following changes:

- Replace buffered io implementation with a simpler, lighter, slightly faster version.
- Turn off both screens when backlight goes off.
- Small change to enable plugins in the folling commit (s).

Change-Id: I45df30be037c3a1686bd85c16c87bcd248db456f
2025-12-30 16:30:34 -05:00
Aidan MacDonald
fcf67a2ea9 echoplayer: enable reggen
Change-Id: Iab8ffd231f226d2772201ad92f3920065b7b0736
2025-12-30 13:53:48 -05:00
Aidan MacDonald
44afcc8cbe firmware: add build rules for RegGen-generated headers
Change-Id: I86ff1a39aec1ee428abd6464483ae3732fdf9196
2025-12-30 13:53:48 -05:00
Aidan MacDonald
a8d792c248 firmware: add RegGen API header
Change-Id: Ifb79416f91a40d0a6538ba0b4a3c7b0496543a5f
2025-12-30 13:53:48 -05:00
Aidan MacDonald
1064aa8dab firmware: add RegGen description for Cortex-M
Change-Id: Iec8c8f1f962653cfa27c50b2bac8b2092eb7afce
2025-12-30 13:53:48 -05:00
Aidan MacDonald
e7b139b06a firmware: add RegGen description for STM32H743
Change-Id: I084c54bd1c2c2974e5fd0b1bfea68697b2b394ba
2025-12-30 13:53:48 -05:00
Marc Aarts
a3d16e34ec Update rockboxdev.sh:
- Change alsa-lib and libffi source to use https instead of ftp
- Change glib source to current path (avoids redirect)
- Change mpc source to GNU mirror because www.multiprecision.org seems down
- Change remaining http to https

Original reason for the change is that on WSL2 (Windows 11) for some reason ftp links do not appear to work.

Change-Id: Ib20470e39f625df790895452b6d6b4003cebae07
2025-12-30 07:11:11 -05:00
Aidan MacDonald
969a2b65c7 tools: add RegGen utility
This is a tool written in C which does basically the same job
as regtools' headergen_v2, but using a new input format which
is less verbose than XML. In the interests of simplicity it
omits some features that regtools does support, like variant
registers or the SoC selector stuff so it cannot completely
replace regtools on the i.MX platforms that use these features.

RegGen doesn't generate API macros like regtools does; instead
these are expected to be maintained by hand, since it's arguably
easier to do that way.

Since RegGen has no dependencies beyond a C compiler it can
be integrated with the build system without adding any new
build time dependencies. This will allow generating headers
automatically, which is a substantial improvement over running
headergen_v2 by hand and committing the generated output.

The RegGen tool itself is licensed as GPLv3+, but generated
headers can be licensed as the user chooses.

Change-Id: If18f9577f8f4df6e2c97c1665b725773dd5466f0
2025-12-29 18:51:56 -05:00
Sebastian Leonhardt
6552554939 Creative ZEN: split ZEN V keymaps off from other ZEN targets
The ZEN V target is the only one which has volume buttons,
but lacks the menu and shortcut buttons.
IMO an independant keymap will make maintenance easier.

Change-Id: Ide79fab629b13eae94946561d99052e570c0e4f2
2025-12-29 23:20:06 +01:00
Aidan MacDonald
cb9094dabb arm: fix start_thread() on Cortex-M targets
The layout of 'struct regs' is a bit different on Cortex-M
and start_thread() wasn't updated to match; it was loading
'sp' from the wrong offset.

Change-Id: I57dbef26809821d411dc86e2066a2f53e78a3f2d
2025-12-29 13:04:54 -05:00
Petr Mikhalicin
19a49220b1 plugin lrcplayer: Fix late rewinding at lrcplayer
If you try to rewind music at lrcplayer it
1. returns back to old time
2. play for some time (1-2 seconds)
3. only after that returns for new time

According to wps code audio_pre_ff_rewind function should be called
before any rewinding. It stops playback and automatically resumes it
after audio_ff_rewind call

Change-Id: Id3755bfe4deeb7cd5d889ad7d8e1dec45061fa5c
2025-12-29 12:58:47 -05:00
Solomon Peachy
716f45e291 Another correction for the Dutch translation
Change-Id: Ia20ba715264464be17516220933675eef2e825bd
2025-12-29 12:57:19 -05:00
Petr Mikhalicin
6f7d70797e plugin api: Add audio_pre_ff_rewind to plugin's API
According to wps code audio_pre_ff_rewind function should be called
before any rewinding. It stops playback and automatically resumes it
after audio_ff_rewind call

So, let's add audio_pre_ff_rewind to plugin's API

Lua scipts were tested:
```lua
-- has issue with rewinding
rb.audio("ff_rewind", 0)
```

```lua
-- no issue with rewinding
rb.audio("pre_ff_rewind")
rb.audio("ff_rewind", 0)
```

Change-Id: I2ad6b9c396760b2086bc0a28633a1c80c3512739
2025-12-29 19:58:26 +05:00
Solomon Peachy
06badb81b4 translations: Mechanical corrections to Dutch translation
Change-Id: Ifeef3cdff24d067a09dbed49b99088cffb14f890
2025-12-29 09:21:30 -05:00
Solomon Peachy
9735e5e878 FS#13736: Updated Italian translation (Alessio Lenzi)
Change-Id: I44d603c47527fbb5cf0608122fea03af196a9f12
2025-12-29 09:02:32 -05:00
Solomon Peachy
5f5c03b3c7 translations: Minor mechanical fix to German translation
Change-Id: Ib5249fe3c7c009187bbe51f00cf6056e4b531a12
2025-12-29 09:02:09 -05:00
Christian Soffke
1a66c4fd5d eq_menu: fix talk menu setting not being respected
Change-Id: I2f3762c466083375dc72d682f6951e9644b06acc
2025-12-29 13:43:50 +01:00
Solomon Peachy
ca253a78cf More translation updates:
* Ukrainian (Pavlo Rudy)
 * Dutch (Marc Aarts)

Change-Id: I72ed4e30f8d43136f6e9c8fc2d185336ddbfdc57
2025-12-28 10:55:33 -05:00
Solomon Peachy
fed9a83d68 hibyr1/r3proii: Fix unused parameter warning
Change-Id: If44f529c49086d644f6183c573327ab38ea14583
2025-12-28 10:53:33 -05:00
Solomon Peachy
4b4f85f0f4 Fix warnings on hibyr1/r3proii targets
Change-Id: I7b0331bd8ffd2d919799e88e4556c3e01ff90c46
2025-12-28 10:30:54 -05:00
Solomon Peachy
ead839b1c3 FS#13726 - Updated Ukranian translation (Pavlo Rudy)
Change-Id: If7db4efc3993585eb6e4d388b504013c02fbc359
2025-12-28 08:24:34 -05:00
Solomon Peachy
d4f341e46d Translation updates:
* German (Karl Huber)
 * Korean (Hoseok Seo)
 * Polish (Adam Rak)
 * Simplified Chinese (王吉)
 * Slovak (Matej Golian)
 * Swedish (wilton millfjord)
 * US English (myself)

Change-Id: I644133e326c3ee1ec3862791075dda39fd17a3e4
2025-12-28 08:22:06 -05:00
Solomon Peachy
9c15ef82ee builds: Add Hiby R1 and R3ProII as Unstable targets
Change-Id: If901cacb295668ca661cf5450e88db509aabf409
2025-12-27 17:07:42 -05:00
Marc Aarts
1183b1ab1b Rockbox for the HiBy R3 Pro II/R1
Original author Melissa Autumn (https://codeberg.org/oopsallnaps/rockbox-hibyos) with contributions from Marc Aarts.

Adaptation to Rockbox standards by Marc Aarts

Change-Id: I09e5af7ba0a75c648e4b9fd424badc2d3665c943
2025-12-27 15:44:54 -05:00
Petr Mikhalicin
eee6c31b4a plugin otp: Stop freezing display when generate OTP
Sometimes OTP code expires soon and we can't use it. So, We have to
wait for new one. And it's really anoying, when devide stucking at this
time

Change-Id: Ic5e0105b6c051ad2ec2a2421068867be2e497683
2025-12-27 12:08:16 -05:00
Petr Mikhalicin
4e13e69de3 plugin otp: Fix handling of unknown otpauth uri parameters
OTP uri parameters is key value options separated by '&'.
So, we on unknown params we have to reject also everything what was
behind '&'

Example:
otpauth://totp/kek?issuer=petya%40IPARTKN.TEST&secret=1234567890&digits=6&algorithm=SHA1&period=30

"algorithm" was unknown. So, next token after it was "SHA1&period", not "period"

Change-Id: I48eb198fd46212c6422dd8eac214adafdf3a52eb
2025-12-27 12:08:06 -05:00
Petr Mikhalicin
ca57184ff0 plugin otp: Make 'Generate Code' first option at otp plugin
Generating code is more popular action then adding accounts. So, let's
make it first

Change-Id: I15ea07ef63186611c4a87ba741c5a7b5d0d5041c
2025-12-27 12:06:57 -05:00
Christian Soffke
f7ede2b9df plugins: Disk Tidy: wait for dircache
Running Disk Tidy while the dircache is loading is a lot
slower than waiting for it to finish building first.

Typical scenarios for this would be starting Disk Tidy
immediately after booting or after unplugging from USB.

Deleting files during a dircache build also seems to easily
result in memory corruption, as evidenced by visual glitches
appearing in the theme.

Change-Id: I9250d918d916b112ffe2504a9225a0b52bcc3622
2025-12-27 16:29:16 +01:00
Christian Soffke
8e512d1f79 plugins: Disk Tidy: SBS title & minor display adjustments
- Move header that displays "Cleaning...", or
  that shows the last run's date, into SBS
  title area, if it exists.
- Left-align everything if SBS title doesn't exist
- Display "Nothing removed" instead of multiple
  zeros for items, size, dirs, and files
- Display "Today" instead of the current date
- display "2m 1s" instead of "00:02:01, and
  "<1s" instead of "00:00:00"
- "1 items" -> "1 item"

Change-Id: I40302af00d1038adca45a1c6a908af76bd9917cc
2025-12-27 16:29:16 +01:00
Christian Soffke
71f84bedd6 plugins: text viewer: use basename in title
i.e. pictureflow.cfg instead of something like
/<microSD0>/main/.rockbox/rocks/demos/pictureflow.cfg
since the last path component is usually more important
and may not be visible otherwise.

Change-Id: Icdc2d0db21d9290ce53213b0a650c83631e7c9ed
2025-12-27 16:29:16 +01:00
Christian Soffke
8c9f70de82 plugins: text viewer: use SBS title
Take advantage of skinned status bar title, instead of
displaying a custom header that reduces space for content.

A custom header will still be displayed if the SBS
doesn't come with its own title, such as on the default
theme, or if the status bar has been turned off in Text
Viewer's settings.

Change-Id: I14c8d9a61acf338d09d7f54947399e8692987a7b
2025-12-27 16:29:16 +01:00
Christian Soffke
1fd45d23a0 plugins: text viewer: use theme colors & backdrop
When Night Mode was added to Text Viewer
in ab1b67f, the regular mode was changed to
black and white instead of using theme colors.
This looks out of place in custom themes when
the statusbar is enabled, i.e. using the default
Text Viewer setting. Only switch to black and
white when statusbar is disabled, which also
disables the backdrop.

Change-Id: I3ff5e1c42de11ca58640e91bcb315ce7804fadcd
2025-12-27 10:28:00 -05:00
Christian Soffke
06af1090bb plugins: vu_meter: enable theme for submenus
Also properly handle situation where theme is already
enabled at launch.

Change-Id: Ic7b3dcf38e77f6e9d6ef4a5512f729e47880e46c
2025-12-27 15:49:05 +01:00
Christian Soffke
17ea0bb82e simplelist: fix unbalanced viewportmanager calls
viewportmanager_theme_enable isn't balanced by
viewportmanager_theme_undo when connecting to USB
while simplelist is displayed.

Change-Id: Iad9408a52150934246c886a01a5d1efc8febd0fd
2025-12-26 16:05:24 +01:00
William Wilgus
44a5163061 firmware: fix misdefinition of QUEUE_GET_THREAD macro #2?
Broke the sim, just above it has..

struct queue_sender_list
{
    /* If non-NULL, there is a thread waiting for the corresponding event */
    /* Must be statically allocated to put in non-cached ram. */
    struct thread_entry *senders[QUEUE_LENGTH]; /* message->thread map */
    struct __wait_queue list;                   /* list of senders in map */
    /* Send info for last message dequeued or NULL if replied or not sent */
    struct thread_entry * volatile curr_sender;
    struct blocker blocker;
};

Change-Id: Ifc7a5fe92ebe5f06c0dc5655ce9725752e606381
2025-12-26 09:24:11 -05:00
Solomon Peachy
515b2816cd FS#13724 - Updated Swedish translation (Wilton Millfjord)
Change-Id: If4c18da6a95a08c9ef3c38d79479742c0da62528
2025-12-26 08:46:21 -05:00
Christian Soffke
dbec04dc81 simplelist: stop scrolling when leaving
Fixes (at least) Shortcuts menu not stopping
a scrolling line after leaving menu for a
plugin in some situations.

Change-Id: I90b4cc71a63e557565d028aae27db082e2e1813f
2025-12-26 02:50:15 -05:00
Christian Soffke
b04fd3efed plugins: fix dangling sbs_title pointer
Change-Id: Ief2a5dde8760e55524a74b482079a2a9ebafece9
2025-12-26 08:29:26 +01:00
Aidan MacDonald
28fa9ca760 firmware: fat: fix sector_t passed to 64-bit format strings
sector_t is still 32-bit on most targets, resulting in compile
warnings on debug builds when used with an %llu/%llx format.
Fix by always casting the sector to uint64_t.

Change-Id: I5afc4a0ae170981c304274806e00ac07be232cd8
2025-12-24 09:30:47 -05:00
Aidan MacDonald
d21d8f49fc firmware: fix misdefinition of QUEUE_GET_THREAD macro
This tries to access 'struct event_queue->send', but that
is only available if HAVE_EXTENDED_MESSAGING_AND_NAME is set.
This is not defined for bootloaders; this is a problem when
trying to build a bootloader with debugging enabled, because
the misdefined macro is used in some KERNEL_ASSERTs that get
compiled out on non-debug builds.

Change-Id: I334eedcda1ee7047c8dddcb7fa0c9717156f2a0a
2025-12-24 09:30:18 -05:00
Solomon Peachy
aaee78586a Minor mechanical correction to French translation
(USB-DAC is correct, and will be spelled out properly au francais
 thanks to voice-corrections.txt)

Change-Id: I2dd8e0e41df3e687a26fa74272f5248cda8f7b20
2025-12-23 20:08:52 -05:00
Aidan MacDonald
d24a127f63 echoplayer: enable USE_ELF to generate ELF binaries
Make the final .echo binary an ELF file. Most STM32s have
their SRAM divided in multiple non-contiguous regions and
putting an ELF loader in the bootloader is basically the
only reasonable way to load Rockbox on such a system.

Change-Id: I818ef9fefe0d53b44cf64402ee1794ad261343eb
2025-12-23 17:57:59 +00:00
Aidan MacDonald
2e85027ae7 configure: set USE_ELF to no by default
Otherwise, toggling USE_ELF in the target's configure section
and running 'make reconf' has no effect, because the previous
value of USE_ELF is inherited from the makefile.

Change-Id: I72d605ef6987fc590871566d73b24acf37e8fbe6
2025-12-23 17:57:59 +00:00
Aidan MacDonald
6078b2a6b4 echoplayer: enable debug symbols by default
This adds debug symbols to rockbox.elf & bootloader.elf to
make debugging with GDB easier. This won't affect code that
runs on the target because debug symbols are stripped from
the final binary.

Change-Id: I9efe207c63e8bd96404213aad96405be27030ae9
2025-12-23 17:57:59 +00:00
402 changed files with 17731 additions and 16415 deletions

3
.gitignore vendored
View file

@ -8,6 +8,8 @@
*.o
*.a
*~
.cache
__pycache__
.DS_STORE
@ -119,6 +121,7 @@ __pycache__
/tools/bmp2rb
/tools/codepages
/tools/rdf2binary
/tools/reggen
/tools/mkboot
/tools/mk500boot
/tools/uclpack

View file

@ -270,6 +270,8 @@ keymaps/keymap-sansa-connect.c
keymaps/keymap-ypr0.c
#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD
keymaps/keymap-zen.c
#elif CONFIG_KEYPAD == CREATIVE_ZENV_PAD
keymaps/keymap-zenv.c
#elif CONFIG_KEYPAD == MA_PAD
keymaps/keymap-ma.c
#elif CONFIG_KEYPAD == SONY_NWZ_PAD
@ -310,4 +312,6 @@ keymaps/keymap-surfansf28.c
keymaps/keymap-rgnano.c
#elif CONFIG_KEYPAD == CTRU_PAD
keymaps/keymap-ctru.c
#elif CONFIG_KEYPAD == HIBY_R3PROII_PAD
keymaps/keymap-hibyr3proii.c
#endif

View file

@ -46,7 +46,7 @@ toolsicon.130x130x16.bmp
hibyicon.70x70x16.bmp
rockboxicon.70x70x16.bmp
toolsicon.70x70x16.bmp
#elif (defined(XDUOO_X3II) || defined(XDUOO_X20) || defined(EROS_Q) || defined(SURFANS_F28))
#elif (defined(XDUOO_X3II) || defined(XDUOO_X20) || defined(EROS_Q) || defined(SURFANS_F28) || defined(HIBY_R3PROII) || defined(HIBY_R1))
hibyicon.130x130x16.bmp
rockboxicon.130x130x16.bmp
toolsicon.130x130x16.bmp

View file

@ -1083,7 +1083,7 @@ static int select_bookmark(const char* bookmark_file_name,
case ACTION_BMS_DELETE:
if (item >= 0)
{
if (confirm_delete_yesno("") == YESNO_YES)
if (confirm_delete_yesno("", str(LANG_BOOKMARK_CONTEXT_MENU)) == YESNO_YES)
{
delete_bookmark(bookmark_file_name, item);
bookmarks->reload = true;

View file

@ -474,12 +474,14 @@ static void load_codec(const struct codec_load_info *ev_data)
dsp_configure(ci.dsp, DSP_RESET, 0);
}
#if defined(HAVE_CODEC_BUFFERING)
if (data.hid >= 0)
{
/* First try buffer load */
status = codec_load_buf(data.hid, &ci);
bufclose(data.hid);
}
#endif /* HAVE_CODEC_BUFFERING */
if (status < 0)
{

View file

@ -225,6 +225,7 @@ static int codec_load_ram(struct codec_api *api)
return c_hdr->entry_point(CODEC_LOAD);
}
#if defined(HAVE_CODEC_BUFFERING)
int codec_load_buf(int hid, struct codec_api *api)
{
int rc = bufread(hid, CODEC_SIZE, codecbuf);
@ -243,6 +244,7 @@ int codec_load_buf(int hid, struct codec_api *api)
return codec_load_ram(api);
}
#endif /* HAVE_CODEC_BUFFERING */
int codec_load_file(const char *plugin, struct codec_api *api)
{

View file

@ -1178,6 +1178,10 @@ static bool view_battery(void)
#else
lcd_putsf(0, 3, "Charger: %s",
charger_inserted() ? "present" : "absent");
#if defined(HAVE_USBSTACK) && defined(HAVE_USB_CHARGING_ENABLE)
lcd_putsf(0, 4, "USB current limit: %d mA",
usb_charging_maxcurrent());
#endif /* HAVE_USB_CHARGING_ENABLE */
#endif /* target type */
#endif /* CONFIG_CHARGING */
break;
@ -2842,7 +2846,7 @@ static const struct {
{ "Screendump", dbg_screendump },
#endif
{ "Skin Engine RAM usage", dbg_skin_engine },
#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SONY_NWZ_LINUX) || defined(HIBY_LINUX) || defined(FIIO_M3K_LINUX)) && !defined(SIMULATOR)
#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SONY_NWZ_LINUX) || (defined(HIBY_LINUX) && !defined(HIBY_R3PROII) && !defined(HIBY_R1)) || defined(FIIO_M3K_LINUX)) && !defined(SIMULATOR)
{ "View HW info", dbg_hw_info },
#endif
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)

View file

@ -20,6 +20,10 @@ alarm
backlight_brightness
#endif
#if defined(HAVE_GENERAL_PURPOSE_LED)
general_purpose_led
#endif
#if defined(HAVE_BUTTON_LIGHT)
button_light
#endif
@ -182,7 +186,7 @@ depth_3d
#endif
/* This should be AUDIOHW_HAVE_FILTER_ROLL_OFF but that is only defined later */
#if defined(DX50) || defined(HAVE_DF1704_CODEC) || defined(HAVE_PCM1792_CODEC) || defined(HAVE_CS4398) || defined(HAVE_WM8740) || defined(HAVE_ES9018)|| defined(HAVE_EROS_QN_CODEC) || defined(HAVE_XDUOO_LINUX_CODEC) || defined(HAVE_FIIO_LINUX_CODEC) || defined(HAVE_AK4376) || defined(HAVE_ES9218) || defined(HAVE_SURFANS_LINUX_CODEC)
#if defined(DX50) || defined(HAVE_DF1704_CODEC) || defined(HAVE_PCM1792_CODEC) || defined(HAVE_CS4398) || defined(HAVE_WM8740) || defined(HAVE_ES9018)|| defined(HAVE_EROS_QN_CODEC) || defined(HAVE_XDUOO_LINUX_CODEC) || defined(HAVE_FIIO_LINUX_CODEC) || defined(HAVE_AK4376) || defined(HAVE_ES9218) || defined(HAVE_SURFANS_LINUX_CODEC) || defined(HAVE_HIBY_LINUX_CODEC)
filter_roll_off
#endif

View file

@ -582,9 +582,8 @@ int delete_fileobject(const char *selected_file)
/* Note: delete_fileobject() will happily delete whatever
* path is passed (after confirmation) */
if (confirm_delete_yesno(param.path) != YESNO_YES) {
if (confirm_delete_yesno(param.path, param.toplevel_name) != YESNO_YES)
return FORC_CANCELLED;
}
if (param.is_dir) {
int rc = check_count_fileobjects(&param);

View file

@ -585,7 +585,7 @@ bool gui_synclist_keyclick_callback(int action, void* data)
*
* The GUI_EVENT_NEED_UI_UPDATE event is registered for in list_do_action_timeout()
* as a oneshot and current_lists updated. later current_lists is set to NULL
* in gui_synclist_do_button() effectively disabling the callback.
* in gui_synclist_do_button() effectively disabling the callback.
* This is done because if something is using the list UI they *must* be calling those
* two functions in the correct order or the list wont work.
*/
@ -692,7 +692,7 @@ bool gui_synclist_do_button(struct gui_synclist * lists, int *actionptr)
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)
@ -883,6 +883,7 @@ bool simplelist_show_list(struct simplelist_info *info)
int action, old_line_count = simplelist_line_count;
list_get_name *getname;
int line_count;
bool ret = false;
if (info->get_name)
{
@ -896,7 +897,10 @@ bool simplelist_show_list(struct simplelist_info *info)
}
FOR_NB_SCREENS(i)
{
sb_set_persistent_title(info->title, info->title_icon, i);
viewportmanager_theme_enable(i, !info->hide_theme, NULL);
}
gui_synclist_init(&lists, getname, info->callback_data,
info->scroll_all, info->selection_size, NULL);
@ -971,19 +975,25 @@ bool simplelist_show_list(struct simplelist_info *info)
}
else if(default_event_handler(action) == SYS_USB_CONNECTED)
{
return true;
ret = true;
break;
}
}
talk_shutup();
gui_synclist_scroll_stop(&lists);
#ifdef HAVE_LCD_COLOR
if (info->selection_color)
gui_synclist_set_sel_color(&lists, NULL);
#endif
FOR_NB_SCREENS(i)
{
sb_set_persistent_title(info->title, info->title_icon, i);
viewportmanager_theme_undo(i, false);
return false;
}
return ret;
}
void simplelist_info_init(struct simplelist_info *info, char* title,

View file

@ -207,6 +207,11 @@ void draw_progressbar(struct gui_wps *gwps, struct skin_viewport* skin_viewport,
length = MAX_PEAK;
end = peak_meter_scale_value(val, length);
}
else if (pb->type == SKIN_TOKEN_PLAYLIST_PERCENTBAR)
{
length = playlist_amount();
end = playlist_get_display_index();
}
else if (pb->type == SKIN_TOKEN_LIST_SCROLLBAR)
{
int val, min, max;

View file

@ -1241,6 +1241,8 @@ static int parse_progressbar_tag(struct skin_element* element,
token->type = SKIN_TOKEN_PEAKMETER_LEFTBAR;
else if (token->type == SKIN_TOKEN_PEAKMETER_RIGHT)
token->type = SKIN_TOKEN_PEAKMETER_RIGHTBAR;
else if (token->type == SKIN_TOKEN_PLAYLIST_PERCENT)
token->type = SKIN_TOKEN_PLAYLIST_PERCENTBAR;
else if (token->type == SKIN_TOKEN_LIST_NEEDS_SCROLLBAR)
token->type = SKIN_TOKEN_LIST_SCROLLBAR;
else if (token->type == SKIN_TOKEN_SETTING)
@ -2418,6 +2420,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
case SKIN_TOKEN_PLAYER_PROGRESSBAR:
case SKIN_TOKEN_PEAKMETER_LEFT:
case SKIN_TOKEN_PEAKMETER_RIGHT:
case SKIN_TOKEN_PLAYLIST_PERCENT:
case SKIN_TOKEN_LIST_NEEDS_SCROLLBAR:
#ifdef HAVE_RADIO_RSSI
case SKIN_TOKEN_TUNER_RSSI:

View file

@ -225,6 +225,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
/* fall through to the progressbar code */
case SKIN_TOKEN_VOLUMEBAR:
case SKIN_TOKEN_BATTERY_PERCENTBAR:
case SKIN_TOKEN_PLAYLIST_PERCENTBAR:
case SKIN_TOKEN_SETTINGBAR:
case SKIN_TOKEN_PROGRESSBAR:
case SKIN_TOKEN_TUNER_RSSI_BAR:

View file

@ -1164,6 +1164,25 @@ const char *get_token_value(struct gui_wps *gwps,
numeric_buf = buf;
goto gtv_ret_numeric_tag_info;
case SKIN_TOKEN_PLAYLIST_PERCENT:
{
int playlist_amt = playlist_amount();
int current_pos = playlist_get_display_index() + offset;
int percentage = current_pos * 100 / playlist_amt;
if (intval && limit != TOKEN_VALUE_ONLY)
{
numeric_ret = current_pos * limit / playlist_amt;
}
else
{
numeric_ret = percentage;
}
itoa_buf(buf, buf_size, percentage);
numeric_buf = buf;
goto gtv_ret_numeric_tag_info;
}
case SKIN_TOKEN_PLAYLIST_SHUFFLE:
if ( global_settings.playlist_shuffle )
return "s";

View file

@ -39,6 +39,7 @@
#include "icon.h"
#include "icons.h"
#include "option_select.h"
#include "string-extra.h"
#ifdef HAVE_TOUCHSCREEN
#include "sound.h"
#include "misc.h"
@ -49,6 +50,7 @@ static int update_delay = DEFAULT_UPDATE_DELAY;
static bool sbs_has_title[NB_SCREENS];
static const char* sbs_title[NB_SCREENS];
static char sbs_persistent_title[NB_SCREENS][80];
static enum themable_icons sbs_icon[NB_SCREENS];
static bool sbs_loaded[NB_SCREENS] = { false };
@ -62,6 +64,15 @@ bool sb_set_title_text(const char* title, enum themable_icons icon, enum screen_
return sbs_has_title[screen];
}
bool sb_set_persistent_title(const char* title, enum themable_icons icon, enum screen_type screen)
{
if (!title)
return sb_set_title_text(title, icon, screen);
strlcpy(sbs_persistent_title[screen], title, sizeof(*sbs_persistent_title));
return sb_set_title_text((const char *) sbs_persistent_title[screen], icon, screen);
}
void sb_skin_has_title(enum screen_type screen)
{
sbs_has_title[screen] = true;
@ -71,6 +82,15 @@ const char* sb_get_title(enum screen_type screen)
{
return sbs_has_title[screen] ? sbs_title[screen] : NULL;
}
const char* sb_get_persistent_title(enum screen_type screen)
{
return (sbs_has_title[screen] &&
sbs_title[screen] == sbs_persistent_title[screen]) ?
sbs_title[screen] : NULL;
}
enum themable_icons sb_get_icon(enum screen_type screen)
{
return sbs_has_title[screen] ? sbs_icon[screen] : Icon_NOICON + 2;

View file

@ -39,8 +39,11 @@ void sb_skin_update(enum screen_type screen, bool force);
void sb_skin_set_update_delay(int delay);
bool sb_set_title_text(const char* title, enum themable_icons icon, enum screen_type screen);
bool sb_set_persistent_title(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);
const char* sb_get_persistent_title(enum screen_type screen);
enum themable_icons sb_get_icon(enum screen_type screen);
#ifdef HAVE_TOUCHSCREEN

View file

@ -111,7 +111,8 @@ static void toggle_theme(enum screen_type screen, bool force)
FOR_NB_SCREENS(i)
{
enable_event = enable_event || is_theme_enabled(i);
sb_set_title_text(NULL, Icon_NOICON, i);
if (!sb_get_persistent_title(i))
sb_set_title_text(NULL, Icon_NOICON, i);
}
toggle_events(enable_event);
@ -195,6 +196,8 @@ void viewportmanager_theme_undo(enum screen_type screen, bool force_redraw)
panicf("Stack underflow... viewportmanager");
toggle_theme(screen, force_redraw);
if (sb_get_persistent_title(screen))
screens[screen].scroll_stop();
}

View file

@ -498,11 +498,7 @@ static void play_hop(int direction)
{
elapsed += step * direction;
}
if(audio_status() & AUDIO_STATUS_PLAY)
{
audio_pre_ff_rewind();
}
audio_pre_ff_rewind();
audio_ff_rewind(elapsed);
}
@ -578,6 +574,7 @@ static void gwps_enter_wps(bool theme_enabled)
gwps = skin_get_gwps(WPS, i);
display = gwps->display;
display->scroll_stop();
sb_set_title_text(NULL, Icon_NOICON, i);
/* Update the values in the first (default) viewport - in case the user
has modified the statusbar or colour settings */
#if LCD_DEPTH > 1

View file

@ -31,6 +31,7 @@
#include "appevents.h"
#include "splash.h"
#include "backlight.h"
#include "statusbar-skinned.h"
struct gui_yesno
{
@ -216,6 +217,7 @@ static void gui_yesno_ui_update(unsigned short id, void *event_data, void *user_
* 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 char * title,
const struct text_message * main_message,
const struct text_message * yes_message,
const struct text_message * no_message)
@ -241,7 +243,9 @@ enum yesno_res gui_syncyesno_run_w_tmo(int ticks, enum yesno_res tmo_default_res
yn[i].main_message=main_message;
yn[i].display=&screens[i];
screens[i].scroll_stop();
sb_set_persistent_title(title, Icon_NOICON, i);
viewportmanager_theme_enable(i, true, &(yn[i].vp));
yn[i].vp_lines = viewport_get_nb_lines(&(yn[i].vp));
}
@ -350,7 +354,8 @@ exit:
FOR_NB_SCREENS(i)
{
screens[i].scroll_stop_viewport(&(yn[i].vp));
viewportmanager_theme_undo(i, true);
sb_set_persistent_title(title, Icon_NOICON, i);
viewportmanager_theme_undo(i, false);
}
#ifdef HAVE_TOUCHSCREEN
@ -363,8 +368,18 @@ 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);
return gui_syncyesno_run_w_tmo(TIMEOUT_BLOCK, YESNO_TMO, NULL,
main_message, yes_message, no_message);
}
extern enum yesno_res gui_syncyesno_run_w_title(
const char * title,
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, title,
main_message, yes_message, no_message);
}
static bool yesno_pop_lines(const char *lines[], int line_cnt)

View file

@ -50,11 +50,19 @@ extern enum yesno_res gui_syncyesno_run(
const struct text_message * yes_message,
const struct text_message * no_message);
/* Sets SBS title for the screen. Title may be NULL. */
extern enum yesno_res gui_syncyesno_run_w_title(
const char *title,
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);
int ticks, enum yesno_res tmo_default_res,
const char *title,
const struct text_message * main_message,
const struct text_message * yes_message,
const struct text_message * no_message);
bool yesno_pop(const char* text);
bool yesno_pop_confirm(const char* text);

View file

@ -119,6 +119,7 @@ enum yesno_res gui_syncyesno_run(const struct text_message * main_message,
}
enum yesno_res gui_syncyesno_run_w_tmo(int ticks, enum yesno_res tmo_default_res,
const char *title,
const struct text_message * main_message,
const struct text_message * yes_message,
const struct text_message * no_message)
@ -126,6 +127,16 @@ enum yesno_res gui_syncyesno_run_w_tmo(int ticks, enum yesno_res tmo_default_res
/* FIXME: create a prompt with timeout for android */
(void)ticks;
(void)tmo_default_res;
(void)title; /* Note: title ignored on Android */
return gui_syncyesno_run(main_message, yes_message, no_message);
}
enum yesno_res gui_syncyesno_run_w_title(const char *title,
const struct text_message * main_message,
const struct text_message * yes_message,
const struct text_message * no_message)
{
(void)title; /* Note: title ignored on Android */
return gui_syncyesno_run(main_message, yes_message, no_message);
}

View file

@ -0,0 +1,233 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 Solomon Peachy
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "config.h"
#include "action.h"
#include "button.h"
#include "settings.h"
static const struct button_mapping button_context_standard[] =
{
{ ACTION_STD_PREV, BUTTON_PREV, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_NEXT, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_OK, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_STD_CONTEXT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_PLAY },
{ ACTION_STD_CANCEL, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
{ ACTION_STD_KEYLOCK, BUTTON_POWER|BUTTON_VOL_UP, BUTTON_POWER },
LAST_ITEM_IN_LIST
};
static const struct button_mapping button_context_wps[] =
{
{ ACTION_WPS_MENU, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
{ ACTION_WPS_PLAY, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY },
{ ACTION_WPS_STOP, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_SKIPNEXT, BUTTON_NEXT|BUTTON_REL, BUTTON_NEXT },
{ ACTION_WPS_SKIPPREV, BUTTON_PREV|BUTTON_REL, BUTTON_PREV },
{ ACTION_WPS_SEEKFWD, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_NEXT|BUTTON_REL, BUTTON_NEXT|BUTTON_REPEAT },
{ ACTION_WPS_SEEKBACK, BUTTON_PREV|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_PREV|BUTTON_REL, BUTTON_PREV|BUTTON_REPEAT },
{ ACTION_STD_KEYLOCK, BUTTON_POWER|BUTTON_VOL_UP, BUTTON_POWER },
LAST_ITEM_IN_LIST
};
static const struct button_mapping button_context_list[] =
{
{ ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE },
{ ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
};
static const struct button_mapping button_context_tree[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
};
static const struct button_mapping button_context_listtree_scroll_with_combo[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM | CONTEXT_TREE),
};
static const struct button_mapping button_context_listtree_scroll_without_combo[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM | CONTEXT_TREE),
};
static const struct button_mapping button_context_settings[] =
{
{ ACTION_SETTINGS_INC, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
};
static const struct button_mapping button_context_settings_right_is_inc[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
};
static const struct button_mapping button_context_mainmenu[] =
{
{ ACTION_TREE_WPS, BUTTON_POWER|BUTTON_REL, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_TREE),
};
static const struct button_mapping button_context_yesno[] =
{
{ ACTION_YESNO_ACCEPT, BUTTON_PLAY, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_POWER, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD),
};
static const struct button_mapping button_context_colorchooser[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
};
static const struct button_mapping button_context_eq[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
};
static const struct button_mapping button_context_keyboard[] =
{
{ ACTION_KBD_LEFT, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_KBD_CURSOR_LEFT, BUTTON_PLAY | BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_KBD_CURSOR_RIGHT, BUTTON_PLAY | BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_KBD_DONE, BUTTON_PLAY | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_SELECT, BUTTON_PLAY | BUTTON_REL, BUTTON_NONE },
{ ACTION_KBD_ABORT, BUTTON_POWER, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_NEXT, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_NEXT | BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_PREV, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_PREV | BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST
};
static const struct button_mapping button_context_bmark[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
};
static const struct button_mapping button_context_time[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS),
};
static const struct button_mapping button_context_quickscreen[] =
{
{ ACTION_QS_TOP, BUTTON_VOL_UP|BUTTON_REL, BUTTON_NONE },
{ ACTION_QS_TOP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_LEFT, BUTTON_PLAY|BUTTON_REL, BUTTON_NONE },
{ ACTION_QS_LEFT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_RIGHT, BUTTON_NEXT|BUTTON_REL, BUTTON_NONE },
{ ACTION_QS_RIGHT, BUTTON_NEXT|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
};
static const struct button_mapping button_context_pitchscreen[] =
{
{ ACTION_PS_INC_SMALL, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_PS_DEC_SMALL, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_PS_EXIT, BUTTON_POWER, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
};
static const struct button_mapping button_context_radio[] =
{
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
};
const struct button_mapping* target_get_context_mapping(int context)
{
switch (context & ~CONTEXT_LOCKED)
{
case CONTEXT_STD: { return button_context_standard; }
case CONTEXT_WPS: { return button_context_wps; }
case CONTEXT_LIST: { return button_context_list; }
case CONTEXT_MAINMENU: { return button_context_mainmenu; }
case CONTEXT_CUSTOM | CONTEXT_TREE: { return button_context_tree; }
case CONTEXT_SETTINGS: { return button_context_settings; }
case CONTEXT_SETTINGS_COLOURCHOOSER: { return button_context_colorchooser; }
case CONTEXT_SETTINGS_EQ: { return button_context_eq; }
case CONTEXT_SETTINGS_TIME: { return button_context_time; }
case CONTEXT_YESNOSCREEN: { return button_context_yesno; }
case CONTEXT_KEYBOARD: { return button_context_keyboard; }
case CONTEXT_FM: { return button_context_radio; }
case CONTEXT_BOOKMARKSCREEN: { return button_context_bmark; }
case CONTEXT_QUICKSCREEN: { return button_context_quickscreen; }
case CONTEXT_PITCHSCREEN: { return button_context_pitchscreen; }
case CONTEXT_CUSTOM | CONTEXT_SETTINGS:
case CONTEXT_SETTINGS_RECTRIGGER: { return button_context_settings_right_is_inc; }
case CONTEXT_TREE:
{
if(global_settings.hold_lr_for_scroll_in_list)
{
return button_context_listtree_scroll_without_combo;
}
return button_context_listtree_scroll_with_combo;
}
}
return button_context_standard;
}

View file

@ -24,33 +24,23 @@
#include "button.h"
#include "settings.h"
/** This keymap is shared by the ZEN targets with some variants. All ZEN targets
* shared a core set of buttons: left, right, up, down, select, back, play/pause
* and they all have a hold button. Two extra groups of button may exist:
* (ctl) menu, shortcut
* (dir) top left, top right, bottom left, bottom left
* (vol) vol up, vol down
* Here is the list of ZEN targets are the groups:
* target core ctl dir vol
* V (Plus) 1 0 0 1
* Mozaic 1 1 0 0
* ZEN 1 1 0 0
* X-Fi 1 1 1 0 */
/* {Action Code, Button code, Prereq button code } */
#ifdef BUTTON_VOL_UP
#define ZEN_HAS_VOL
#endif
/** This keymap is shared by the ZEN targets with some variants.
* All ZEN targets shared a core set of buttons: left, right, up, down, select,
* back, menu, shortcut, and play/pause. All have a power/hold switch, except
* for the ZEN XFi Style that only has a power button.
* The ZEN XFi has an extra group of buttons:
* top left, top right, bottom left, bottom left.
*
* (Note: There's a stripped down version of the ZEN, the ZEN MX, that lacks
* the power/hold switch (play/pause also serves as power button).
* This target is not yet supported by rockbox, however a preliminary
* patch exists in gerrit.)
*/
#ifdef BUTTON_BOTTOMLEFT
#define ZEN_HAS_DIRECTIONAL
#endif
#ifdef BUTTON_MENU
#define ZEN_HAS_CONTROL
#endif
/*
* The format of the list is as follows
* { Action Code, Button code, Prereq button code }
@ -65,9 +55,7 @@ static const struct button_mapping button_context_standard[] = {
{ ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
{ ACTION_STD_CONTEXT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_RIGHT },
#ifdef ZEN_HAS_CONTROL
{ ACTION_STD_CONTEXT, BUTTON_MENU|BUTTON_REL, BUTTON_MENU },
#endif
{ ACTION_STD_QUICKSCREEN, BUTTON_BACK|BUTTON_REPEAT, BUTTON_BACK },
{ ACTION_STD_CANCEL, BUTTON_BACK|BUTTON_REL, BUTTON_BACK },
@ -84,13 +72,10 @@ static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_STOP, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE },
#ifdef ZEN_HAS_CONTROL
{ ACTION_WPS_CONTEXT, BUTTON_MENU|BUTTON_REL, BUTTON_MENU },
#ifdef HAVE_HOTKEY
{ ACTION_WPS_HOTKEY, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU },
#endif
#endif
{ ACTION_WPS_SKIPNEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
{ ACTION_WPS_SEEKFWD, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_SKIPPREV, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
@ -98,17 +83,9 @@ static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_STOPSEEK, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT },
{ ACTION_WPS_STOPSEEK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT|BUTTON_REPEAT },
#ifdef ZEN_HAS_VOL
{ ACTION_WPS_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
#endif
{ ACTION_WPS_VOLUP, BUTTON_UP, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
#ifdef ZEN_HAS_VOL
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
#endif
{ ACTION_WPS_VOLDOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
@ -136,11 +113,6 @@ static const struct button_mapping button_context_keyboard[] = {
{ ACTION_KBD_DONE, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
{ ACTION_KBD_ABORT, BUTTON_POWER, BUTTON_NONE },
#ifdef ZEN_HAS_VOL
{ ACTION_KBD_MORSE_INPUT, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_KBD_MORSE_SELECT, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
#endif
LAST_ITEM_IN_LIST
}; /* button_context_keyboard */
@ -165,7 +137,7 @@ static const struct button_mapping button_context_tree[] = {
{ ACTION_TREE_WPS, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_TREE_STOP, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_NONE },
#if defined(HAVE_HOTKEY) && defined(ZEN_HAS_CONTROL)
#if defined(HAVE_HOTKEY)
{ ACTION_TREE_HOTKEY, BUTTON_MENU|BUTTON_REPEAT, BUTTON_MENU },
#endif
@ -174,12 +146,6 @@ static const struct button_mapping button_context_tree[] = {
static const struct button_mapping button_context_list[] = {
#ifdef HAVE_VOLUME_IN_LIST
#ifdef ZEN_HAS_VOL
{ ACTION_LIST_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
#endif
#endif
/*#ifdef HAVE_HOTKEY on some gesture later?
{ ACTION_TREE_HOTKEY, BUTTON_BACK|BUTTON_REL, BUTTON_BACK|BUTTON_REPEAT },
@ -191,17 +157,9 @@ static const struct button_mapping button_context_list[] = {
#ifdef CONFIG_TUNER
static const struct button_mapping button_context_radio[] = {
{ ACTION_FM_MENU, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE },
#ifdef ZEN_HAS_CONTROL
{ ACTION_FM_MENU, BUTTON_MENU, BUTTON_NONE },
#endif
{ ACTION_FM_PLAY, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_FM_STOP, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_NONE },
#ifdef ZEN_HAS_VOL
{ ACTION_SETTINGS_INC, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
#endif
{ ACTION_FM_EXIT, BUTTON_BACK, BUTTON_NONE },
@ -282,7 +240,6 @@ static const struct button_mapping button_context_bmark[] = {
}; /* button_context_bmark */
static const struct button_mapping button_context_pitchscreen[] = {
{ ACTION_PS_INC_SMALL, BUTTON_UP, BUTTON_NONE },
{ ACTION_PS_INC_BIG, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_PS_DEC_SMALL, BUTTON_DOWN, BUTTON_NONE },
@ -293,11 +250,7 @@ static const struct button_mapping button_context_pitchscreen[] = {
{ ACTION_PS_NUDGE_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_PS_NUDGE_RIGHTOFF, BUTTON_RIGHT|BUTTON_REL, BUTTON_NONE },
#ifdef ZEN_HAS_CONTROL
{ ACTION_PS_TOGGLE_MODE, BUTTON_MENU, BUTTON_NONE },
#else
{ ACTION_PS_TOGGLE_MODE, BUTTON_PLAYPAUSE, BUTTON_NONE },
#endif
{ ACTION_PS_RESET, BUTTON_SELECT, BUTTON_NONE },
{ ACTION_PS_EXIT, BUTTON_BACK, BUTTON_NONE },
@ -323,17 +276,10 @@ static const struct button_mapping button_context_usb_hid[] = {
}; /* button_context_usb_hid */
static const struct button_mapping button_context_usb_hid_mode_multimedia[] = {
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_UP, BUTTON_UP, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_UP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
#ifdef ZEN_HAS_VOL
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_DOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_DOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_UP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_UP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
#endif
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_MUTE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_MUTE, BUTTON_BACK|BUTTON_REL, BUTTON_BACK },
{ ACTION_USB_HID_MULTIMEDIA_PLAYBACK_PLAY_PAUSE, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
@ -367,12 +313,6 @@ static const struct button_mapping button_context_usb_hid_mode_browser[] = {
{ ACTION_USB_HID_BROWSER_SCROLL_UP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_SCROLL_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_SCROLL_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
#ifdef ZEN_HAS_VOL
{ ACTION_USB_HID_BROWSER_ZOOM_IN, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_ZOOM_IN, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_ZOOM_OUT, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_ZOOM_OUT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
#endif
{ ACTION_USB_HID_BROWSER_ZOOM_RESET, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_TAB_PREV, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
{ ACTION_USB_HID_BROWSER_TAB_NEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
@ -407,7 +347,7 @@ static const struct button_mapping button_context_usb_hid_mode_mouse[] = {
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
}; /* button_context_usb_hid_mode_mouse */
#endif
#endif
#endif /* USB_ENABLE_HID */
/* 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)
@ -468,10 +408,9 @@ const struct button_mapping* get_context_mapping(int context)
case CONTEXT_USB_HID_MODE_MOUSE:
return button_context_usb_hid_mode_mouse;
#endif
#endif
#endif /* USB_ENABLE_HID */
default:
return button_context_standard;
}
return button_context_standard;
}

425
apps/keymaps/keymap-zenv.c Normal file
View file

@ -0,0 +1,425 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright © Amaury Pouly 2013
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "action.h"
#include "button.h"
#include "settings.h"
/** The Creative ZEN V has a 5-way mini joystick for directional control,
* a Play/Pause and a Back button. On the right side it has Volume +/- buttons
* and a record button, to the left is a combined power/hold switch.
*/
/*
* The format of the list is as follows
* { Action Code, Button code, Prereq button code }
* if there's no need to check the previous button's value, use BUTTON_NONE
* Insert LAST_ITEM_IN_LIST at the end of each mapping
*/
static const struct button_mapping button_context_standard[] = {
{ ACTION_STD_PREV, BUTTON_UP, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
{ ACTION_STD_CONTEXT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_RIGHT },
{ ACTION_STD_QUICKSCREEN, BUTTON_BACK|BUTTON_REPEAT, BUTTON_BACK },
{ ACTION_STD_CANCEL, BUTTON_BACK|BUTTON_REL, BUTTON_BACK },
{ ACTION_STD_CANCEL, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_CANCEL, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
{ ACTION_STD_OK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
LAST_ITEM_IN_LIST
}; /* button_context_standard */
static const struct button_mapping button_context_wps[] = {
{ ACTION_WPS_PLAY, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_WPS_STOP, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_CONTEXT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_SKIPNEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
{ ACTION_WPS_SEEKFWD, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_SKIPPREV, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
{ ACTION_WPS_SEEKBACK, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_STOPSEEK, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT|BUTTON_REPEAT },
{ ACTION_WPS_STOPSEEK, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT|BUTTON_REPEAT },
{ ACTION_WPS_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_UP, BUTTON_NONE },
{ ACTION_WPS_VOLUP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_WPS_VOLDOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_WPS_MENU, BUTTON_BACK|BUTTON_REL, BUTTON_BACK },
{ ACTION_WPS_QUICKSCREEN, BUTTON_BACK|BUTTON_REPEAT, BUTTON_BACK },
{ ACTION_WPS_BROWSE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_wps */
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_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_KBD_RIGHT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_UP, BUTTON_NONE },
{ ACTION_KBD_UP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_KBD_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_BACKSPACE, BUTTON_BACK, BUTTON_NONE },
{ ACTION_KBD_BACKSPACE, BUTTON_BACK|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_KBD_SELECT, BUTTON_PLAYPAUSE, BUTTON_NONE },
{ ACTION_KBD_DONE, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
{ ACTION_KBD_ABORT, BUTTON_POWER, BUTTON_NONE },
{ ACTION_KBD_MORSE_INPUT, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_KBD_MORSE_SELECT, BUTTON_VOL_DOWN|BUTTON_REL, BUTTON_NONE },
LAST_ITEM_IN_LIST
}; /* button_context_keyboard */
static const struct button_mapping button_context_quickscreen[] = {
{ 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 },
{ ACTION_QS_TOP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_QS_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_QS_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ 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 },
LAST_ITEM_IN_LIST
}; /* button_context_quickscreen */
static const struct button_mapping button_context_tree[] = {
{ ACTION_TREE_WPS, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_TREE_STOP, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST)
}; /* button_context_tree */
static const struct button_mapping button_context_list[] = {
#ifdef HAVE_VOLUME_IN_LIST
{ ACTION_LIST_VOLUP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_LIST_VOLUP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_LIST_VOLDOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
#endif
/*#ifdef HAVE_HOTKEY on some gesture later?
{ ACTION_TREE_HOTKEY, BUTTON_BACK|BUTTON_REL, BUTTON_BACK|BUTTON_REPEAT },
#endif*/
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_list */
#ifdef CONFIG_TUNER
static const struct button_mapping button_context_radio[] = {
{ ACTION_FM_MENU, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_FM_PLAY, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_FM_STOP, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_INC, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_FM_EXIT, BUTTON_BACK, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
}; /* button_context_radio */
#endif
#ifdef HAVE_RECORDING
static const struct button_mapping button_context_recscreen[] = {
{ ACTION_REC_PAUSE, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_SETTINGS_INC, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_recscreen */
#endif
static const struct button_mapping button_context_settings[] = {
/* we overwrite this to avoid select from std */
{ ACTION_NONE, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
{ ACTION_SETTINGS_INC, BUTTON_UP, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_settings */
static const struct button_mapping button_context_settings_right_is_inc[] = {
{ ACTION_SETTINGS_INC, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_SETTINGS_INCREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_SETTINGS_DEC, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_SETTINGS_DECREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_PREV, BUTTON_UP, BUTTON_NONE },
{ ACTION_STD_PREVREPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_STD_NEXT, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_STD_NEXTREPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
}; /* button_context_settingsgraphical */
static const struct button_mapping button_context_time[] = {
{ ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE },
{ ACTION_STD_OK, BUTTON_PLAYPAUSE, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
}; /* button_context_time */
static const struct button_mapping button_context_colorchooser[] = {
{ ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
{ ACTION_STD_CANCEL, BUTTON_BACK, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS),
}; /* button_context_colorchooser */
static const struct button_mapping button_context_eq[] = {
{ ACTION_STD_OK, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_CUSTOM|CONTEXT_SETTINGS),
}; /* button_context_eq */
/* Bookmark Screen */
static const struct button_mapping button_context_bmark[] = {
{ ACTION_BMS_DELETE, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_LIST),
}; /* button_context_bmark */
static const struct button_mapping button_context_pitchscreen[] = {
{ ACTION_PS_INC_SMALL, BUTTON_UP, BUTTON_NONE },
{ ACTION_PS_INC_BIG, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_PS_DEC_SMALL, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_PS_DEC_BIG, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_PS_NUDGE_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ 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_PLAYPAUSE, BUTTON_NONE },
{ ACTION_PS_RESET, BUTTON_SELECT, BUTTON_NONE },
{ ACTION_PS_EXIT, BUTTON_BACK, BUTTON_NONE },
{ 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)
}; /* button_context_pitchcreen */
static const struct button_mapping button_context_yesno[] = {
{ ACTION_YESNO_ACCEPT, BUTTON_SELECT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
}; /* button_context_yesno */
#ifdef USB_ENABLE_HID
static const struct button_mapping button_context_usb_hid[] = {
{ ACTION_USB_HID_MODE_SWITCH_NEXT, BUTTON_POWER|BUTTON_REL, BUTTON_POWER },
{ ACTION_USB_HID_MODE_SWITCH_PREV, BUTTON_POWER|BUTTON_REPEAT, BUTTON_POWER },
LAST_ITEM_IN_LIST
}; /* button_context_usb_hid */
static const struct button_mapping button_context_usb_hid_mode_multimedia[] = {
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_UP, BUTTON_UP, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_UP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_DOWN, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_DOWN, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_UP, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_UP, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_MUTE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT },
{ ACTION_USB_HID_MULTIMEDIA_VOLUME_MUTE, BUTTON_BACK|BUTTON_REL, BUTTON_BACK },
{ ACTION_USB_HID_MULTIMEDIA_PLAYBACK_PLAY_PAUSE, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_USB_HID_MULTIMEDIA_PLAYBACK_STOP, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_PLAYPAUSE },
{ ACTION_USB_HID_MULTIMEDIA_PLAYBACK_TRACK_PREV, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
{ ACTION_USB_HID_MULTIMEDIA_PLAYBACK_TRACK_NEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
}; /* button_context_usb_hid_mode_multimedia */
static const struct button_mapping button_context_usb_hid_mode_presentation[] = {
{ ACTION_USB_HID_PRESENTATION_SLIDESHOW_START, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_USB_HID_PRESENTATION_SLIDESHOW_LEAVE, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_PLAYPAUSE },
{ ACTION_USB_HID_PRESENTATION_SLIDE_PREV, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
{ ACTION_USB_HID_PRESENTATION_SLIDE_NEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
{ ACTION_USB_HID_PRESENTATION_SLIDE_FIRST, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_PRESENTATION_SLIDE_LAST, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_PRESENTATION_LINK_PREV, BUTTON_UP, BUTTON_NONE },
{ ACTION_USB_HID_PRESENTATION_LINK_PREV, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_PRESENTATION_LINK_NEXT, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_PRESENTATION_LINK_NEXT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_PRESENTATION_MOUSE_CLICK, BUTTON_SELECT, BUTTON_SELECT },
{ ACTION_USB_HID_PRESENTATION_MOUSE_OVER, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
}; /* button_context_usb_hid_mode_presentation */
static const struct button_mapping button_context_usb_hid_mode_browser[] = {
{ ACTION_USB_HID_BROWSER_SCROLL_UP, BUTTON_UP, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_SCROLL_UP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_SCROLL_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_SCROLL_DOWN, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_ZOOM_IN, BUTTON_VOL_UP, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_ZOOM_IN, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_ZOOM_OUT, BUTTON_VOL_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_ZOOM_OUT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_ZOOM_RESET, BUTTON_PLAYPAUSE|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_BROWSER_TAB_PREV, BUTTON_LEFT|BUTTON_REL, BUTTON_LEFT },
{ ACTION_USB_HID_BROWSER_TAB_NEXT, BUTTON_RIGHT|BUTTON_REL, BUTTON_RIGHT },
{ ACTION_USB_HID_BROWSER_TAB_CLOSE, BUTTON_BACK|BUTTON_REPEAT, BUTTON_BACK },
{ ACTION_USB_HID_BROWSER_HISTORY_BACK, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_LEFT },
{ ACTION_USB_HID_BROWSER_HISTORY_FORWARD, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_RIGHT },
{ ACTION_USB_HID_BROWSER_VIEW_FULL_SCREEN, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_SELECT },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
}; /* button_context_usb_hid_mode_browser */
#ifdef HAVE_USB_HID_MOUSE
static const struct button_mapping button_context_usb_hid_mode_mouse[] = {
{ ACTION_USB_HID_MOUSE_UP, BUTTON_UP, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_UP_REP, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_DOWN_REP, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_LEFT_REP, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_RIGHT_REP, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_BUTTON_LEFT, BUTTON_SELECT, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_BUTTON_LEFT_REL, BUTTON_SELECT|BUTTON_REL, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_BUTTON_RIGHT, BUTTON_PLAYPAUSE, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_BUTTON_RIGHT_REL, BUTTON_PLAYPAUSE|BUTTON_REL, BUTTON_PLAYPAUSE },
{ ACTION_USB_HID_MOUSE_WHEEL_SCROLL_UP, BUTTON_BACK, BUTTON_NONE },
{ ACTION_USB_HID_MOUSE_WHEEL_SCROLL_UP, BUTTON_BACK|BUTTON_REPEAT, BUTTON_NONE },
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_USB_HID)
}; /* button_context_usb_hid_mode_mouse */
#endif
#endif /* USB_ENABLE_HID */
/* 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)
{
case CONTEXT_STD:
return button_context_standard;
case CONTEXT_MAINMENU:
return button_context_tree;
case CONTEXT_SETTINGS:
return button_context_settings;
case CONTEXT_WPS:
return button_context_wps;
case CONTEXT_YESNOSCREEN:
return button_context_yesno;
case CONTEXT_SETTINGS_TIME:
return button_context_time;
case CONTEXT_KEYBOARD:
case CONTEXT_MORSE_INPUT:
return button_context_keyboard;
#ifdef CONFIG_TUNER
case CONTEXT_FM:
return button_context_radio;
#endif
case CONTEXT_LIST:
return button_context_list;
case CONTEXT_TREE:
return button_context_tree;
case CONTEXT_SETTINGS_EQ:
return button_context_eq;
#ifdef HAVE_RECORDING
case CONTEXT_RECSCREEN:
return button_context_recscreen;
#endif
case CONTEXT_QUICKSCREEN:
return button_context_quickscreen;
case CONTEXT_BOOKMARKSCREEN:
return button_context_bmark;
case CONTEXT_PITCHSCREEN:
return button_context_pitchscreen;
case CONTEXT_SETTINGS_COLOURCHOOSER:
return button_context_colorchooser;
case CONTEXT_SETTINGS_RECTRIGGER:
return button_context_settings_right_is_inc;
case CONTEXT_CUSTOM|CONTEXT_SETTINGS:
return button_context_settings_right_is_inc;
#ifdef USB_ENABLE_HID
case CONTEXT_USB_HID:
return button_context_usb_hid;
case CONTEXT_USB_HID_MODE_MULTIMEDIA:
return button_context_usb_hid_mode_multimedia;
case CONTEXT_USB_HID_MODE_PRESENTATION:
return button_context_usb_hid_mode_presentation;
case CONTEXT_USB_HID_MODE_BROWSER:
return button_context_usb_hid_mode_browser;
#ifdef HAVE_USB_HID_MOUSE
case CONTEXT_USB_HID_MODE_MOUSE:
return button_context_usb_hid_mode_mouse;
#endif
#endif /* USB_ENABLE_HID */
default:
return button_context_standard;
}
return button_context_standard;
}

View file

@ -1,4 +1,3 @@
afrikaans.lang
basque.lang
bulgarian.lang
catala.lang
@ -38,7 +37,6 @@ tagalog.lang
turkce.lang
ukrainian.lang
vlaams.lang
wallisertitsch.lang
walon.lang
arabic.lang
chinese-simp.lang

View file

@ -1,998 +0,0 @@
# __________ __ ___.
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
# $Id$
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
# KIND, either express or implied.
#
# Afrikaans language file, translated by:
# - Rian van Staden
<phrase>
id: LANG_SET_BOOL_YES
desc: bool true representation
user: core
<source>
*: "Yes"
</source>
<dest>
*: "Ja"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SET_BOOL_NO
desc: bool false representation
user: core
<source>
*: "No"
</source>
<dest>
*: "Nee"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_ON
desc: Used in a lot of places
user: core
<source>
*: "On"
</source>
<dest>
*: "Aan"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_OFF
desc: Used in a lot of places
user: core
<source>
*: "Off"
</source>
<dest>
*: "Af"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SOUND_SETTINGS
desc: in the main menu
user: core
<source>
*: "Sound Settings"
</source>
<dest>
*: "Klank Opsies"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_GENERAL_SETTINGS
desc: in the main menu
user: core
<source>
*: "General Settings"
</source>
<dest>
*: "Algemene Opsies"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_VOLUME
desc: in sound_settings
user: core
<source>
*: "Volume"
</source>
<dest>
*: "Volume"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_BASS
desc: in sound_settings
user: core
<source>
*: "Bass"
</source>
<dest>
*: "Bas"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_TREBLE
desc: in sound_settings
user: core
<source>
*: "Treble"
</source>
<dest>
*: "Hoog"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_BALANCE
desc: in sound_settings
user: core
<source>
*: "Balance"
</source>
<dest>
*: "Balans"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_CHANNEL_STEREO
desc: in sound_settings
user: core
<source>
*: "Stereo"
</source>
<dest>
*: "Stereo"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_CHANNEL_MONO
desc: in sound_settings
user: core
<source>
*: "Mono"
</source>
<dest>
*: "Mono"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_CHANNEL_LEFT
desc: in sound_settings
user: core
<source>
*: "Mono Left"
</source>
<dest>
*: "Mono Links"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_CHANNEL_RIGHT
desc: in sound_settings
user: core
<source>
*: "Mono Right"
</source>
<dest>
*: "Mono Regs"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_LOUDNESS
desc: in sound_settings
user: core
<source>
*: "Loudness"
</source>
<dest>
*: "Luid"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_AUTOVOL
desc: in sound_settings
user: core
<source>
*: "Auto Volume"
</source>
<dest>
*: "Auto Volume"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_DECAY
desc: in sound_settings
user: core
<source>
*: "AV Decay Time"
</source>
<dest>
*: "AV Terugloop"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PLAYBACK
desc: in settings_menu()
user: core
<source>
*: "Playback"
</source>
<dest>
*: "Speel"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_FILE
desc: in settings_menu()
user: core
<source>
*: "File View"
</source>
<dest>
*: "Lêers"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_DISPLAY
desc: in settings_menu()
user: core
<source>
*: "Display"
</source>
<dest>
*: "Skerm"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SYSTEM
desc: in settings_menu()
user: core
<source>
*: "System"
</source>
<dest>
*: "Stelsel"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_RESET
desc: in system_settings_menu()
user: core
<source>
*: "Reset settings"
</source>
<dest>
*: "Stel Opsies Terug"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_RESET_DONE_CLEAR
desc: visual confirmation after settings reset
user: core
<source>
*: "Cleared"
</source>
<dest>
*: "Skoon"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_VERSION
desc: in the main menu
user: core
<source>
*: "Version"
</source>
<dest>
*: "Weergawe"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_DEBUG
desc: in the main menu
user: core
<source>
*: "Debug (keep out!)"
</source>
<dest>
*: "OntGogga"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SHUFFLE
desc: in settings_menu
user: core
<source>
*: "Shuffle"
</source>
<dest>
*: "Skommel"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_REPEAT
desc: in settings_menu
user: core
<source>
*: "Repeat"
</source>
<dest>
*: "Herhaal"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_REPEAT_ONE
desc: repeat one song
user: core
<source>
*: "One"
</source>
<dest>
*: "Een"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PLAY_SELECTED
desc: in settings_menu
user: core
<source>
*: "Play Selected First"
</source>
<dest>
*: "Speel Keuse Eerste"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SORT_CASE
desc: in settings_menu
user: core
<source>
*: "Sort Case Sensitive"
</source>
<dest>
*: "Sorteer groot/klein"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_FILTER
desc: setting name for dir filter
user: core
<source>
*: "Show Files"
</source>
<dest>
*: "Wys Lêers"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_FILTER_SUPPORTED
desc: show all file types supported by Rockbox
user: core
<source>
*: "Supported"
</source>
<dest>
*: "Ondersteunde"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_FILTER_MUSIC
desc: show only music-related files
user: core
<source>
*: "Music"
</source>
<dest>
*: "Musiek"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_FOLLOW
desc: in settings_menu
user: core
<source>
*: "Follow Playlist"
</source>
<dest>
*: "Volg Speellys"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SCROLL_MENU
desc: in display_settings_menu()
user: core
<source>
*: "Scroll Speed"
</source>
<dest>
*: "Rol Spoed"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PM_MENU
desc: in the display menu
user: core
<source>
*: "Peak Meter"
</source>
<dest>
*: "Piek Meter"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_POWEROFF_IDLE
desc: in settings_menu
user: core
<source>
*: "Idle Poweroff"
</source>
<dest>
*: "Auto Krag Af"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_FFRW_STEP
desc: in settings_menu
user: core
<source>
*: "FF/RW Min Step"
</source>
<dest>
*: "FF/RW Min Stap"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_FFRW_ACCEL
desc: in settings_menu
user: core
<source>
*: "FF/RW Accel"
</source>
<dest>
*: "FF/RW versnelling"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_BACKLIGHT
desc: in settings_menu
user: core
<source>
*: "Backlight"
</source>
<dest>
*: "Lig"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_BACKLIGHT_ON_WHEN_CHARGING
desc: in display_settings_menu
user: core
<source>
*: "Backlight on When Plugged"
</source>
<dest>
*: "Beligting Tydens Laai"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_CONTRAST
desc: in settings_menu
user: core
<source>
*: "Contrast"
</source>
<dest>
*: "Kontras"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SCROLL
desc: in settings_menu
user: core
<source>
*: "Scroll Speed Setting Example"
</source>
<dest>
*: "Rol Spoed Opsie Voorbeeld 12345"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SCROLL_BAR
desc: display menu, F3 substitute
user: core
<source>
*: "Scroll Bar"
</source>
<dest>
*: "Rol balk"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_STATUS_BAR
desc: display menu, F3 substitute
user: core
<source>
*: "Status Bar"
</source>
<dest>
*: "Status balk"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PM_RELEASE
desc: in the peak meter menu
user: core
<source>
*: "Peak Release"
</source>
<dest>
*: "Piek Terugloop"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PM_PEAK_HOLD
desc: in the peak meter menu
user: core
<source>
*: "Peak Hold Time"
</source>
<dest>
*: "Pieke Vashou"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PM_CLIP_HOLD
desc: in the peak meter menu
user: core
<source>
*: "Clip Hold Time"
</source>
<dest>
*: "Clip Vashou"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PM_ETERNAL
desc: in the peak meter menu
user: core
<source>
*: "Eternal"
</source>
<dest>
*: "Altyd"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SPINDOWN
desc: in settings_menu
user: core
<source>
*: "Disk Spindown"
</source>
<dest>
*: "Disk stoptyd"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_TIME
desc: in settings_menu
user: core
<source>
*: "Set Time/Date"
</source>
<dest>
*: "Stel Tyd/Datum"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_ROCKBOX_INFO
desc: displayed topmost on the info screen
user: core
<source>
*: "Rockbox Info:"
</source>
<dest>
*: "Inligting:"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_BATTERY_CHARGE
desc: tells that the battery is charging, instead of battery level
user: core
<source>
*: "Battery: charging"
</source>
<dest>
*: "Battery: laai"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PITCH_UP
desc: in wps
user: core
<source>
*: "Pitch up"
</source>
<dest>
*: "Versnel"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PITCH_DOWN
desc: in wps
user: core
<source>
*: "Pitch down"
</source>
<dest>
*: "Vertraag"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PAUSE
desc: in wps
user: core
<source>
*: "Pause"
</source>
<dest>
*: "Pause"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_TIME_REVERT
desc: used in set_time()
user: core
<source>
*: "OFF to revert"
</source>
<dest>
*: "OFF kanselleer"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_ID3_TITLE
desc: in wps
user: core
<source>
*: "Title"
</source>
<dest>
*: "Titel"
</dest>
<voice>
*: "Titel"
</voice>
</phrase>
<phrase>
id: LANG_ID3_ARTIST
desc: in wps
user: core
<source>
*: "Artist"
</source>
<dest>
*: "Kunstenaar"
</dest>
<voice>
*: "Kunstenaar"
</voice>
</phrase>
<phrase>
id: LANG_ID3_ALBUM
desc: in wps
user: core
<source>
*: "Album"
</source>
<dest>
*: "Album"
</dest>
<voice>
*: "Album"
</voice>
</phrase>
<phrase>
id: LANG_ID3_TRACKNUM
desc: in wps
user: core
<source>
*: "Tracknum"
</source>
<dest>
*: "Liednommer"
</dest>
<voice>
*: "Liednommer"
</voice>
</phrase>
<phrase>
id: LANG_ID3_PLAYLIST
desc: in wps
user: core
<source>
*: "Playlist"
</source>
<dest>
*: "Speellys"
</dest>
<voice>
*: "Speellys"
</voice>
</phrase>
<phrase>
id: LANG_ID3_BITRATE
desc: in wps
user: core
<source>
*: "Bitrate"
</source>
<dest>
*: "Bitrate"
</dest>
<voice>
*: "Bitrate"
</voice>
</phrase>
<phrase>
id: LANG_ID3_FREQUENCY
desc: in wps
user: core
<source>
*: "Frequency"
</source>
<dest>
*: "Frekwensie"
</dest>
<voice>
*: "Frekwensie"
</voice>
</phrase>
<phrase>
id: LANG_ID3_PATH
desc: in wps
user: core
<source>
*: "Path"
</source>
<dest>
*: "Pad"
</dest>
<voice>
*: "Pad"
</voice>
</phrase>
<phrase>
id: LANG_PLAYLIST_BUFFER_FULL
desc: in playlist.indices() when playlist is full
user: core
<source>
*: "Playlist buffer full"
</source>
<dest>
*: "Speellys buffer vol"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SHOWDIR_BUFFER_FULL
desc: in showdir(), displayed on screen when you reach buffer limit
user: core
<source>
*: "Dir Buffer is full!"
</source>
<dest>
*: "Buffer is vol!!"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_LANGUAGE_LOADED
desc: shown when a language has been loaded from the dir browser
user: core
<source>
*: "new language"
</source>
<dest>
*: "Nuwe Taal"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SYSFONT_CHANNEL_STEREO
desc: in sound_settings
user: core
<source>
*: "Stereo"
</source>
<dest>
*: "Stereo"
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_SYSFONT_CHANNEL_MONO
desc: in sound_settings
user: core
<source>
*: "Mono"
</source>
<dest>
*: "Mono"
</dest>
<voice>
*: ""
</voice>
</phrase>

View file

@ -12511,20 +12511,6 @@
*: "平均比特率"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "收集信息时出错"
</dest>
<voice>
*: "收集信息时出错"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15837,20 +15823,6 @@
*: "默认浏览器"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Amaze 主菜单"
</dest>
<voice>
*: "Amaze 主菜单"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16103,34 +16075,6 @@
*: "Mikmod 设置"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Mikmod 菜单"
</dest>
<voice>
*: "Mikmod 菜单"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Chessbox 菜单"
</dest>
<voice>
*: "Chess box 菜单"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16992,3 +16936,20 @@
usbdac: "USB-DAC 工作中"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "使用LED指示灯"
</dest>
<voice>
*: none
general_purpose_led: "使用 L E D 指示灯"
</voice>
</phrase>

View file

@ -12632,20 +12632,6 @@
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Fehler beim Sammeln von Informationen"
</dest>
<voice>
*: "Fehler beim Sammeln von Informationen"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_LEVEL_7
desc: in the chessbox game level selection
@ -15848,20 +15834,6 @@
*: "Standardbrowser"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Amaze Hauptmenü"
</dest>
<voice>
*: "Amaze Hauptmenü"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16128,34 +16100,6 @@
*: "Mik mod Einstellungen"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Mikmod Menü"
</dest>
<voice>
*: "Mik mod Menü"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Schachbox Menü"
</dest>
<voice>
*: "Schach box Menü"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -17003,3 +16947,20 @@
usbdac: "USB-Digital Analog Wandler Aktiv"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "LED Indikatoren verwenden"
</dest>
<voice>
*: none
general_purpose_led: "LED Indikatoren verwenden"
</voice>
</phrase>

View file

@ -12501,20 +12501,6 @@
*: "Average bit rate"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Error while gathering info"
</dest>
<voice>
*: "Error while gathering info"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15826,20 +15812,6 @@
*: "Default Browser"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Amaze Main Menu"
</dest>
<voice>
*: "Amaze Main Menu"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16092,34 +16064,6 @@
*: "Mik mod Settings"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Mikmod Menu"
</dest>
<voice>
*: "Mik mod Menu"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Chessbox Menu"
</dest>
<voice>
*: "Chess box Menu"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16981,3 +16925,20 @@
usbdac: "USB-DAC Active"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Use LED indicators"
</dest>
<voice>
*: none
general_purpose_led: "Use LED indicators"
</voice>
</phrase>

View file

@ -16998,3 +16998,20 @@
*: "sort playlists"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Use LED indicators"
</dest>
<voice>
*: none
general_purpose_led: "Use LED indicators"
</voice>
</phrase>

View file

@ -12626,20 +12626,6 @@
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Erreur lors de la collecte d'informations"
</dest>
<voice>
*: "Erreur lors de la collecte d'informations"
</voice>
</phrase>
<phrase>
id: VOICE_QUEEN
desc: spoken only, for announcing chess piece names
@ -15966,20 +15952,6 @@
*: "Navigateur par défaut"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Menu Principale de Amaze"
</dest>
<voice>
*: "Menu Principale de Amaze"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16232,34 +16204,6 @@
*: "Paramètres de Mik mod"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Menu de Mikmod"
</dest>
<voice>
*: "Menu de Mikmod"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Menu de Chessbox"
</dest>
<voice>
*: "Menu de Chessbox"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16937,11 +16881,11 @@
</source>
<dest>
*: none
usbdac: "USB-DAC"
usbdac: "~USB-DAC"
</dest>
<voice>
*: none
usbdac: "USB-DAC"
usbdac: "~USB-DAC"
</voice>
</phrase>
<phrase>

View file

@ -13443,20 +13443,6 @@
*: "Opzioni del display"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Errore durante la raccolta delle informazioni"
</dest>
<voice>
*: "Errore durante la raccolta delle informazioni"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU_RESTORE_GAME
desc: in the chessbox menu
@ -15830,20 +15816,6 @@
*: "Browser Predefinito"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Menu Principale Labirinto"
</dest>
<voice>
*: "Menu Principale Labirinto"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16110,34 +16082,6 @@
*: "Impostazioni Mik mod"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Menu Mikmod"
</dest>
<voice>
*: "Menu Mik mod"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Menu Chessbox"
</dest>
<voice>
*: "Menu Chess box"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16985,3 +16929,20 @@
usbdac: "DAC-USB Attivo"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Usa indicatori led"
</dest>
<voice>
*: none
general_purpose_led: "Usa indicatori led"
</voice>
</phrase>

View file

@ -12519,20 +12519,6 @@
*: "평균 비트 전송률"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "정보 수집 중 오류 발생"
</dest>
<voice>
*: "정보 수집 중 오류 발생"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15844,20 +15830,6 @@
*: "기본 탐색기"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Amaze 메인 메뉴"
</dest>
<voice>
*: "Amaze 메인 메뉴"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16110,34 +16082,6 @@
*: "Mik 모드 설정"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Mik모드 메뉴"
</dest>
<voice>
*: "Mik 모드 메뉴"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "체스박스메뉴"
</dest>
<voice>
*: "체스 박스 메뉴"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16999,3 +16943,20 @@
usbdac: "USB-DAC 켜짐"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "LED 표시기 사용"
</dest>
<voice>
*: none
general_purpose_led: "LED 표시기 사용"
</voice>
</phrase>

View file

@ -57,7 +57,11 @@ $(BUILDDIR)/apps/lang/voice-corrections.txt: $(ROOTDIR)/tools/voice-corrections.
$(SILENT)mkdir -p $(dir $@)
$(call PRINTS,CP $(subst $(ROOTDIR)/,,$<))cp $< $@
$(BUILDDIR)/apps/lang/voicestrings.zip: $(VOICEOBJ) $(wildcard $(BUILDDIR)/apps/lang/*.talk) $(BUILDDIR)/apps/lang/voice-corrections.txt
$(BUILDDIR)/apps/lang/lang-enum.txt: $(BUILDDIR)/lang_enum.h
$(SILENT)mkdir -p $(dir $@)
$(call PRINTS,GEN $(subst $(BUILDDIR)/,,$@))perl -ne 'print if s|\s+(.*), /\* (\w+).*|$$2:$$1|' < $< |grep -v 'this:' > $@
$(BUILDDIR)/apps/lang/voicestrings.zip: $(VOICEOBJ) $(wildcard $(BUILDDIR)/apps/lang/*.talk) $(BUILDDIR)/apps/lang/voice-corrections.txt $(BUILDDIR)/apps/lang/lang-enum.txt
$(call PRINTS,ZIP $(subst $(BUILDDIR)/,,$@))
$(SILENT)zip -9 -q $@ $(subst $(BUILDDIR)/,,$^)

View file

@ -12616,20 +12616,6 @@
*: "Vidējais bitu pārraides ātrums"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Kļūda iegūstot informāciju"
</dest>
<voice>
*: "Kļūda iegūstot informāciju"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15941,20 +15927,6 @@
*: "Noklusējuma pārlūks"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Amaze galvenā izvēlne"
</dest>
<voice>
*: "Amaze galvenā izvēlne"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16207,34 +16179,6 @@
*: "Mik mod iestatījumi"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Mikmod izvēlne"
</dest>
<voice>
*: "Mik mod izvēlne"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Chessbox izvēlne"
</dest>
<voice>
*: "Chessbox izvēlne"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16984,3 +16928,20 @@
usbdac: "USB DAC ir ieslēgts"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Izmantot LED indikatorus"
</dest>
<voice>
*: none
general_purpose_led: "Izmantot LED indikatorus"
</voice>
</phrase>

View file

@ -12619,20 +12619,6 @@
*: "Átlagos bitráta"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Hiba információgyűjtés közben"
</dest>
<voice>
*: "Hiba információgyűjtés közben"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15944,20 +15930,6 @@
*: "Alapértelmezett böngésző"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Amaze főmenü"
</dest>
<voice>
*: "Amaze főmenü"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16210,34 +16182,6 @@
*: "Mik mod beállítások"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Mikmod menü"
</dest>
<voice>
*: "Mik mod menü"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Chessbox menü"
</dest>
<voice>
*: "Chess box menü"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16987,3 +16931,20 @@
usbdac: "USB-DAC aktív"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "LED jelzőfények használata"
</dest>
<voice>
*: none
general_purpose_led: "LED jelzőfények használata"
</voice>
</phrase>

View file

@ -12622,20 +12622,6 @@
*: "Rată de biți medie"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Eroare la colectarea informațiilor"
</dest>
<voice>
*: "Eroare la colectarea informațiilor"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15947,20 +15933,6 @@
*: "Navigator implicit"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Meniu principal Amaze"
</dest>
<voice>
*: "Meniu principal a meiz"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16213,34 +16185,6 @@
*: "Setări miki mod"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Meniu Mikmod"
</dest>
<voice>
*: "Meniu miki mod"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Meniu Chessbox "
</dest>
<voice>
*: "Meniu ces boks"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16922,3 +16866,88 @@
*: "Toate pistele sortate după album"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC
desc: in settings_menu
user: core
<source>
*: none
usbdac: "USB-DAC"
</source>
<dest>
*: none
usbdac: "DAC USB"
</dest>
<voice>
*: none
usbdac: "dac u se be"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_USB_CHARGE_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Charge-Only Mode"
</source>
<dest>
*: none
usbdac: "Cînd este în modul de încrăcare USB"
</dest>
<voice>
*: none
usbdac: "Cînd este în modul de încrăcare u se be"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_MASS_STORAGE_USB_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Mass-Storage Mode"
</source>
<dest>
*: none
usbdac: "Cînd este în modul de stocare în masă USB"
</dest>
<voice>
*: none
usbdac: "Cînd este în modul de stocare în masă u se be"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC_ACTIVE
desc: for splash
user: core
<source>
*: none
usbdac: "USB-DAC Active"
</source>
<dest>
*: none
usbdac: "DAC USB activ"
</dest>
<voice>
*: none
usbdac: "dac u se be activ"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Folosește indicatori LED"
</dest>
<voice>
*: none
general_purpose_led: "Folosește indicatori led"
</voice>
</phrase>

View file

@ -12270,20 +12270,6 @@
*: "Gemiddelde bit snelheid"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Fout bij het verzamelen van informatie"
</dest>
<voice>
*: "Fout bij het verzamelen van informatie"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15838,20 +15824,6 @@
*: "Standaard Browser"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Amaze Hoofdmenu"
</dest>
<voice>
*: "Amaze Hoofdmenu"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16230,34 +16202,6 @@
*: "Mik mod instellingen"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "~Mikmod Menu"
</dest>
<voice>
*: "Mik mod menu"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "~Chessbox Menu"
</dest>
<voice>
*: "Chess box menu"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16925,3 +16869,88 @@
*: "Afspeellijst sorteren"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC
desc: in settings_menu
user: core
<source>
*: none
usbdac: "USB-DAC"
</source>
<dest>
*: none
usbdac: "~USB-DAC"
</dest>
<voice>
*: none
usbdac: "~USB-DAC"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_USB_CHARGE_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Charge-Only Mode"
</source>
<dest>
*: none
usbdac: "Tijdens 'enkel opladen' USB-modus"
</dest>
<voice>
*: none
usbdac: "Tijdens 'enkel opladen' USB-modus"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_MASS_STORAGE_USB_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Mass-Storage Mode"
</source>
<dest>
*: none
usbdac: "Tijdens 'massaopslag' USB-modus"
</dest>
<voice>
*: none
usbdac: "Tijdens 'massaopslag' USB-modus"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC_ACTIVE
desc: for splash
user: core
<source>
*: none
usbdac: "USB-DAC Active"
</source>
<dest>
*: none
usbdac: "USB-DAC aktief"
</dest>
<voice>
*: none
usbdac: "USB-DAC aktief"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Gebruik LED-indicatoren"
</dest>
<voice>
*: none
general_purpose_led: "Gebruik LED-indicatoren"
</voice>
</phrase>

View file

@ -13289,20 +13289,6 @@
recording: "Katalog nagrań"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Błąd podczas zbierania informacji"
</dest>
<voice>
*: "Błąd podczas zbierania informacji"
</voice>
</phrase>
<phrase>
id: LANG_CONDITIONAL_START_MENU
desc: in mpegplayer menus
@ -15836,20 +15822,6 @@
*: "Przeglądarka domyślna"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Menu główne Amaze"
</dest>
<voice>
*: "Menu główne Amejz"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16102,34 +16074,6 @@
*: "Ustawienia Mykmod"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Menu Mikmod"
</dest>
<voice>
*: "Menu Mykmod"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Menu Chessbox"
</dest>
<voice>
*: "Menu Czesboks"
</voice>
</phrase>
<phrase>
id: VOICE_LANG_NAME
desc: Spoken name of the language
@ -16991,3 +16935,20 @@
usbdac: "dak uesbe aktywny"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Użyj wskaźników LED"
</dest>
<voice>
*: none
general_purpose_led: "Użyj wskaźników led"
</voice>
</phrase>

View file

@ -12622,20 +12622,6 @@
*: "Rată de biți medie"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Eroare la colectarea informațiilor"
</dest>
<voice>
*: "Eroare la colectarea informațiilor"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15947,20 +15933,6 @@
*: "Navigator implicit"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Meniu principal Amaze"
</dest>
<voice>
*: "Meniu principal a meiz"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16213,34 +16185,6 @@
*: "Setări miki mod"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Meniu Mikmod"
</dest>
<voice>
*: "Meniu miki mod"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Meniu Chessbox "
</dest>
<voice>
*: "Meniu ces boks"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16922,3 +16866,88 @@
*: "Toate pistele sortate după album"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC
desc: in settings_menu
user: core
<source>
*: none
usbdac: "USB-DAC"
</source>
<dest>
*: none
usbdac: "DAC USB"
</dest>
<voice>
*: none
usbdac: "dac u se be"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_USB_CHARGE_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Charge-Only Mode"
</source>
<dest>
*: none
usbdac: "Când este în modul de încrăcare USB"
</dest>
<voice>
*: none
usbdac: "Când este în modul de încrăcare u se be"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_MASS_STORAGE_USB_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Mass-Storage Mode"
</source>
<dest>
*: none
usbdac: "Când este în modul de stocare în masă USB"
</dest>
<voice>
*: none
usbdac: "Când este în modul de stocare în masă u se be"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC_ACTIVE
desc: for splash
user: core
<source>
*: none
usbdac: "USB-DAC Active"
</source>
<dest>
*: none
usbdac: "DAC USB activ"
</dest>
<voice>
*: none
usbdac: "dac u se be activ"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Folosește indicatori LED"
</dest>
<voice>
*: none
general_purpose_led: "Folosește indicatori led"
</voice>
</phrase>

View file

@ -13193,20 +13193,6 @@
lowmem: none
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Chyba pri zbere iinfo"
</dest>
<voice>
*: "Chyba pri zbere iinformácií"
</voice>
</phrase>
<phrase>
id: LANG_PROPERTIES_SUBDIRS
desc: in properties plugin
@ -15956,20 +15942,6 @@
*: "Predvolený prehliadač"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Hlavná ponuka Amazeu"
</dest>
<voice>
*: "Hlavná ponuka Amazeu"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16222,34 +16194,6 @@
*: "Nastavenia Mikmodu"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Ponuka Mikmodu"
</dest>
<voice>
*: "Ponuka Mikmodu"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Ponuka Chessboxu"
</dest>
<voice>
*: "Ponuka Chessboxu"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16985,3 +16929,20 @@
usbdac: "USB-DAC aktívny"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Používať LED indikátory"
</dest>
<voice>
*: none
general_purpose_led: "Používať LED indikátory"
</voice>
</phrase>

View file

@ -3363,57 +3363,6 @@
*: "Batterikapacitet"
</voice>
</phrase>
<phrase>
id: LANG_BATTERY_TYPE
desc: deprecated
user: core
<source>
*: none
battery_types: ""
</source>
<dest>
*: none
battery_types: ""
</dest>
<voice>
*: none
battery_types: ""
</voice>
</phrase>
<phrase>
id: LANG_BATTERY_TYPE_1
desc: deprecated
user: core
<source>
*: none
battery_types,xduoox3: ""
</source>
<dest>
*: none
battery_types,xduoox3: ""
</dest>
<voice>
*: none
battery_types,xduoox3: ""
</voice>
</phrase>
<phrase>
id: LANG_BATTERY_TYPE_2
desc: deprecated
user: core
<source>
*: none
battery_types,xduoox3: ""
</source>
<dest>
*: none
battery_types,xduoox3: ""
</dest>
<voice>
*: none
battery_types,xduoox3: ""
</voice>
</phrase>
<phrase>
id: LANG_DISK_MENU
desc: in the system sub menu
@ -3555,8 +3504,8 @@
<dest>
*: none
rtc: "PÅ = Ställ"
gigabeat*,iaudiom5,iaudiox5,ipod*,iriverh10,iriverh10_5gb,mrobe100,sansac200*,sansaclip*,sansaconnect,sansae200*,sansafuze*: "VÄLJ = Ställ"
aigoerosq,erosqnative,gogearsa9200,samsungyh*,xduoox3*: "SPELA = Ställ"
gigabeat*,iaudiom5,iaudiox5,ipod*,iriverh10,iriverh10_5gb,mrobe100,sansac200*,sansaclip*,sansaconnect,sansae200*,sansafuze*: "VÄLJ = Ställ"
iriverh100,iriverh120,iriverh300: "NAVI = Ställ"
mpiohd300: "ENTER = Ställ"
mrobe500: "HJÄRTA = Ställ"
@ -3564,7 +3513,6 @@
</dest>
<voice>
*: none
gigabeat*,gogearsa9200,iaudiom5,iaudiox5,ipod*,iriverh10,iriverh100,iriverh10_5gb,iriverh120,iriverh300,mrobe100,rtc,samsungyh*,sansac200*,sansae200*: ""
</voice>
</phrase>
<phrase>
@ -3588,8 +3536,8 @@
<dest>
*: none
rtc: "AV = Avbryt"
gigabeatfx,mrobe500: "PÅ/AV = Avbryt"
aigoerosq,erosqnative,gigabeats,sansafuzeplus,xduoox3*: "BAKÅT = Avbryt"
gigabeatfx,mrobe500: "PÅ/AV = Avbryt"
gogearsa9200: "VÄNSTER = Avbryt"
iaudiom5,iaudiox5: "SPELA IN = Avbryt"
ipod*,mpiohd300,sansac200*: "MENY = Avbryt"
@ -3601,7 +3549,6 @@
</dest>
<voice>
*: none
gigabeat*,gogearsa9200,iaudiom5,iaudiox5,ipod*,iriverh10,iriverh100,iriverh10_5gb,iriverh120,iriverh300,mrobe100,rtc,samsungyh*,sansac200*,sansae200*: ""
</voice>
</phrase>
<phrase>
@ -4679,7 +4626,7 @@
</dest>
<voice>
*: none
radio: ""
radio: "Söker vid MHz"
</voice>
</phrase>
<phrase>
@ -5791,20 +5738,6 @@
*: "sparade spår"
</voice>
</phrase>
<phrase>
id: LANG_CATALOG
desc: deprecated
user: core
<source>
*: ""
</source>
<dest>
*: ""
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_RECURSE_DIRECTORY
desc: In playlist menu
@ -7193,11 +7126,11 @@
*: "AV = avbryt"
gigabeatfx: "PÅ/AV = Avbryt"
gigabeats: "BAKÅT = Avbryt"
sansafuzeplus: "BACK för att avbryta"
iaudiom5,iaudiox5: "Lång SPELA = Avbryt"
ipod*: "SPELA/PAUSA = Avbryt"
iriverh10,iriverh10_5gb,sansac200*,sansae200*,vibe500: "FÖREGÅENDE = Avbryt"
iriverh100,iriverh120,iriverh300: "STOPP = Avbryt"
sansafuzeplus: "BACK för att avbryta"
</dest>
<voice>
*: ""
@ -7242,7 +7175,7 @@
*: "Kan inte öppna %s"
</dest>
<voice>
*: ""
*: "Kan inte öppna"
</voice>
</phrase>
<phrase>
@ -7256,7 +7189,7 @@
*: "Kan inte läsa %s"
</dest>
<voice>
*: ""
*: "Kan inte läsa"
</voice>
</phrase>
<phrase>
@ -12607,20 +12540,6 @@
*: "Spår är över"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_REMAINING
desc: deprecated
user: core
<source>
*: ""
</source>
<dest>
*: ""
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_TRK_REMAINING
desc: playing time screen
@ -12705,20 +12624,6 @@
*: "Genomsnittlig bithastighet"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Fel vid insamling av information"
</dest>
<voice>
*: "Fel vid insamling av information"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -14173,16 +14078,16 @@
</phrase>
<phrase>
id: LANG_TOGGLE_ITEM
desc: in main_menu_config
desc: deprecated
user: core
<source>
*: "Toggle Item"
*: ""
</source>
<dest>
*: "Växla objekt"
*: ""
</dest>
<voice>
*: "Växla objekt"
*: ""
</voice>
</phrase>
<phrase>
@ -14243,13 +14148,13 @@
</phrase>
<phrase>
id: LANG_MAIN_MENU_ORDER
desc: main_menu_config plugin title
desc: deprecated
user: core
<source>
*: "Rockbox Main Menu Order"
*: ""
</source>
<dest>
*: "Rockbox huvudmenyordning"
*: ""
</dest>
<voice>
*: ""
@ -14752,20 +14657,6 @@
*: "Inget albumomslag hittades"
</voice>
</phrase>
<phrase>
id: LANG_CACHE_REBUILT_NEXT_RESTART
desc: deprecated
user: core
<source>
*: ""
</source>
<dest>
*: ""
</dest>
<voice>
*: ""
</voice>
</phrase>
<phrase>
id: LANG_ERROR_WRITING_CONFIG
desc: in the pictureflow splash messages
@ -16044,20 +15935,6 @@
*: "Standardwebbläsare"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Amaze Huvudmeny"
</dest>
<voice>
*: "Amaze Huvudmeny"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16310,34 +16187,6 @@
*: "Mik mod Inställningar"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Mikmod meny"
</dest>
<voice>
*: "Mik mod meny"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Schackbox Meny"
</dest>
<voice>
*: "Schackbox Meny"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16991,3 +16840,116 @@
*: "Spellistan är klar. Spela igen?"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC
desc: in settings_menu
user: core
<source>
*: none
usbdac: "USB-DAC"
</source>
<dest>
*: none
usbdac: "~USB-DAC"
</dest>
<voice>
*: none
usbdac: "~USB-DAC"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_USB_CHARGE_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Charge-Only Mode"
</source>
<dest>
*: none
usbdac: "Vid USB-läge för endast laddning"
</dest>
<voice>
*: none
usbdac: "Vid USB-läge för endast laddning"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_MASS_STORAGE_USB_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Mass-Storage Mode"
</source>
<dest>
*: none
usbdac: "När USB-masslagringsläge är aktivt"
</dest>
<voice>
*: none
usbdac: "När USB-masslagringsläge är aktivt"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC_ACTIVE
desc: for splash
user: core
<source>
*: none
usbdac: "USB-DAC Active"
</source>
<dest>
*: none
usbdac: "USB-DAC Aktiv"
</dest>
<voice>
*: none
usbdac: "USB-DAC Aktiv"
</voice>
</phrase>
<phrase>
id: LANG_TAGNAVI_ALL_TRACKS_SORTED_BY_ALBUM
desc: "[By album]" entry in tag browser
user: core
<source>
*: "[By album]"
</source>
<dest>
*: "[Efter album]ä"
</dest>
<voice>
*: "Alla låtar sorterade efter album"
</voice>
</phrase>
<phrase>
id: LANG_SORT_PLAYLISTS
desc: playlists sorting setting
user: core
<source>
*: "Sort Playlists"
</source>
<dest>
*: "Sortera spellistor"
</dest>
<voice>
*: "Sortera spellistor"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Använd LED-indikatorer"
</dest>
<voice>
*: none
general_purpose_led: "Använd LED-indikatorer"
</voice>
</phrase>

View file

@ -3530,13 +3530,13 @@
*: none
aigoerosq,erosqnative,gigabeats,sansafuzeplus,xduoox3*: "НАЗАД = Скасувати"
gigabeatfx: "ЖИВЛЕННЯ = Скасувати"
mrobe500,rtc: "ВИМК. = Скасувати"
gogearsa9200: "ВЛIВО = Скасувати"
iaudiom5,iaudiox5: "ЗАПИС = Скасувати"
ipod*,mpiohd300,sansac200*: "МЕНЮ = Скасувати"
iriverh10,iriverh10_5gb,sansae200*,sansafuze*: "ПОПЕРЕД. = Скасувати"
iriverh100,iriverh120,iriverh300: "СТОП = Скасувати"
mrobe100: "ДИСПЛЕЙ = Скасувати"
mrobe500,rtc: "ВИМК. = Скасувати"
samsungyh*: "REW = Скасувати"
vibe500: "C = Скасувати"
</dest>
@ -7349,10 +7349,10 @@
*: "."
</source>
<dest>
*: "точка"
*: "~."
</dest>
<voice>
*: "точка"
*: "і"
</voice>
</phrase>
<phrase>
@ -12616,20 +12616,6 @@
*: "Середній бітрейт"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Помилка при зборі інформації"
</dest>
<voice>
*: "Помилка при зборі інформації"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15941,20 +15927,6 @@
*: "Браузер за замовчуванням"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Перетворити головне меню"
</dest>
<voice>
*: "Перетворити головне меню"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16207,34 +16179,6 @@
*: "Налаштування Mikmod"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Mikmod меню"
</dest>
<voice>
*: "Mikmod меню"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Меню шахової дошки"
</dest>
<voice>
*: "Меню шахової дошки"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16916,3 +16860,88 @@
*: "Сортувати усі треки по альбомах"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC
desc: in settings_menu
user: core
<source>
*: none
usbdac: "USB-DAC"
</source>
<dest>
*: none
usbdac: "USB аудіо"
</dest>
<voice>
*: none
usbdac: "ЮСБ аудіо"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_USB_CHARGE_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Charge-Only Mode"
</source>
<dest>
*: none
usbdac: "Тільки заряджання через USB"
</dest>
<voice>
*: none
usbdac: "Тільки заряджання через ЮСБ"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_MASS_STORAGE_USB_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Mass-Storage Mode"
</source>
<dest>
*: none
usbdac: "У режимі USB-накопичувача"
</dest>
<voice>
*: none
usbdac: "У режимі ЮСБ-накопичувача"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC_ACTIVE
desc: for splash
user: core
<source>
*: none
usbdac: "USB-DAC Active"
</source>
<dest>
*: none
usbdac: "Активний USB-ЦАП"
</dest>
<voice>
*: none
usbdac: "Активний ЮСБ-ЦАП"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Використати світлодіодні індикатори"
</dest>
<voice>
*: none
general_purpose_led: "Використати світлодіодні індикатори"
</voice>
</phrase>

View file

@ -12525,20 +12525,6 @@
*: "Bit rate trung bình"
</voice>
</phrase>
<phrase>
id: LANG_PLAYTIME_ERROR
desc: playing time screen
user: core
<source>
*: "Error while gathering info"
</source>
<dest>
*: "Lỗi khi thu thập thông tin"
</dest>
<voice>
*: "Lỗi khi thu thập thông tin"
</voice>
</phrase>
<phrase>
id: LANG_PLAYING_TIME
desc: onplay menu
@ -15850,20 +15836,6 @@
*: "Trình duyệt mặc định"
</voice>
</phrase>
<phrase>
id: LANG_AMAZE_MENU
desc: Amaze game
user: core
<source>
*: "Amaze Main Menu"
</source>
<dest>
*: "Menu chính của Amaze"
</dest>
<voice>
*: "Menu chính của Amaze"
</voice>
</phrase>
<phrase>
id: LANG_SET_MAZE_SIZE
desc: Maze size in Amaze game
@ -16116,34 +16088,6 @@
*: "Thiết lập Mik mod"
</voice>
</phrase>
<phrase>
id: LANG_MIKMOD_MENU
desc: mikmod plugin
user: core
<source>
*: "Mikmod Menu"
</source>
<dest>
*: "Menu Mikmod"
</dest>
<voice>
*: "Menu Mik mod"
</voice>
</phrase>
<phrase>
id: LANG_CHESSBOX_MENU
desc: chessbox plugin
user: core
<source>
*: "Chessbox Menu"
</source>
<dest>
*: "Menu Chessbox"
</dest>
<voice>
*: "Menu Chess box"
</voice>
</phrase>
<phrase>
id: VOICE_INVALID_VOICE_FILE
desc: played if the voice file fails to load
@ -16983,3 +16927,20 @@
usbdac: "USB-DAC đang hoạt động"
</voice>
</phrase>
<phrase>
id: LANG_USE_LED_INDICATORS
desc: LED indicators setting
user: core
<source>
*: none
general_purpose_led: "Use LED indicators"
</source>
<dest>
*: none
general_purpose_led: "Dùng đèn hiệu LED"
</dest>
<voice>
*: none
general_purpose_led: "Dùng đèn hiệu LED"
</voice>
</phrase>

File diff suppressed because it is too large Load diff

View file

@ -53,6 +53,7 @@
#include "viewport.h"
#include "quickscreen.h"
#include "shortcuts.h"
#include "statusbar-skinned.h"
#include "icons.h"
@ -197,9 +198,38 @@ static enum themable_icons menu_get_icon(int selected_item, void * data)
return menu_icon;
}
static char* init_title(const struct menu_item_ex *menu, int *icon,
char* buf, size_t buf_sz)
{
char *title;
if (menu->flags&MENU_HAS_DESC)
{
*icon = menu->callback_and_desc->icon_id;
title = P2STR(menu->callback_and_desc->desc);
}
else if (menu->flags&MENU_DYNAMIC_DESC)
{
*icon = menu->menu_get_name_and_icon->icon_id;
title = menu->menu_get_name_and_icon->
list_get_name(-1, menu->menu_get_name_and_icon->
list_get_name_data, buf, buf_sz);
}
else
{
*icon = Icon_NOICON;
title = "";
}
if (*icon == Icon_NOICON)
*icon = Icon_Submenu_Entered;
return title;
}
static int init_menu_lists(const struct menu_item_ex *menu,
struct gui_synclist *lists, int selected, bool callback,
struct viewport parent[NB_SCREENS])
struct viewport parent[NB_SCREENS], char* buf, size_t buf_sz)
{
if (!menu || !lists)
{
@ -236,28 +266,7 @@ static int init_menu_lists(const struct menu_item_ex *menu,
current_submenus_menu = (struct menu_item_ex *)menu;
gui_synclist_init(lists,get_menu_item_name,(void*)menu,false,1, parent);
if (menu->flags&MENU_HAS_DESC)
{
icon = menu->callback_and_desc->icon_id;
title = P2STR(menu->callback_and_desc->desc);
}
else if (menu->flags&MENU_DYNAMIC_DESC)
{
char buffer[80];
icon = menu->menu_get_name_and_icon->icon_id;
title = menu->menu_get_name_and_icon->
list_get_name(-1, menu->menu_get_name_and_icon->
list_get_name_data, buffer, sizeof(buffer));
}
else
{
icon = Icon_NOICON;
title = "";
}
if (icon == Icon_NOICON)
icon = Icon_Submenu_Entered;
title = init_title(menu, &icon, buf, buf_sz);
gui_synclist_set_title(lists, title, icon);
gui_synclist_set_icon_callback(lists, global_settings.show_icons?menu_get_icon:NULL);
if(global_settings.talk_menu)
@ -382,6 +391,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
int ret = 0;
int action;
int start_action;
int icon;
char buf[80], *title;
struct gui_synclist lists;
const struct menu_item_ex *temp = NULL;
const struct menu_item_ex *menu = start_menu;
@ -398,9 +409,12 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
touchscreen_set_mode(global_settings.touch_mode);
#endif
title = init_title(menu, &icon, buf, sizeof buf);
FOR_NB_SCREENS(i)
{
sb_set_persistent_title(title, icon, i);
viewportmanager_theme_enable(i, !hide_theme, NULL);
}
struct menu_data_t mstack[MAX_MENUS]; /* menu, selected */
int stack_top = 0;
@ -411,7 +425,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
* this function, e.g. with viewport_set_defaults(parent, screen)
* start_action allows an action to be processed
* by menu logic by bypassing get_action on the initial run */
start_action = init_menu_lists(menu, &lists, selected, true, parent);
start_action = init_menu_lists(menu, &lists, selected, true, parent,
buf, sizeof buf);
vps = *(lists.parent);
in_stringlist = ((menu->flags&MENU_TYPE_MASK) == MT_RETURN_ID);
/* load the callback, and only reload it if menu changes */
@ -472,7 +487,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
}
}
if (!done)
init_menu_lists(menu, &lists, lists.selected_item, false, vps);
init_menu_lists(menu, &lists, lists.selected_item, false, vps,
buf, sizeof buf);
redraw_lists = true;
}
#endif
@ -616,7 +632,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
if (!exiting_menu && (menu->flags&MENU_EXITAFTERTHISMENU))
done = true;
else
init_menu_lists(menu, &lists, msel, false, vps);
init_menu_lists(menu, &lists, msel, false, vps, buf, sizeof buf);
redraw_lists = true;
/* new menu, so reload the callback */
get_menu_callback(menu, &menu_callback);
@ -657,7 +673,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
mstack[stack_top].selected = selected;
stack_top++;
menu = temp;
init_menu_lists(menu, &lists, 0, true, vps);
init_menu_lists(menu, &lists, 0, true, vps, buf, sizeof buf);
}
break;
case MT_FUNCTION_CALL_W_PARAM:
@ -677,7 +693,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
(temp->flags&MENU_EXITAFTERTHISMENU))
{
/* Reload menu but don't run the calback again FS#8117 */
init_menu_lists(menu, &lists, selected, false, vps);
init_menu_lists(menu, &lists, selected, false, vps,
buf, sizeof buf);
}
if (temp->flags&MENU_FUNC_CHECK_RETVAL)
{
@ -693,7 +710,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
case MT_SETTING_W_TEXT:
{
do_setting_from_menu(temp, vps);
init_menu_lists(menu, &lists, selected, false, vps);
init_menu_lists(menu, &lists, selected, false, vps, buf, sizeof buf);
redraw_lists = true;
break;
@ -710,7 +727,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
mstack[stack_top].selected = selected;
stack_top++;
menu = temp;
init_menu_lists(menu,&lists,0,false, vps);
init_menu_lists(menu, &lists, 0, false, vps, buf, sizeof buf);
in_stringlist = true;
}
break;
@ -729,7 +746,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
menu_callback(ACTION_EXIT_MENUITEM, temp, &lists);
}
if (current_submenus_menu != menu)
init_menu_lists(menu,&lists,selected,true,vps);
init_menu_lists(menu, &lists,selected, true, vps, buf, sizeof buf);
/* callback was changed, so reload the menu's callback */
get_menu_callback(menu, &menu_callback);
if ((menu->flags&MENU_EXITAFTERTHISMENU) &&
@ -777,7 +794,8 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
if (stack_top > 0)
{
menu = mstack[0].menu;
init_menu_lists(menu,&lists,mstack[0].selected,true, vps);
init_menu_lists(menu, &lists, mstack[0].selected, true, vps,
buf, sizeof buf);
}
*start_selected = get_menu_selection(
gui_synclist_get_sel_pos(&lists), menu);
@ -785,6 +803,7 @@ int do_menu(const struct menu_item_ex *start_menu, int *start_selected,
FOR_NB_SCREENS(i)
{
sb_set_persistent_title(lists.title, lists.title_icon, i);
viewportmanager_theme_undo(i, false);
skinlist_set_cfg(i, NULL); /* Bugfix dangling reference in skin_draw() */
}

View file

@ -198,7 +198,8 @@ static int eq_do_simple_menu(void * param)
simplelist_info_init(&info, str(LANG_EQUALIZER_GAIN), EQ_NUM_BANDS, NULL);
info.get_name = (list_get_name*)gainitem_get_name;
info.get_talk = gainitem_speak_item;
if(global_settings.talk_menu)
info.get_talk = gainitem_speak_item;
info.get_icon = gainitem_get_icon;
info.action_callback = simplelist_action_callback;
info.selection = -1;
@ -362,7 +363,8 @@ static int eq_do_advanced_menu(void * param)
simplelist_info_init(&info, str(LANG_EQUALIZER_ADVANCED),
EQ_NUM_BANDS, &selected_band);
info.get_name = (list_get_name*)advancedmenu_item_get_name;
info.get_talk = advancedmenu_speak_item;
if(global_settings.talk_menu)
info.get_talk = advancedmenu_speak_item;
info.get_icon = advancedmenu_get_icon;
info.action_callback = simplelist_action_callback;
info.selection = -1;

View file

@ -272,6 +272,9 @@ MAKE_MENU(battery_menu, ID2P(LANG_BATTERY_MENU), 0, Icon_NOICON,
#if defined(DX50) || defined(DX90) || (defined(HAVE_USB_POWER) && !defined(USB_NONE) && !defined(SIMULATOR))
MENUITEM_SETTING(usb_mode, &global_settings.usb_mode, NULL);
#endif
#if defined(HAVE_GENERAL_PURPOSE_LED)
MENUITEM_SETTING(use_led_indicators, &global_settings.use_led_indicators, NULL);
#endif
/* Disk */
#ifdef HAVE_DISK_STORAGE
MENUITEM_SETTING(disk_spindown, &global_settings.disk_spindown, NULL);
@ -395,8 +398,8 @@ MENUITEM_SETTING(bt_selective_actions,
&global_settings.bt_selective_softlock_actions,
selectivesoftlock_callback);
MENUITEM_FUNCTION(sel_softlock_mask, 0, ID2P(LANG_SETTINGS),
selectivesoftlock_set_mask, selectivesoftlock_callback,
Icon_Menu_setting);
selectivesoftlock_set_mask, selectivesoftlock_callback,
Icon_Menu_setting);
MAKE_MENU(sel_softlock, ID2P(LANG_SOFTLOCK_SELECTIVE),
NULL, Icon_Menu_setting, &bt_selective_actions, &sel_softlock_mask);
@ -469,6 +472,9 @@ MAKE_MENU(system_menu, ID2P(LANG_SYSTEM),
#endif
#if defined(DX50) || defined(DX90) || (defined(HAVE_USB_POWER) && !defined(USB_NONE) && !defined(SIMULATOR))
&usb_mode,
#endif
#if defined(HAVE_GENERAL_PURPOSE_LED)
&use_led_indicators,
#endif
);

View file

@ -1277,13 +1277,13 @@ char* skip_whitespace(char* const str)
#if !defined(CHECKWPS) && !defined(DBTOOL)
int confirm_delete_yesno(const char *name)
int confirm_delete_yesno(const char *name, const char *title)
{
const char *lines[] = { ID2P(LANG_REALLY_DELETE), name };
const char *yes_lines[] = { ID2P(LANG_DELETING), name };
const struct text_message message = { lines, 2 };
const struct text_message yes_message = { yes_lines, 2 };
return gui_syncyesno_run(&message, &yes_message, NULL);
return gui_syncyesno_run_w_title(title, &message, &yes_message, NULL);
}
/* time_split_units()

View file

@ -174,7 +174,9 @@ void adjust_volume_ex(int steps, enum volume_adjust_mode mode);
int hex_to_rgb(const char* hex, int* color);
#endif
int confirm_delete_yesno(const char *name);
/* Note: Don't rely on title being visible. It is not
displayed on Android, or if SBS has no title. */
int confirm_delete_yesno(const char *name, const char *title);
char* strrsplt(char* str, int c);
char* skip_whitespace(char* const str);

View file

@ -296,7 +296,7 @@ static void op_playlist_insert_selected(int position, bool queue)
}
playlist_insert_directory(NULL, selected_file.path, position, queue,
recurse == RECURSE_ON);
recurse == RECURSE_ON, NULL);
}
}

View file

@ -78,11 +78,6 @@
/* Internal support for voice playback */
#define PLAYBACK_VOICE
#if CONFIG_PLATFORM & PLATFORM_NATIVE
/* Application builds don't support direct code loading */
#define HAVE_CODEC_BUFFERING
#endif
/* Amount of guess-space to allow for codecs that must hunt and peck
* for their correct seek target, 32k seems a good size */
#define AUDIO_REBUFFER_GUESS_SIZE (1024*32)
@ -494,14 +489,6 @@ static void id3_write_locked(enum audio_id3_types id3_num,
/** --- Track info --- **/
#ifdef HAVE_CODEC_BUFFERING
static void track_info_close_handle(int *hidp)
{
bufclose(*hidp);
*hidp = ERR_HANDLE_NOT_FOUND;
}
#endif /* HAVE_CODEC_BUFFERING */
/* Invalidate all members to initial values - does not close handles or sync */
static void track_info_wipe(struct track_info *infop)
{
@ -1669,7 +1656,8 @@ static bool audio_init_codec(struct track_info *track_infop,
/* Close any buffered codec (we could have skipped directly to a
format transistion that is the same format as the current track
and the buffered one is no longer needed) */
track_info_close_handle(&track_infop->codec_hid);
bufclose(track_infop->codec_hid);
track_infop->codec_hid = ERR_HANDLE_NOT_FOUND;
track_info_sync(track_infop);
#endif /* HAVE_CODEC_BUFFERING */
return true;

View file

@ -2221,7 +2221,7 @@ int playlist_directory_tracksearch(const char* dirname, bool recurse,
/* user abort */
if (action_userabort(TIMEOUT_NOBLOCK))
{
result = -1;
result = -2;
break;
}
@ -2507,22 +2507,29 @@ void playlist_insert_context_release(struct playlist_insert_context *context)
*/
int playlist_insert_directory(struct playlist_info* playlist,
const char *dirname, int position, bool queue,
bool recurse)
bool recurse, struct playlist_insert_context* context)
{
int result = -1;
struct playlist_insert_context context;
result = playlist_insert_context_create(playlist, &context,
position, queue, true);
bool context_provided = context;
int result = 0;
struct playlist_insert_context c;
if (!context_provided)
{
context = &c;
result = playlist_insert_context_create(playlist, &c,
position, queue, true);
}
if (result >= 0)
{
cpu_boost(true);
result = playlist_directory_tracksearch(dirname, recurse,
directory_search_callback, &context);
directory_search_callback, context);
cpu_boost(false);
}
playlist_insert_context_release(&context);
if (!context_provided)
playlist_insert_context_release(&c);
return result;
}
@ -3159,7 +3166,6 @@ int playlist_resume(void)
struct playlist_info* playlist = &current_playlist;
dc_thread_stop(playlist);
playlist_write_lock(playlist);
if (core_allocatable() < (1 << 10))
talk_buffer_set_policy(TALK_BUFFER_LOOSE); /* back off voice buffer */
@ -3172,9 +3178,11 @@ int playlist_resume(void)
if (handle < 0)
{
splashf(HZ * 2, "%s(): OOM", __func__);
goto out;
goto out_nolock;
}
playlist_write_lock(playlist);
/* align buffer for faster load times */
buffer = core_get_data(handle);
STORAGE_ALIGN_BUFFER(buffer, buflen);
@ -3534,8 +3542,9 @@ int playlist_resume(void)
out:
playlist_write_unlock(playlist);
dc_thread_start(playlist, true);
out_nolock:
dc_thread_start(playlist, true);
talk_buffer_set_policy(TALK_BUFFER_DEFAULT);
core_free(handle);
cpu_boost(false);

View file

@ -157,7 +157,7 @@ int playlist_insert_context_add(struct playlist_insert_context *context,
void playlist_insert_context_release(struct playlist_insert_context *context);
int playlist_insert_directory(struct playlist_info* playlist,
const char *dirname, int position, bool queue,
bool recurse);
bool recurse, struct playlist_insert_context *context);
int playlist_insert_playlist(struct playlist_info* playlist, const char *filename,
int position, bool queue);
bool playlist_entries_iterate(const char *filename,

View file

@ -646,7 +646,8 @@ static void close_playlist_viewer(void)
if (viewer.num_tracks && yesno_pop(ID2P(LANG_SAVE_CHANGES)))
save_playlist_screen(viewer.playlist);
else if (!viewer.num_tracks &&
confirm_delete_yesno(viewer.playlist->filename) == YESNO_YES)
confirm_delete_yesno(viewer.playlist->filename,
viewer.title) == YESNO_YES)
{
remove(viewer.playlist->filename);
reload_directory();

View file

@ -48,6 +48,7 @@
#include "file.h"
#include "core_keymap.h"
#include "language.h"
#include "statusbar-skinned.h"
#if CONFIG_CHARGING
#include "power.h"
@ -355,6 +356,11 @@ static const struct plugin_api rockbox_api = {
simplelist_info_init,
simplelist_show_list,
yesno_pop,
yesno_pop_confirm,
/* status bar */
sb_set_title_text,
sb_set_persistent_title,
/* action handling */
get_custom_action,
@ -362,6 +368,18 @@ static const struct plugin_api rockbox_api = {
#ifdef HAVE_TOUCHSCREEN
action_get_touchscreen_press,
action_get_touchscreen_press_in_vp,
action_get_touch_event,
action_gesture_reset,
action_gesture_get_event_in_vp,
action_gesture_get_event,
action_gesture_is_valid,
action_gesture_is_pressed,
gesture_reset,
gesture_process,
gesture_get_event_in_vp,
gesture_vel_reset,
gesture_vel_process,
gesture_vel_get,
#endif
action_userabort,
core_set_keyremap,
@ -427,6 +445,9 @@ static const struct plugin_api rockbox_api = {
crc_32r,
filetype_get_attr,
filetype_get_plugin,
#ifdef HAVE_DIRCACHE
dircache_wait,
#endif
/* dir */
FS_PREFIX(opendir),
@ -515,7 +536,6 @@ static const struct plugin_api rockbox_api = {
commit_discard_idcache,
lc_open,
lc_open_from_mem,
lc_get_header,
lc_close,
@ -564,6 +584,7 @@ static const struct plugin_api rockbox_api = {
strncmp,
strcasecmp,
strncasecmp,
strstr,
memset,
memcpy,
memmove,
@ -720,6 +741,8 @@ static const struct plugin_api rockbox_api = {
playlist_insert_track,
playlist_insert_directory,
playlist_insert_playlist,
playlist_insert_context_create,
playlist_insert_context_release,
playlist_shuffle,
warn_on_pl_erase,
audio_play,
@ -728,6 +751,7 @@ static const struct plugin_api rockbox_api = {
audio_resume,
audio_next,
audio_prev,
audio_pre_ff_rewind,
audio_ff_rewind,
audio_next_track,
audio_status,
@ -737,6 +761,7 @@ static const struct plugin_api rockbox_api = {
#ifdef PLUGIN_USE_IRAM
audio_hard_stop,
#endif
add_playbacklog,
/* menu */
root_menu_get_options,
@ -760,6 +785,7 @@ static const struct plugin_api rockbox_api = {
#endif
/* power */
&device_battery_tables,
battery_level,
battery_level_safe,
battery_time,
@ -771,12 +797,17 @@ static const struct plugin_api rockbox_api = {
charging_state,
# endif
#endif
/* usb */
usb_inserted,
usb_acknowledge,
#ifdef USB_ENABLE_HID
usb_hid_send,
#endif
#ifdef USB_ENABLE_AUDIO
usb_audio_get_playing,
#endif
/* misc */
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
__errno,
@ -848,27 +879,6 @@ static const struct plugin_api rockbox_api = {
/* new stuff at the end, sort into place next time
the API gets incompatible */
add_playbacklog,
&device_battery_tables,
yesno_pop_confirm,
#ifdef USB_ENABLE_AUDIO
usb_audio_get_playing,
#endif
#ifdef HAVE_TOUCHSCREEN
action_get_touch_event,
action_gesture_reset,
action_gesture_get_event_in_vp,
action_gesture_get_event,
action_gesture_is_valid,
action_gesture_is_pressed,
gesture_reset,
gesture_process,
gesture_get_event_in_vp,
gesture_vel_reset,
gesture_vel_process,
gesture_vel_get,
#endif
strstr,
};
static int plugin_buffer_handle;
@ -888,6 +898,7 @@ int plugin_load(const char* plugin, const void* parameter)
bool theme_enabled = sepch && (!strcmp("properties.rock", sepch + 1) ||
!strcmp("playing_time.rock", sepch + 1) ||
!strcmp("main_menu_config.rock", sepch + 1) ||
!strcmp("text_viewer.rock", sepch + 1) ||
!strcmp("disktidy.rock", sepch + 1));
if (current_plugin_handle)
@ -1065,6 +1076,10 @@ int plugin_load(const char* plugin, const void* parameter)
FOR_NB_SCREENS(i)
viewportmanager_theme_undo(i, true);
}
else
/* fix dangling sbs_title pointer */
FOR_NB_SCREENS(i)
sb_set_title_text(NULL, Icon_NOICON, i);
plugin_check_open_close__exit();

View file

@ -112,6 +112,7 @@ int plugin_open(const char *plugin, const char *parameter);
#include "menu.h"
#include "rbunicode.h"
#include "list.h"
#include "statusbar-skinned.h"
#include "tree.h"
#include "color_picker.h"
#include "buflib.h"
@ -177,7 +178,7 @@ int plugin_open(const char *plugin, const char *parameter);
* when this happens please take the opportunity to sort in
* any new functions "waiting" at the end of the list.
*/
#define PLUGIN_API_VERSION 274
#define PLUGIN_API_VERSION 277
/* 239 Marks the removal of ARCHOS HWCODEC and CHARCELL */
@ -417,6 +418,12 @@ struct plugin_api {
int count, void* data);
bool (*simplelist_show_list)(struct simplelist_info *info);
bool (*yesno_pop)(const char* text);
bool (*yesno_pop_confirm)(const char* text);
/* status bar */
bool (*sb_set_title_text)(const char* title, enum themable_icons icon, enum screen_type screen);
bool (*sb_set_persistent_title)(const char* title, enum themable_icons icon,
enum screen_type screen);
/* action handling */
int (*get_custom_action)(int context,int timeout,
@ -425,6 +432,22 @@ struct plugin_api {
#ifdef HAVE_TOUCHSCREEN
int (*action_get_touchscreen_press)(short *x, short *y);
int (*action_get_touchscreen_press_in_vp)(short *x1, short *y1, struct viewport *vp);
int (*action_get_touch_event)(struct touchevent *ev);
void (*action_gesture_reset)(void);
bool (*action_gesture_get_event_in_vp)(struct gesture_event *gevt,
const struct viewport *vp);
bool (*action_gesture_get_event)(struct gesture_event *gevt);
bool (*action_gesture_is_valid)(void);
bool (*action_gesture_is_pressed)(void);
void (*gesture_reset)(struct gesture *g);
void (*gesture_process)(struct gesture *g, const struct touchevent *ev);
bool (*gesture_get_event_in_vp)(struct gesture *g,
struct gesture_event *gevt,
const struct viewport *vp);
void (*gesture_vel_reset)(struct gesture_vel *gv);
void (*gesture_vel_process)(struct gesture_vel *gv,
const struct touchevent *ev);
bool (*gesture_vel_get)(struct gesture_vel *gv, int *xvel, int *yvel);
#endif
bool (*action_userabort)(int timeout);
int (*core_set_keyremap)(struct button_mapping* core_keymap, int count);
@ -492,6 +515,9 @@ struct plugin_api {
int (*filetype_get_attr)(const char* file);
char* (*filetype_get_plugin)(int attr, char *buffer, size_t buffer_len);
#ifdef HAVE_DIRCACHE
void (*dircache_wait)(void);
#endif
/* dir */
DIR * (*opendir)(const char *dirname);
@ -594,7 +620,6 @@ struct plugin_api {
/* load code api for overlay */
void* (*lc_open)(const char *filename, unsigned char *buf, size_t buf_size);
void* (*lc_open_from_mem)(void* addr, size_t blob_size);
void* (*lc_get_header)(void *handle);
void (*lc_close)(void *handle);
@ -651,6 +676,7 @@ struct plugin_api {
int (*strncmp)(const char *, const char *, size_t);
int (*strcasecmp)(const char *, const char *);
int (*strncasecmp)(const char *s1, const char *s2, size_t n);
char* (*strstr)(const char *s1, const char *s2);
void* (*memset)(void *dst, int c, size_t length);
void* (*memcpy)(void *out, const void *in, size_t n);
void* (*memmove)(void *out, const void *in, size_t n);
@ -841,9 +867,13 @@ struct plugin_api {
const char *filename, int position, bool queue, bool sync);
int (*playlist_insert_directory)(struct playlist_info* playlist,
const char *dirname, int position, bool queue,
bool recurse);
bool recurse, struct playlist_insert_context *context);
int (*playlist_insert_playlist)(struct playlist_info* playlist,
const char *filename, int position, bool queue);
int (*playlist_insert_context_create)(struct playlist_info* playlist,
struct playlist_insert_context *context,
int position, bool queue, bool progress);
void (*playlist_insert_context_release)(struct playlist_insert_context *context);
int (*playlist_shuffle)(int random_seed, int start_index);
bool (*warn_on_pl_erase)(void);
void (*audio_play)(unsigned long elapsed, unsigned long offset);
@ -852,6 +882,7 @@ struct plugin_api {
void (*audio_resume)(void);
void (*audio_next)(void);
void (*audio_prev)(void);
void (*audio_pre_ff_rewind)(void);
void (*audio_ff_rewind)(long newtime);
struct mp3entry* (*audio_next_track)(void);
int (*audio_status)(void);
@ -861,6 +892,7 @@ struct plugin_api {
#ifdef PLUGIN_USE_IRAM
void (*audio_hard_stop)(void);
#endif
void (*add_playbacklog)(struct mp3entry *id3);
/* menu */
struct menu_table *(*root_menu_get_options)(int *nb_options);
@ -901,6 +933,7 @@ struct plugin_api {
#endif
/* power */
struct battery_tables_t *device_battery_tables;
int (*battery_level)(void);
bool (*battery_level_safe)(void);
int (*battery_time)(void);
@ -912,12 +945,17 @@ struct plugin_api {
bool (*charging_state)(void);
# endif
#endif
/* usb */
bool (*usb_inserted)(void);
void (*usb_acknowledge)(long id);
#ifdef USB_ENABLE_HID
void (*usb_hid_send)(usage_page_t usage_page, int id);
#endif
#ifdef USB_ENABLE_AUDIO
bool (*usb_audio_get_playing)(void);
#endif
/* misc */
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
int * (*__errno)(void);
@ -993,33 +1031,9 @@ struct plugin_api {
#ifdef HAVE_MULTIVOLUME
int (*path_strip_volume)(const char *name, const char **nameptr, bool greedy);
#endif
/* new stuff at the end, sort into place next time
the API gets incompatible */
void (*add_playbacklog)(struct mp3entry *id3);
struct battery_tables_t *device_battery_tables;
bool (*yesno_pop_confirm)(const char* text);
#ifdef USB_ENABLE_AUDIO
bool (*usb_audio_get_playing)(void);
#endif
#ifdef HAVE_TOUCHSCREEN
int (*action_get_touch_event)(struct touchevent *ev);
void (*action_gesture_reset)(void);
bool (*action_gesture_get_event_in_vp)(struct gesture_event *gevt,
const struct viewport *vp);
bool (*action_gesture_get_event)(struct gesture_event *gevt);
bool (*action_gesture_is_valid)(void);
bool (*action_gesture_is_pressed)(void);
void (*gesture_reset)(struct gesture *g);
void (*gesture_process)(struct gesture *g, const struct touchevent *ev);
bool (*gesture_get_event_in_vp)(struct gesture *g,
struct gesture_event *gevt,
const struct viewport *vp);
void (*gesture_vel_reset)(struct gesture_vel *gv);
void (*gesture_vel_process)(struct gesture_vel *gv,
const struct touchevent *ev);
bool (*gesture_vel_get)(struct gesture_vel *gv, int *xvel, int *yvel);
#endif
char* (*strstr)(const char *s1, const char *s2);
};
/* plugin header */

View file

@ -1,4 +1,4 @@
#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90)
#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90) || defined(HIBY_R3PROII) || defined(HIBY_R1)
/* In devices running RockBox as an application, but having a keypad */
#include "SOURCES"
#else

View file

@ -75,7 +75,7 @@ mikmod
(CONFIG_KEYPAD == SANSA_FUZE_PAD) || (CONFIG_KEYPAD == SANSA_E200_PAD) || \
(CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
(CONFIG_KEYPAD == IPOD_1G2G_PAD || CONFIG_KEYPAD == SAMSUNG_YPR0_PAD) || \
(CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD)
(CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD) || (CONFIG_KEYPAD == CTRU_PAD)
/* PDBox is confirmed to run on these player models. */
pdbox
#endif

View file

@ -1,4 +1,4 @@
#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90)
#if !defined(HAVE_TOUCHSCREEN) || defined(DX50) || defined(DX90) || defined(HIBY_R3PROII) || defined(HIBY_R1)
/* This is for devices having a keypad, running RockBox as an application */
#include "SUBDIRS"

View file

@ -250,7 +250,7 @@ struct battery_tables_t {
#define BATTERY_ON_TXT "Play"
#define BATTERY_OFF_TXT "Power"
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#elif CONFIG_KEYPAD == MA_PAD
@ -265,6 +265,12 @@ struct battery_tables_t {
#define BATTERY_ON_TXT "A"
#define BATTERY_OFF_TXT "X"
#elif CONFIG_KEYPAD == CTRU_PAD
#define BATTERY_ON BUTTON_SELECT
#define BATTERY_OFF BUTTON_BACK
#define BATTERY_ON_TXT "A - start"
#define BATTERY_OFF_TXT "B"
#else
#error "No keymap defined!"
#endif

View file

@ -24,7 +24,7 @@ bubbles_bubble.220x176x1.bmp
((LCD_WIDTH == 360) && (LCD_HEIGHT == 400))
bubbles_bubble.320x240x1.bmp
#elif ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \
((LCD_WIDTH == 480) && (LCD_HEIGHT == 640))
((LCD_WIDTH == 480) && (LCD_HEIGHT >= 640))
bubbles_bubble.640x480x1.bmp
#endif

View file

@ -436,7 +436,9 @@ invadrox_shield.22x16x16.bmp
invadrox_ufo.16x7x16.bmp
invadrox_ufo_explode.21x8x16.bmp
invadrox_numbers.50x7x16.bmp
#if LCD_WIDTH == 360 && LCD_HEIGHT == 400
#if LCD_WIDTH == 480
invadrox_background.480x640x16.bmp
#elif LCD_WIDTH == 360 && LCD_HEIGHT == 400
invadrox_background.360x400x16.bmp
#elif LCD_WIDTH == 320
invadrox_background.320x240x16.bmp
@ -513,8 +515,8 @@ jewels.320x240x16.bmp
jewels.320x240x16.bmp
#elif (LCD_WIDTH == 360) && (LCD_HEIGHT == 400)
jewels.360x400x16.bmp
#elif ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \
((LCD_WIDTH == 480) && (LCD_HEIGHT == 640))
#elif ((LCD_WIDTH >= 480) && (LCD_HEIGHT >= 640)) || \
((LCD_WIDTH >= 640) && (LCD_HEIGHT >= 480))
jewels.640x480x16.bmp
#endif
@ -947,9 +949,9 @@ superdom_boarditems.320x240x16.bmp
((LCD_WIDTH == 240) && (LCD_HEIGHT == 400)) || \
((LCD_WIDTH == 360) && (LCD_HEIGHT == 400))
superdom_boarditems.240x320x16.bmp
#elif (LCD_WIDTH == 480 && LCD_HEIGHT == 640)
#elif (LCD_WIDTH >= 480 && LCD_HEIGHT >= 640)
superdom_boarditems.480x640x16.bmp
#elif (LCD_WIDTH == 640 && LCD_HEIGHT == 480)
#elif (LCD_WIDTH >= 640 && LCD_HEIGHT >= 480)
superdom_boarditems.640x480x16.bmp
#endif
#endif
@ -984,7 +986,7 @@ sliding_puzzle.176x176x16.bmp
sliding_puzzle.240x240x16.bmp
#elif SMALLER_DIMENSION <= 360
sliding_puzzle.360x360x16.bmp
#elif SMALLER_DIMENSION <= 480
#else
sliding_puzzle.480x480x16.bmp
#endif
#elif (LCD_DEPTH > 1)

View file

@ -608,7 +608,7 @@ enum {
#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
#define BJACK_QUIT BUTTON_POWER
#define BJACK_QUIT_NAME "QUIT"
@ -628,6 +628,22 @@ enum {
#define BJACK_RIGHT BUTTON_RIGHT
#define BJACK_LEFT BUTTON_LEFT
#elif CONFIG_KEYPAD == CTRU_PAD
#define BJACK_SELECT_NAME "A"
#define BJACK_STAY_NAME "X"
#define BJACK_QUIT_NAME "B"
#define BJACK_DOUBLE_NAME "Y"
#define BJACK_SELECT BUTTON_SELECT
#define BJACK_QUIT BUTTON_BACK
#define BJACK_MAX (BUTTON_LEFT|BUTTON_UP)
#define BJACK_MIN (BUTTON_RIGHT|BUTTON_DOWN)
#define BJACK_STAY BUTTON_MENU
#define BJACK_DOUBLEDOWN BUTTON_USER
#define BJACK_UP BUTTON_UP
#define BJACK_DOWN BUTTON_DOWN
#define BJACK_RIGHT BUTTON_RIGHT
#define BJACK_LEFT BUTTON_LEFT
#else
#error No keymap defined!
#endif

View file

@ -362,7 +362,7 @@ CONFIG_KEYPAD == SANSA_M200_PAD
#define UP BUTTON_UP
#define DOWN BUTTON_DOWN
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
#define QUIT BUTTON_POWER
#elif CONFIG_KEYPAD == MA_PAD
@ -382,6 +382,14 @@ CONFIG_KEYPAD == SANSA_M200_PAD
#define UP BUTTON_UP
#define DOWN BUTTON_DOWN
#elif CONFIG_KEYPAD == CTRU_PAD
#define QUIT BUTTON_BACK
#define LEFT BUTTON_LEFT
#define RIGHT BUTTON_RIGHT
#define SELECT BUTTON_SELECT
#define UP BUTTON_UP
#define DOWN BUTTON_DOWN
#else
#error No keymap defined!
#endif

View file

@ -135,7 +135,7 @@ enum {
#define NEXT_BB_WIDTH 32
#define NEXT_BB_Y 402
#elif (LCD_WIDTH == 480) && (LCD_HEIGHT == 640)
#elif (LCD_WIDTH == 480) && (LCD_HEIGHT >= 640)
#define XOFS 128
#define MAX_FPS 40

View file

@ -533,7 +533,7 @@ F3: equal to "="
#define CALCULATOR_CALC BUTTON_MENU
#define CALCULATOR_CLEAR BUTTON_BACK
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
#define CALCULATOR_QUIT BUTTON_POWER
#elif CONFIG_KEYPAD == MA_PAD
@ -557,6 +557,17 @@ F3: equal to "="
#define CALCULATOR_CALC BUTTON_X
#define CALCULATOR_CLEAR BUTTON_B
#elif CONFIG_KEYPAD == CTRU_PAD
#define CALCULATOR_LEFT BUTTON_LEFT
#define CALCULATOR_RIGHT BUTTON_RIGHT
#define CALCULATOR_UP BUTTON_UP
#define CALCULATOR_DOWN BUTTON_DOWN
#define CALCULATOR_QUIT BUTTON_BACK
#define CALCULATOR_INPUT BUTTON_SELECT
#define CALCULATOR_CALC BUTTON_MENU
#define CALCULATOR_CLEAR BUTTON_USER
#else
#error No keymap defined!
#endif

View file

@ -419,7 +419,7 @@
#define CALENDAR_NEXT_MONTH BUTTON_VOL_UP
#define CALENDAR_PREV_MONTH BUTTON_VOL_DOWN
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#elif CONFIG_KEYPAD == MA_PAD
@ -443,6 +443,16 @@
#define CALENDAR_PREV_MONTH BUTTON_L
#define CALENDAR_EVENT_MENU_NAME "A"
#elif CONFIG_KEYPAD == CTRU_PAD
#define CALENDAR_QUIT BUTTON_BACK
#define CALENDAR_SELECT BUTTON_SELECT
#define CALENDAR_NEXT_WEEK BUTTON_DOWN
#define CALENDAR_PREV_WEEK BUTTON_UP
#define CALENDAR_NEXT_DAY BUTTON_RIGHT
#define CALENDAR_PREV_DAY BUTTON_LEFT
#define CALENDAR_NEXT_MONTH BUTTON_POWER
#define CALENDAR_PREV_MONTH BUTTON_USER
#else
#error "No keypad setting."
#endif

View file

@ -581,7 +581,7 @@
#define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT)
#define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT)
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#elif CONFIG_KEYPAD == MA_PAD
@ -614,6 +614,20 @@
#define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT)
#define CB_RC_QUIT BUTTON_START
#elif CONFIG_KEYPAD == CTRU_PAD
#define CB_SELECT BUTTON_SELECT
#define CB_UP BUTTON_UP
#define CB_DOWN BUTTON_DOWN
#define CB_LEFT BUTTON_LEFT
#define CB_RIGHT BUTTON_RIGHT
#define CB_PLAY BUTTON_USER
#define CB_LEVEL BUTTON_BACK
#define CB_MENU BUTTON_MENU
#define CB_SCROLL_UP (BUTTON_UP|BUTTON_REPEAT)
#define CB_SCROLL_DOWN (BUTTON_DOWN|BUTTON_REPEAT)
#define CB_SCROLL_LEFT (BUTTON_LEFT|BUTTON_REPEAT)
#define CB_SCROLL_RIGHT (BUTTON_RIGHT|BUTTON_REPEAT)
#else
#error No keymap defined!
#endif

View file

@ -395,7 +395,7 @@
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_POWER
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
#define CHC_QUIT BUTTON_POWER
#elif (CONFIG_KEYPAD == MA_PAD)
@ -418,6 +418,16 @@
#define CHC_SETTINGS_OK BUTTON_A
#define CHC_SETTINGS_CANCEL BUTTON_B
#elif CONFIG_KEYPAD == CTRU_PAD
#define CHC_QUIT BUTTON_BACK
#define CHC_STARTSTOP BUTTON_SELECT
#define CHC_RESET BUTTON_USER
#define CHC_MENU BUTTON_MENU
#define CHC_SETTINGS_INC BUTTON_UP
#define CHC_SETTINGS_DEC BUTTON_DOWN
#define CHC_SETTINGS_OK BUTTON_SELECT
#define CHC_SETTINGS_CANCEL BUTTON_BACK
#else
#error No keymap defined!
#endif

View file

@ -1312,7 +1312,19 @@ CONFIG_KEYPAD == MROBE500_PAD
#define CHIP8_KEY9 BUTTON_R
#define CHIP8_KEY0 BUTTON_L
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif (CONFIG_KEYPAD == CTRU_PAD)
#define CHIP8_OFF (BUTTON_BACK|BUTTON_REPEAT)
#define CHIP8_KEY1 BUTTON_MENU
#define CHIP8_KEY2 BUTTON_UP
#define CHIP8_KEY3 BUTTON_DOWN
#define CHIP8_KEY4 BUTTON_LEFT
#define CHIP8_KEY5 BUTTON_SELECT
#define CHIP8_KEY6 BUTTON_RIGHT
#define CHIP8_KEY7 BUTTON_BACK
#define CHIP8_KEY8 BUTTON_POWER
#define CHIP8_KEY9 BUTTON_USER
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#else

View file

@ -213,6 +213,12 @@ CONFIG_KEYPAD == MROBE500_PAD
#define ACTION2 BUTTON_B
#define ACTIONTEXT "A"
#elif CONFIG_KEYPAD == CTRU_PAD
#define QUIT BUTTON_BACK
#define ACTION BUTTON_SELECT
#define ACTION2 BUTTON_MENU
#define ACTIONTEXT "A"
#elif !defined(HAVE_TOUCHSCREEN)
#error No keymap defined!
#endif

View file

@ -314,7 +314,7 @@
#define CLIX_BUTTON_RIGHT BUTTON_RIGHT
#define CLIX_BUTTON_CLICK BUTTON_SELECT
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
#define CLIX_BUTTON_QUIT BUTTON_POWER
#elif CONFIG_KEYPAD == MA_PAD
@ -333,6 +333,14 @@
#define CLIX_BUTTON_UP BUTTON_UP
#define CLIX_BUTTON_DOWN BUTTON_DOWN
#elif (CONFIG_KEYPAD == CTRU_PAD)
#define CLIX_BUTTON_QUIT BUTTON_BACK
#define CLIX_BUTTON_LEFT BUTTON_LEFT
#define CLIX_BUTTON_RIGHT BUTTON_RIGHT
#define CLIX_BUTTON_CLICK BUTTON_SELECT
#define CLIX_BUTTON_UP BUTTON_UP
#define CLIX_BUTTON_DOWN BUTTON_DOWN
#else
#error "no keymap"
#endif

View file

@ -402,7 +402,7 @@
#define CUBE_PAUSE BUTTON_PLAY
#define CUBE_HIGHSPEED BUTTON_BACK
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#elif CONFIG_KEYPAD == MA_PAD
@ -425,6 +425,16 @@
#define CUBE_PAUSE BUTTON_A
#define CUBE_HIGHSPEED BUTTON_Y
#elif (CONFIG_KEYPAD == CTRU_PAD)
#define CUBE_QUIT BUTTON_BACK
#define CUBE_NEXT BUTTON_RIGHT
#define CUBE_PREV BUTTON_LEFT
#define CUBE_INC BUTTON_UP
#define CUBE_DEC BUTTON_DOWN
#define CUBE_MODE BUTTON_MENU
#define CUBE_PAUSE BUTTON_USER
#define CUBE_HIGHSPEED BUTTON_SELECT
#else
#error No keymap defined!
#endif

View file

@ -27,6 +27,7 @@
#define DEFAULT_FILES PLUGIN_APPS_DATA_DIR "/disktidy.config"
#define CUSTOM_FILES PLUGIN_APPS_DATA_DIR "/disktidy_custom.config"
#define LAST_RUN_STATS_FILE PLUGIN_APPS_DATA_DIR "/disktidy.stats"
#define CLEANING_STR "Cleaning..."
#define DIR_STACK_SIZE 25
struct dir_info {
@ -64,6 +65,7 @@ static size_t tidy_type_count;
static bool user_abort;
static bool tidy_loaded_and_changed = false;
static bool stats_file_exists = false;
static bool sbs_has_title;
static void dir_stack_init(struct dir_stack *dstack)
{
@ -224,6 +226,8 @@ static bool load_run_stats(void)
static enum plugin_status display_run_stats(void)
{
struct viewport vp;
if (!load_run_stats()) {
rb->splash(HZ * 2, "Unable to load last run stats");
return PLUGIN_OK;
@ -247,9 +251,10 @@ static enum plugin_status display_run_stats(void)
magnitude++;
}
char total_removed[8];
rb->snprintf(total_removed, sizeof(total_removed), "%d",
run_stats.files_removed + run_stats.dirs_removed);
char total_removed[8] = "Nothing";
int num_removed = run_stats.files_removed + run_stats.dirs_removed;
if (num_removed)
rb->snprintf(total_removed, sizeof(total_removed), "%d", num_removed);
char files_removed[8];
rb->snprintf(files_removed, sizeof(files_removed), "%d",
@ -264,18 +269,34 @@ static enum plugin_status display_run_stats(void)
(int)rm_size, (int)((rm_size - (int)rm_size) * 100),
size_units[magnitude]);
char run_time[12];
rb->snprintf(run_time, sizeof(run_time), "in %02d:%02d:%02d",
run_stats.run_duration / 3600, run_stats.run_duration / 60,
run_stats.run_duration % 60);
char run_time[12] = "in <1s";
int s = run_stats.run_duration % 60;
int m = run_stats.run_duration / 60;
int h = run_stats.run_duration / 3600;
if (h)
rb->snprintf(run_time, sizeof(run_time), "in %dh %dm, %ds", h, m, s);
else if (m)
rb->snprintf(run_time, sizeof(run_time), "in %dm %ds", m, s);
else if (s)
rb->snprintf(run_time, sizeof(run_time), "in %ds", s);
#if CONFIG_RTC
struct tm tm = *rb->get_time();
char last_run[18];
rb->snprintf(last_run, sizeof(last_run), "%02d:%02d %d/%s/%d",
run_stats.last_run_time.tm_hour,
run_stats.last_run_time.tm_min, run_stats.last_run_time.tm_mday,
months[run_stats.last_run_time.tm_mon],
2000 + (run_stats.last_run_time.tm_year % 100));
if (tm.tm_mday == run_stats.last_run_time.tm_mday &&
tm.tm_mon == run_stats.last_run_time.tm_mon &&
tm.tm_year == run_stats.last_run_time.tm_year)
{
rb->snprintf(last_run, sizeof(last_run), "%02d:%02d Today",
run_stats.last_run_time.tm_hour,
run_stats.last_run_time.tm_min);
}
else
rb->snprintf(last_run, sizeof(last_run), "%02d:%02d %d/%s/%d",
run_stats.last_run_time.tm_hour,
run_stats.last_run_time.tm_min, run_stats.last_run_time.tm_mday,
months[run_stats.last_run_time.tm_mon],
2000 + (run_stats.last_run_time.tm_year % 100));
#endif
char* last_run_text[] = {
@ -287,19 +308,34 @@ static enum plugin_status display_run_stats(void)
dirs_removed , run_stats.dirs_removed == 1 ? "dir" : "dirs", "",
run_time , "",
};
static struct style_text display_style[] = {
char** text_arr = last_run_text;
int len = ARRAYLEN(last_run_text);
if (!num_removed)
{
/* Hide superfluous zeros if nothing was removed */
text_arr[len - 9] = "";
text_arr[len - 8] = run_time;
text_arr[len - 7] = "";
len -= 6;
}
#if CONFIG_RTC
{ 0, TEXT_CENTER },
sbs_has_title = rb->sb_set_title_text(last_run, Icon_NOICON, SCREEN_MAIN);
if (sbs_has_title)
{
text_arr += 2;
len -=2;
#else
sbs_has_title = rb->sb_set_title_text("Last Run", Icon_NOICON, SCREEN_MAIN);
if (sbs_has_title)
{
#endif
LAST_STYLE_ITEM
};
rb->send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
}
struct viewport vp;
rb->viewport_set_defaults(&vp, SCREEN_MAIN);
if (display_text(ARRAYLEN(last_run_text), last_run_text,
display_style, &vp, false)) {
if (display_text(len, text_arr, NULL, &vp, false))
{
return PLUGIN_USB_CONNECTED;
}
while (true) /* keep info on screen until cancelled */
@ -343,22 +379,30 @@ static bool tidy_remove_item(const char *item, int attr)
static void tidy_lcd_status(const char *name, struct viewport *vp)
{
static long next_tick;
int i, num_removed;
struct screen *display;
struct viewport *last_vp;
if (TIME_AFTER(next_tick, *rb->current_tick))
return;
next_tick = *rb->current_tick + HZ/10;
struct screen *display = rb->screens[SCREEN_MAIN];
struct viewport *last_vp = display->set_viewport(vp);
display = rb->screens[SCREEN_MAIN];
last_vp = display->set_viewport(vp);
display->clear_viewport();
display->puts(0, 0, "Cleaning...");
display->puts(0, 1, name);
display->putsf(0, 2, "%d items removed",
run_stats.files_removed + run_stats.dirs_removed);
display->update_viewport();
i = 0;
num_removed = run_stats.files_removed + run_stats.dirs_removed;
if (!sbs_has_title)
display->puts(0, i++, CLEANING_STR);
display->puts(0, i++, name);
if (num_removed)
display->putsf(0, i++, num_removed == 1 ? "%d item removed" : "%d items removed", num_removed);
else
display->puts(0, i++, "Nothing removed");
display->update_viewport();
display->set_viewport(last_vp);
}
@ -557,6 +601,10 @@ static enum plugin_status tidy_do(void)
/* clean disk and display num of items removed */
char path[MAX_PATH];
sbs_has_title = rb->sb_set_title_text(CLEANING_STR, Icon_NOICON, SCREEN_MAIN);
if (sbs_has_title)
rb->send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
run_stats.files_removed = 0;
run_stats.dirs_removed = 0;
run_stats.removed_size = 0;
@ -686,6 +734,10 @@ static enum plugin_status tidy_lcd_menu(void)
switch(rb->do_menu(&menu, &selection, NULL, false)) {
case 0:
if (tidy_types_selected()) {
#ifdef HAVE_DIRCACHE
rb->splash(0, ID2P(LANG_WAIT));
rb->dircache_wait();
#endif
disktidy_status = tidy_do();
if (disktidy_status == PLUGIN_OK)
disktidy_status = display_run_stats();

View file

@ -629,7 +629,7 @@ void I_ShutdownGraphics(void)
#define DOOMBUTTON_WEAPON BUTTON_BACK
#define DOOMBUTTON_MAP (BUTTON_BACK|BUTTON_REPEAT)
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
#define DOOMBUTTON_ESC BUTTON_POWER
#define DOOMBUTTON_MAP BUTTON_PREV
@ -645,6 +645,17 @@ void I_ShutdownGraphics(void)
#define DOOMBUTTON_WEAPON BUTTON_X
#define DOOMBUTTON_MAP BUTTON_Y
#elif CONFIG_KEYPAD == CTRU_PAD
#define DOOMBUTTON_UP BUTTON_UP
#define DOOMBUTTON_DOWN BUTTON_DOWN
#define DOOMBUTTON_LEFT BUTTON_LEFT
#define DOOMBUTTON_RIGHT BUTTON_RIGHT
#define DOOMBUTTON_SHOOT BUTTON_SELECT
#define DOOMBUTTON_OPEN BUTTON_MENU
#define DOOMBUTTON_ESC BUTTON_BACK
#define DOOMBUTTON_ENTER BUTTON_POWER
#define DOOMBUTTON_WEAPON BUTTON_USER
#else
#error Keymap not defined!
#endif

View file

@ -494,7 +494,7 @@
#define FLIPIT_STEP_BY_STEP BUTTON_VOL_UP
#define FLIPIT_TOGGLE BUTTON_SELECT
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#elif CONFIG_KEYPAD == MA_PAD
@ -523,6 +523,18 @@
#define FLIPIT_STEP_BY_STEP BUTTON_Y
#define FLIPIT_TOGGLE BUTTON_A
#elif CONFIG_KEYPAD == CTRU_PAD
#define FLIPIT_LEFT BUTTON_LEFT
#define FLIPIT_RIGHT BUTTON_RIGHT
#define FLIPIT_UP BUTTON_UP
#define FLIPIT_DOWN BUTTON_DOWN
#define FLIPIT_QUIT BUTTON_BACK
#define FLIPIT_SHUFFLE BUTTON_MENU
#define FLIPIT_SOLVE BUTTON_USER
#define FLIPIT_STEP_BY_STEP BUTTON_POWER
#define FLIPIT_TOGGLE BUTTON_SELECT
#else
#error No keymap defined!
#endif

View file

@ -504,7 +504,7 @@
#define FRACTAL_PRECISION_DEC BUTTON_BACK
#define FRACTAL_RESET BUTTON_PLAY
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
#define FRACTAL_QUIT BUTTON_POWER
#elif CONFIG_KEYPAD == MA_PAD
@ -531,6 +531,18 @@
#define FRACTAL_PRECISION_DEC BUTTON_L
#define FRACTAL_RESET BUTTON_A
#elif CONFIG_KEYPAD == CTRU_PAD
#define FRACTAL_QUIT BUTTON_BACK
#define FRACTAL_UP BUTTON_UP
#define FRACTAL_DOWN BUTTON_DOWN
#define FRACTAL_LEFT BUTTON_LEFT
#define FRACTAL_RIGHT BUTTON_RIGHT
#define FRACTAL_ZOOM_IN (BUTTON_MENU|BUTTON_REL)
#define FRACTAL_ZOOM_OUT (BUTTON_USER|BUTTON_REL)
#define FRACTAL_PRECISION_INC (BUTTON_MENU|BUTTON_REPEAT)
#define FRACTAL_PRECISION_DEC (BUTTON_USER|BUTTON_REPEAT)
#define FRACTAL_RESET BUTTON_POWER
#else
#error No keymap defined!
#endif

View file

@ -524,6 +524,16 @@
#define GBN_BUTTON_CONTEXT BUTTON_X
#define GBN_BUTTON_NEXT_VAR BUTTON_Y
#elif (CONFIG_KEYPAD == CTRU_PAD)
#define GBN_BUTTON_UP BUTTON_UP
#define GBN_BUTTON_DOWN BUTTON_DOWN
#define GBN_BUTTON_LEFT BUTTON_LEFT
#define GBN_BUTTON_RIGHT BUTTON_RIGHT
#define GBN_BUTTON_RETREAT BUTTON_BACK
#define GBN_BUTTON_ADVANCE BUTTON_USER
#define GBN_BUTTON_PLAY BUTTON_SELECT
#define GBN_BUTTON_MENU BUTTON_MENU
#else
#error Unsupported keypad
#endif

View file

@ -557,7 +557,7 @@
#define IMGVIEW_MENU (BUTTON_PLAY|BUTTON_REPEAT)
#define IMGVIEW_SLIDE_SHOW BUTTON_PLAY
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#elif CONFIG_KEYPAD == RG_NANO_PAD
@ -572,6 +572,18 @@
#define IMGVIEW_MENU BUTTON_B
#define IMGVIEW_QUIT BUTTON_START
#elif CONFIG_KEYPAD == CTRU_PAD
#define IMGVIEW_ZOOM_IN BUTTON_POWER
#define IMGVIEW_ZOOM_OUT BUTTON_USER
#define IMGVIEW_UP BUTTON_UP
#define IMGVIEW_DOWN BUTTON_DOWN
#define IMGVIEW_LEFT BUTTON_LEFT
#define IMGVIEW_RIGHT BUTTON_RIGHT
#define IMGVIEW_NEXT BUTTON_SELECT
#define IMGVIEW_PREVIOUS 0xFFFFFFA //not used
#define IMGVIEW_MENU BUTTON_MENU
#define IMGVIEW_QUIT BUTTON_BACK
#else
#error No keymap defined!
#endif

View file

@ -229,9 +229,38 @@ static int get_image(struct image_info *info, int frame, int ds)
j->Components[2].du[j->Components[2].du_width * ((y / v2) / 8)] + 8 * ((y / v2) & 7);
for (x = 0; x < max_x; x += ds)
{
TCOEF c0 = C0[(x / h0 / 8) * 64 + ((x / h0) & 7)];
TCOEF c1 = C1[(x / h1 / 8) * 64 + ((x / h1) & 7)];
TCOEF c2 = C2[(x / h2 / 8) * 64 + ((x / h2) & 7)];
int c0, c1, c2;
if (ds == 1)
{
c0 = C0[(x / h0 / 8) * 64 + ((x / h0) & 7)];
c1 = C1[(x / h1 / 8) * 64 + ((x / h1) & 7)];
c2 = C2[(x / h2 / 8) * 64 + ((x / h2) & 7)];
}
else
{
/* Box filter downsampling (area averaging):
Average a ds*ds block of Y/U/V samples per output pixel
for simple anti-aliasing without extra buffers */
int sumY = 0, sumU = 0, sumV = 0;
int dx, dy;
int area = ds * ds;
for (dy = 0; dy < ds; dy++)
{
TCOEF *C0_dy = j->Components[0].du[j->Components[0].du_width * (((y + dy) / v0) / 8)] + 8 * (((y + dy) / v0) & 7);
TCOEF *C1_dy = j->Components[1].du[j->Components[1].du_width * (((y + dy) / v1) / 8)] + 8 * (((y + dy) / v1) & 7);
TCOEF *C2_dy = j->Components[2].du[j->Components[2].du_width * (((y + dy) / v2) / 8)] + 8 * (((y + dy) / v2) & 7);
for (dx = 0; dx < ds; dx++)
{
int sx = x + dx;
sumY += C0_dy[((sx / h0 / 8) * 64) + ((sx / h0) & 7)];
sumU += C1_dy[((sx / h1 / 8) * 64) + ((sx / h1) & 7)];
sumV += C2_dy[((sx / h2 / 8) * 64) + ((sx / h2) & 7)];
}
}
c0 = (sumY + area/2) / area;
c1 = (sumU + area/2) / area;
c2 = (sumV + area/2) / area;
}
// ITU BT.601 full-range YUV-to-RGB integer approximation
{

View file

@ -288,7 +288,7 @@ CONFIG_KEYPAD == MROBE500_PAD
#define RIGHT BUTTON_RIGHT
#define FIRE BUTTON_SELECT
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#elif CONFIG_KEYPAD == MA_PAD
@ -305,6 +305,13 @@ CONFIG_KEYPAD == MROBE500_PAD
#define RIGHT BUTTON_RIGHT
#define FIRE BUTTON_A
#elif CONFIG_KEYPAD == CTRU_PAD
#define QUIT BUTTON_POWER
#define LEFT BUTTON_LEFT
#define RIGHT BUTTON_RIGHT
#define FIRE BUTTON_SELECT
#else
#error INVADROX: Unsupported keypad
#endif
@ -369,7 +376,7 @@ CONFIG_KEYPAD == MROBE500_PAD
/* m:robe 500 defines */
#if ((LCD_WIDTH == 640) && (LCD_HEIGHT == 480)) || \
((LCD_WIDTH == 480) && (LCD_HEIGHT == 640))
((LCD_WIDTH == 480) && (LCD_HEIGHT >= 640))
/* Original arcade game size 224x240, 1bpp with
* red overlay at top and green overlay at bottom.

View file

@ -377,7 +377,7 @@ CONFIG_KEYPAD == MROBE500_PAD
#define HK_SELECT "SELECT"
#define HK_CANCEL "BACK"
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
/* use touchscreen */
#elif CONFIG_KEYPAD == MA_PAD
@ -400,6 +400,16 @@ CONFIG_KEYPAD == MROBE500_PAD
#define HK_SELECT "A"
#define HK_CANCEL "START"
#elif CONFIG_KEYPAD == CTRU_PAD
#define JEWELS_UP BUTTON_UP
#define JEWELS_DOWN BUTTON_DOWN
#define JEWELS_LEFT BUTTON_LEFT
#define JEWELS_RIGHT BUTTON_RIGHT
#define JEWELS_SELECT BUTTON_SELECT
#define JEWELS_CANCEL BUTTON_BACK
#define HK_SELECT "A"
#define HK_CANCEL "B"
#else
#error No keymap defined!
#endif

View file

@ -255,7 +255,7 @@
#define BTN_FIRE BUTTON_SELECT
#define BTN_PAUSE BUTTON_POWER
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD
#define BTN_FIRE BUTTON_CENTER
#define BTN_PAUSE BUTTON_POWER
#define BTN_HAVE_DIAGONAL
@ -280,15 +280,31 @@
#define BTN_FIRE BUTTON_A
#define BTN_PAUSE BUTTON_START
#elif CONFIG_KEYPAD == CTRU_PAD
#define BTN_UP BUTTON_UP
#define BTN_DOWN BUTTON_DOWN
#define BTN_LEFT BUTTON_LEFT
#define BTN_RIGHT BUTTON_RIGHT
#define BTN_FIRE BUTTON_USER
#define BTN_PAUSE BUTTON_MENU
#else
#error Unsupported keypad
#endif
#ifdef HAVE_TOUCHSCREEN
#define BTN_UP BUTTON_TOPMIDDLE
#define BTN_DOWN BUTTON_BOTTOMMIDDLE
#define BTN_LEFT BUTTON_LEFT
#define BTN_RIGHT BUTTON_RIGHT
#ifndef BTN_UP
#define BTN_UP BUTTON_TOPMIDDLE
#endif
#ifndef BTN_DOWN
#define BTN_DOWN BUTTON_BOTTOMMIDDLE
#endif
#ifndef BTN_LEFT
#define BTN_LEFT BUTTON_LEFT
#endif
#ifndef BTN_RIGHT
#define BTN_RIGHT BUTTON_RIGHT
#endif
#if (CONFIG_KEYPAD == MROBE500_PAD) || \
(CONFIG_KEYPAD == ONDAVX777_PAD)
@ -298,7 +314,8 @@
(CONFIG_KEYPAD != DX50_PAD) && \
(CONFIG_KEYPAD != ONDAVX777_PAD) && \
(CONFIG_KEYPAD != CREATIVE_ZENXFI2_PAD) && \
(CONFIG_KEYPAD != SHANLING_Q1_PAD)
(CONFIG_KEYPAD != SHANLING_Q1_PAD) && \
(CONFIG_KEYPAD != HIBY_R3PROII_PAD)
#define BTN_FIRE BUTTON_BOTTOMLEFT
#define BTN_PAUSE BUTTON_TOPLEFT
#endif

View file

@ -286,6 +286,15 @@ const struct button_mapping pla_main_ctx[] =
{ PLA_DOWN_REPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
#elif (CONFIG_KEYPAD == CTRU_PAD)
{ PLA_UP, BUTTON_UP, BUTTON_NONE },
{ PLA_DOWN, BUTTON_DOWN, BUTTON_NONE },
{ PLA_LEFT, BUTTON_LEFT, BUTTON_NONE },
{ PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE },
{ PLA_UP_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE },
{ PLA_DOWN_REPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE },
{ PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
{ PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
#else
# ifndef HAVE_TOUCHSCREEN
# error pluginlib_actions: No directions defined
@ -517,7 +526,7 @@ const struct button_mapping pla_main_ctx[] =
{PLA_SELECT, BUTTON_SELECT, BUTTON_NONE},
{PLA_SELECT_REL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT},
{PLA_SELECT_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE},
#elif (CONFIG_KEYPAD == SHANLING_Q1_PAD)
#elif (CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD)
{PLA_EXIT, BUTTON_POWER, BUTTON_NONE},
#elif (CONFIG_KEYPAD == MA_PAD)
{PLA_CANCEL, BUTTON_BACK|BUTTON_REL, BUTTON_BACK},
@ -531,6 +540,12 @@ const struct button_mapping pla_main_ctx[] =
{PLA_SELECT, BUTTON_A, BUTTON_NONE},
{PLA_SELECT_REL, BUTTON_A|BUTTON_REL, BUTTON_A},
{PLA_SELECT_REPEAT, BUTTON_A|BUTTON_REPEAT, BUTTON_NONE},
#elif (CONFIG_KEYPAD == CTRU_PAD)
{PLA_CANCEL, BUTTON_BACK, BUTTON_NONE},
{PLA_EXIT, BUTTON_MENU, BUTTON_NONE},
{PLA_SELECT, BUTTON_SELECT, BUTTON_NONE},
{PLA_SELECT_REL, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT},
{PLA_SELECT_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE},
#else
# ifndef HAVE_TOUCHSCREEN
# error pluginlib_actions: No actions defined

View file

@ -2526,20 +2526,10 @@ static bool check_audio_status(void)
}
return false;
}
static void ff_rewind(long time, bool resume)
static void ff_rewind(long time)
{
if (AUDIO_PLAY)
{
if (!AUDIO_PAUSE)
{
resume = true;
rb->audio_pause();
}
rb->audio_ff_rewind(time);
rb->sleep(HZ/10); /* take affect seeking */
if (resume)
rb->audio_resume();
}
rb->audio_ff_rewind(time);
rb->sleep(HZ/10); /* take effect seeking */
}
static int handle_button(void)
@ -2603,15 +2593,14 @@ static int handle_button(void)
else
{
current.ff_rewind = current.elapsed;
if (!AUDIO_PAUSE)
rb->audio_pause();
rb->audio_pre_ff_rewind();
step = 1000 * rb->global_settings->ff_rewind_min_step;
}
break;
case ACTION_WPS_STOPSEEK:
if (current.ff_rewind == -1)
break;
ff_rewind(current.ff_rewind, !AUDIO_PAUSE);
ff_rewind(current.ff_rewind);
current.elapsed = current.ff_rewind;
current.ff_rewind = -1;
break;
@ -2620,9 +2609,14 @@ static int handle_button(void)
break;
case ACTION_WPS_SKIPPREV:
if (current.elapsed < 3000)
{
rb->audio_prev();
}
else
ff_rewind(0, false);
{
rb->audio_pre_ff_rewind();
ff_rewind(0);
}
break;
case ACTION_WPS_VOLDOWN:
rb->adjust_volume(-1);

View file

@ -31,7 +31,6 @@ rockaux.c
rocklib.c
rocklib_img.c
tlsf_helper.c
strftime.c
strpbrk.c
rocklua.c
luadir.c

View file

@ -31,6 +31,7 @@ rb.audio_pause = function() rb.audio("pause") end
rb.audio_resume = function() rb.audio("resume") end
rb.audio_next = function() rb.audio("next") end
rb.audio_prev = function() rb.audio("prev") end
rb.audio_pre_ff_rewind = function () rb.audio("pre_ff_rewind") end
rb.audio_ff_rewind = function (newtime) rb.audio("ff_rewind", newtime) end
rb.audio_flush_and_reload_tracks = function() rb.audio("flush_and_reload_tracks") end
rb.audio_get_file_pos = function() return rb.audio("get_file_pos") end

View file

@ -0,0 +1,299 @@
--[[
__________ __ ___.
Open \______ \ ____ ____ | | _\_ |__ _______ ___
Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
\/ \/ \/ \/ \/
$Id$
strfrtime
Copyright (C) 2026 William Wilgus
gmtime
* Copyright (C) 2017 by Michael Sevakis
* Copyright (C) 2012 by Bertrik Sikken
* Based on code from: rtc_as3514.c
* Copyright (C) 2007 by Barry Wardell
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
KIND, either express or implied.
]]--
-- Lua implementation of strftime
-- if not os.time() then rb.splash(rb.HZ, "No Support!") return nil end
-- Weekday and month names
local weekdays = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
local months = {"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
}
--local ampm = {"am", "pm", "AM", "PM"}
local strformat = string.format
-- Main strftime function
local function strftime(tmfmt, tm)
local result = {}
local i = 1
while i <= #tmfmt do
local out = ""
local c = tmfmt:sub(i,i)
if c == "%" then
i = i + 1
c = tmfmt:sub(i,i)
if c ~= "%" then
local handled
repeat
handled = true
if c == "n" then
out = "\n"
elseif c == "N" then --custom for rocklua
out = strftime("%a %d %T %b %Y", tm)
elseif c == "t" then
out = "\t"
elseif c == "c" then
out = strftime("%x %T %Z %Y", tm)
elseif c == "r" then
out = strftime("%I:%M:%S %p", tm)
elseif c == "R" then
out = strftime("%H:%M", tm)
elseif c == "x" then
out = strftime("%b %a %d", tm)
elseif c == "T" or c == "X" then
out = strformat("%02d:%02d:%02d",
tm.hour, tm.min, tm.sec)
elseif c == "D" then
out = strformat("%02d/%02d/%02d",
tm.mon, tm.day, tm.year % 100)
elseif c == "F" then
out = strftime("%Y-%m-%d", tm)
elseif c == "a" then
out = weekdays[tm.wday + 1]:sub(1, 3)
elseif c == "A" then
out = weekdays[tm.wday + 1]
elseif c == "h" or c == "b" then
out = months[tm.month + 1]:sub(1, 3)
elseif c == "B" then
out = months[tm.month + 1]
elseif c == "p" then
--local idx = tm.hour > 12 and 4 or 5
out = tm.hour > 12 and "PM" or "AM"
elseif c == "P" then
--local idx = tm.hour > 12 and 2 or 1
out = tm.hour > 12 and "pm" or "am"
elseif c == "C" then
local no = (tm.year / 100) + 19
out = strformat("%02d", no)
elseif c == "d" then
out = strformat("%02d", tm.day)
elseif c == "e" then
out = strformat("%2.0d", tm.day)
elseif c == "H" then
out = strformat("%02d", tm.hour)
elseif c == "I" then
local no = tm.hour % 12
if no == 0 then no = 12 end
out = strformat("%02d", no)
elseif c == "j" then
out = strformat("%03d", tm.yday)
elseif c == "k" then
out = strformat("%2.0d", tm.hour)
elseif c == "l" then
local no = tm.hour % 12
if no == 0 then no = 12 end
out = strformat("%2.0d", no)
elseif c == "m" then
out = strformat("%02d", tm.mon)
elseif c == "M" then
out = strformat("%02d", tm.min)
elseif c == "S" then
out = strformat("%02d", tm.sec)
elseif c == "u" then
local no = tm.wday == 0 and 7 or tm.wday
out = strformat("%d", no)
elseif c == "w" then
out = strformat("%d", tm.wday)
elseif c == "U" then
local no = ((tm.yday - tm.wday + 7) / 7)
out = strformat("%02d", no)
elseif c == "W" then
local no = ((tm.yday - (tm.wday + 7) % 7 + 7) / 7)
out = strformat("%02d", no)
elseif c == "s" then
out = os.time()
elseif c == "Z" then
out = "[ETC?]"
elseif c == "Y" then
local y1 = (tm.year / 100) + 19
local y2 = tm.year % 100
out = strformat("%02d%02d", y1, y2)
elseif c == "y" then
out = strformat("%02d", tm.year % 100)
elseif c == "O" or c == "E" then
i = i + 1
c = tmfmt:sub(i,i)
handled = false
else
out = "%" .. c
end
until (handled == true)
else -- c == "%"
out = "%"
end
else
out = c
end
table.insert(result, out)
i = i + 1
end
return table.concat(result)
end
--[[
Note: This implementation assumes the following structure for the `tm`
table (similar to C's `struct tm`):
local tm = {
year = 126, -- Years since 1900
mon = 0, -- Month (0-11)
day = 5, -- Day of month (1-31)
hour = 14, -- Hours (0-23)
min = 30, -- Minutes (0-59)
sec = 45, -- Seconds (0-59)
wday = 2, -- Day of week (0-6, Sunday=0)
yday = 4, -- Day of year (0-365)
isdst = false -- Daylight saving time flag
}
For a complete implementation, you would need to add proper timezone handling
]]
local UNIX_EPOCH_DAY_NUM = 134774
local UNIX_EPOCH_YEAR = (1601 - 1900)
-- Last day number it can do
local MAX_DAY_NUM = 551879
--[[ d is days since epoch start, Monday, 1 January 1601 (d = 0) + UNIX_EPOCH_DAY_NUM
*
* That date is the beginning of a full 400 year cycle and so simplifies the
* calculations a bit, not requiring offsets before divisions to shift the
* leap year cycle.
*
* It can handle dates up through Sunday, 31 December 3111 (d = 551879).
*
* time_t can't get near the limits anyway for now but algorithm can be
* altered slightly to increase range if even needed.
--Different than the rockbox version starting from midnight UTC on January 1, 1970
]]
local mon_yday = {
-- year day of 1st of month (non-leap)
-- +31 +28 +31 +30 +31 +30 +31 +31 +30 +31 +30 +31 +31
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
}
local function get_tmdate(d, tm)
d = d + UNIX_EPOCH_DAY_NUM -- different than the rb version
local x0 = (d / 1460)
local x1 = (x0 / 25)
local x2 = (x1 / 4)
local y = ((d - x0 + x1 - x2) / 365)
x0 = (y / 4)
x1 = (x0 / 25)
x2 = (x1 / 4)
local yday = d - x0 + x1 - x2 - y * 365
local x3 = yday
local tm_yday = yday
-- check if leap year; adjust February->March transition if so rather
-- than keeping a leap year version of mon_yday[]
if y - x0 * 4 == 3 and (x0 - x1 * 25 ~= 24 or x1 - x2 * 4 == 3) then
if x3 >= mon_yday[3] then
x3 = x3 - 1
if x3 >= mon_yday[3] then
yday = yday - 1
end
end
end
-- stab approximately at current month based on year day; advance if
-- it fell short (never initially more than 1 short).
x0 = (x3 / 32)
if mon_yday[x0 + 2] <= x3 then
x0 = x0 + 1
end
tm = tm or {}
tm.year = y + UNIX_EPOCH_YEAR -- year - 1900
tm.month = x0 -- 0..11
tm.yday = tm_yday
tm.day = yday - mon_yday[x0 + 1] + 1 -- 1..31
tm.wday = (d + 1) % 7 -- 0..6
return tm--return tm
end
local function gmtime(t, tm)
tm = tm or {}
local d = (t / 86400)
local s = t - d * 86400
if s < 0 then
d = d - 1
s = s + 86400
end
local x = (s / 3600)
tm.hour = x -- 0..23
s = s - x * 3600
x = (s / 60)
tm.min = x -- 0..59
s = s - x * 60
tm.sec = s -- 0..59
tm.isdst = false -- not implemented right now
return get_tmdate(d, tm)
end
local function os_date(format_string, timestamp)
format_string = format_string or "%N"
timestamp = timestamp or os.time()
if format_string:sub(1, 1) == "!" then -- UTC
format_string = format_string:sub(2)
--else -- Localtime -- Rockbox doesn't support timezones
--timestamp = get_tz(timestamp)
end
local tt = gmtime(timestamp);
if format_string == "*t" then
return tt
else
return strftime(format_string, tt)
end
end
--fill os.date
if not os.date() then
os.date = os_date;
end
return {
strftime = strftime;
os_date = os_date;
get_tmdate = get_tmdate;
gmtime = gmtime;
}

View file

@ -25,10 +25,10 @@
#include "lauxlib.h"
#include "rocklibc.h" /* ROCKLUA ADDED */
#define FREELIST_REF 0 /* free list of references */
/* convert a stack index to positive */
#define abs_index(L, i) ((i) > 0 || (i) <= LUA_REGISTRYINDEX ? (i) : \
lua_gettop(L) + (i) + 1)
@ -701,7 +701,7 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
*size = 1;
return "\n";
}
*size = rb->read(lf->f, lf->buff, LUAL_BUFFERSIZE);
*size = read(lf->f, lf->buff, LUAL_BUFFERSIZE);
return (*size > 0) ? lf->buff : NULL;
}
@ -719,11 +719,11 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
int status;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
lf.f = rb->open(filename, O_RDONLY);
lf.f = open(filename, O_RDONLY);
lua_pushfstring(L, "@%s", filename);
if (lf.f < 0) return errfile(L, "open", fnameindex);
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
rb->close(lf.f);
close(lf.f);
lua_remove(L, fnameindex);
return status;
}
@ -794,7 +794,7 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
static int panic (lua_State *L) {
DEBUGF("PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
rb->splashf(5 * HZ, "PANIC: unprotected error in call to Lua API (%s)",
splashf(5 * HZ, "PANIC: unprotected error in call to Lua API (%s)",
lua_tostring(L, -1));
return 0;

View file

@ -8,7 +8,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rocklibc.h" /* ROCKLUA ADDED */
#define liolib_c
#define LUA_LIB
@ -16,8 +16,8 @@
#include "lauxlib.h"
#include "lualib.h"
#include "rocklibc.h"
#include "rocklib.h"
#include "rocklib.h" /* ROCKLUA ADDED */
#include "llimits.h"
@ -96,7 +96,7 @@ static int* newfile (lua_State *L) {
*/
static int io_fclose (lua_State *L) {
int *p = tofile(L);
int ok = (rb->close(*p) == 0);
int ok = (close(*p) == 0);
*p = -1;
return pushresult(L, ok, NULL);
}
@ -165,7 +165,7 @@ static int io_open (lua_State *L) {
flags |= wrmode;
*pf = rb->open(filename, flags, 0666);
*pf = open(filename, flags, 0666);
return (*pf < 0) ? pushresult(L, 0, filename) : 1;
}
@ -185,7 +185,7 @@ static int g_iofile (lua_State *L, int f, int flags) {
const char *filename = lua_tostring(L, 1);
if (filename) {
int *pf = newfile(L);
*pf = rb->open(filename, flags);
*pf = open(filename, flags);
if (*pf < 0)
fileerror(L, 1, filename);
}
@ -237,7 +237,7 @@ static int io_lines (lua_State *L) {
else {
const char *filename = luaL_checkstring(L, 1);
int *pf = newfile(L);
*pf = rb->open(filename, O_RDONLY);
*pf = open(filename, O_RDONLY);
if (*pf < 0)
fileerror(L, 1, filename);
aux_lines(L, lua_gettop(L), 1);
@ -266,9 +266,9 @@ static int read_number (lua_State *L, int *f) {
static int test_eof (lua_State *L, int *f) {
off_t s = rb->lseek(*f, 0, SEEK_CUR);
off_t s = lseek(*f, 0, SEEK_CUR);
lua_pushlstring(L, NULL, 0);
return s < rb->filesize(*f);
return s < filesize(*f);
}
@ -279,7 +279,7 @@ static int _read_line (lua_State *L, int *f) {
for (;;) {
size_t l;
char *p = luaL_prepbuffer(&b);
off_t r = rb->read_line(*f, p, LUAL_BUFFERSIZE); /* does not include `eol' */
off_t r = read_line(*f, p, LUAL_BUFFERSIZE); /* does not include `eol' */
if (r <= 0) { /* eof? */
luaL_pushresult(&b); /* close buffer */
return (lua_objlen(L, -1) > 0); /* check whether read something */
@ -304,7 +304,7 @@ static int read_chars (lua_State *L, int *f, size_t n) {
do {
char *p = luaL_prepbuffer(&b);
if (rlen > n) rlen = n; /* cannot read more than asked */
nr = rb->read(*f, p, rlen);
nr = read(*f, p, rlen);
if (nr < 0)
luaL_error(L, "error reading file");
luaL_addsize(&b, nr);
@ -396,12 +396,12 @@ static int g_write (lua_State *L, int *f, int arg) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
status = status &&
rb->fdprintf(*f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
fdprintf(*f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
}
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
status = status && (rb->write(*f, s, l) == (ssize_t)l);
status = status && (write(*f, s, l) == (ssize_t)l);
}
}
return pushresult(L, status, NULL);
@ -424,7 +424,7 @@ static int f_seek (lua_State *L) {
int *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
long offset = luaL_optlong(L, 3, 0);
off_t size = rb->lseek(*f, offset, mode[op]);
off_t size = lseek(*f, offset, mode[op]);
if (size < 0 || size > MAX_INT) /* signed limit */
return pushresult(L, 0, NULL); /* error */
else {

View file

@ -191,7 +191,7 @@ static int math_max (lua_State *L) {
static int math_random (lua_State *L) {
/* We're not SunOS */
lua_Number r = (lua_Number)(rb->rand());
lua_Number r = (lua_Number)(rand());
switch (lua_gettop(L)) { /* check number of arguments */
case 0: { /* no arguments */
lua_pushnumber(L, r); /* Number between 0 and RAND_MAX */
@ -217,7 +217,7 @@ static int math_random (lua_State *L) {
static int math_randomseed (lua_State *L) {
rb->srand(luaL_checkint(L, 1));
srand(luaL_checkint(L, 1));
return 0;
}

View file

@ -34,9 +34,9 @@
static int readable (const char *filename) {
int f = rb->open(filename, O_RDONLY); /* try to open file */
int f = open(filename, O_RDONLY); /* try to open file */
if (f < 0) return 0; /* open failed */
rb->close(f);
close(f);
return 1;
}

View file

@ -17,7 +17,7 @@
#include "lauxlib.h"
#include "lualib.h"
#include "rocklibc.h" /* ROCKLUA ADDED */
static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
@ -36,14 +36,14 @@ static int os_pushresult (lua_State *L, int i, const char *filename) {
static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
return os_pushresult(L, rb->remove(filename) == 0, filename);
return os_pushresult(L, remove(filename) == 0, filename);
}
static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
return os_pushresult(L, rb->rename(fromname, toname) == 0, fromname);
return os_pushresult(L, rename(fromname, toname) == 0, fromname);
}
@ -54,7 +54,7 @@ static int os_rename (lua_State *L) {
** wday=%w+1, yday=%j, isdst=? }
** =======================================================
*/
#if 0 /* supplied by strfrtime.lua*/
static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
@ -66,6 +66,7 @@ static void setboolfield (lua_State *L, const char *key, int value) {
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
#endif
#if CONFIG_RTC
static int getboolfield (lua_State *L, const char *key) {
@ -94,10 +95,11 @@ static int getfield (lua_State *L, const char *key, int d) {
static int os_date (lua_State *L) {
#if 0
const char *s = luaL_optstring(L, 1, "%c");
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2,
#if CONFIG_RTC
rb->mktime(rb->get_time())
mktime(get_time())
#else
0
#endif
@ -139,13 +141,18 @@ static int os_date (lua_State *L) {
luaL_pushresult(&b);
}
return 1;
#else /* supplied by strfrtime.lua*/
lua_pushnil(L);
return 1;
#endif
}
static int os_time (lua_State *L) {
time_t t = -1;
#if CONFIG_RTC
if (lua_isnoneornil(L, 1)) /* called without args? */
t = rb->mktime(rb->get_time()); /* get current time */
t = mktime(get_time()); /* get current time */
else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
@ -157,7 +164,7 @@ static int os_time (lua_State *L) {
ts.tm_mon = getfield(L, "month", -1) - 1;
ts.tm_year = getfield(L, "year", -1) - 1900;
ts.tm_isdst = getboolfield(L, "isdst");
t = rb->mktime(&ts);
t = mktime(&ts);
}
#endif
if (t == (time_t)(-1))

View file

@ -0,0 +1,212 @@
--[[
__________ __ ___.
Open \______ \ ____ ____ | | _\_ |__ _______ ___
Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
\/ \/ \/ \/ \/
$Id$
Copyright (C) 2026 William Wilgus
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
KIND, either express or implied.
]]--
if not os.time() then rb.splash(rb.HZ, "No Support!") return nil end
local timefns = require("strftime")
-- Random timestamps with expected UTC tm fields
-- yday is 0-based, wday is 1=Sunday
local tests = {
{ts = 0, --Thu Jan 1 00:00:00 1970
tm = {year=70, month=0, day=1, hour=0, min=0, sec=0, wday=4, yday=0}},
{ts = 15620300, --Tue Jun 30 18:58:20 1970
tm = {year=70, month=5, day=30, hour=18, min=58, sec=20, wday=2, yday=180}},
{ts = 70679700, --Wed Mar 29 01:15:00 1972
tm = {year=72, month=2, day=29, hour=1, min=15, sec=0, wday=3, yday=88}},
{ts = 118231000, --Sun Sep 30 09:56:40 1973
tm = {year=73, month=8, day=30, hour=9, min=56, sec=40, wday=0, yday=272}},
{ts = 135663600, --Sat Apr 20 04:20:00 1974
tm = {year=74, month=3, day=20, hour=4, min=20, sec=0, wday=6, yday=109}},
{ts = 142740200, --Thu Jul 11 02:03:20 1974
tm = {year=74, month=6, day=11, hour=2, min=3, sec=20, wday=4, yday=191}},
{ts = 161467300, --Wed Feb 12 20:01:40 1975
tm = {year=75, month=1, day=12, hour=20, min=1, sec=40, wday=3, yday=42}},
{ts = 163538500, --Sat Mar 8 19:21:40 1975
tm = {year=75, month=2, day=8, hour=19, min=21, sec=40, wday=6, yday=66}},
{ts = 199525600, --Wed Apr 28 07:46:40 1976
tm = {year=76, month=3, day=28, hour=7, min=46, sec=40, wday=3, yday=118}},
{ts = 251219300, --Sat Dec 17 15:08:20 1977
tm = {year=77, month=11, day=17, hour=15, min=8, sec=20, wday=6, yday=350}},
{ts = 265027300, --Fri May 26 10:41:40 1978
tm = {year=78, month=4, day=26, hour=10, min=41, sec=40, wday=5, yday=145}},
{ts = 274951800, --Mon Sep 18 07:30:00 1978
tm = {year=78, month=8, day=18, hour=7, min=30, sec=0, wday=1, yday=260}},
{ts = 286861200, --Sat Feb 3 03:40:00 1979
tm = {year=79, month=1, day=3, hour=3, min=40, sec=0, wday=6, yday=33}},
{ts = 299892500, --Tue Jul 3 23:28:20 1979
tm = {year=79, month=6, day=3, hour=23, min=28, sec=20, wday=2, yday=183}},
{ts = 324488000, --Sun Apr 13 15:33:20 1980
tm = {year=80, month=3, day=13, hour=15, min=33, sec=20, wday=0, yday=103}},
{ts = 369450300, --Wed Sep 16 01:05:00 1981
tm = {year=81, month=8, day=16, hour=1, min=5, sec=0, wday=3, yday=258}},
{ts = 423042600, --Sun May 29 07:50:00 1983
tm = {year=83, month=4, day=29, hour=7, min=50, sec=0, wday=0, yday=148}},
{ts = 442891600, --Sat Jan 14 01:26:40 1984
tm = {year=84, month=0, day=14, hour=1, min=26, sec=40, wday=6, yday=13}},
{ts = 449968200, --Wed Apr 4 23:10:00 1984
tm = {year=84, month=3, day=4, hour=23, min=10, sec=0, wday=3, yday=94}},
{ts = 468609000, --Tue Nov 6 17:10:00 1984
tm = {year=84, month=10, day=6, hour=17, min=10, sec=0, wday=2, yday=310}},
{ts = 477670500, --Tue Feb 19 14:15:00 1985
tm = {year=85, month=1, day=19, hour=14, min=15, sec=0, wday=2, yday=49}},
{ts = 481295100, --Tue Apr 2 13:05:00 1985
tm = {year=85, month=3, day=2, hour=13, min=5, sec=0, wday=2, yday=91}},
{ts = 543517400, --Mon Mar 23 17:03:20 1987
tm = {year=87, month=2, day=23, hour=17, min=3, sec=20, wday=1, yday=81}},
{ts = 599439800, --Thu Dec 29 23:03:20 1988
tm = {year=88, month=11, day=29, hour=23, min=3, sec=20, wday=4, yday=363}},
{ts = 653808800, --Thu Sep 20 05:33:20 1990
tm = {year=90, month=8, day=20, hour=5, min=33, sec=20, wday=4, yday=262}},
{ts = 670723600, --Thu Apr 4 00:06:40 1991
tm = {year=91, month=3, day=4, hour=0, min=6, sec=40, wday=4, yday=93}},
{ts = 718274900, --Mon Oct 5 08:48:20 1992
tm = {year=92, month=9, day=5, hour=8, min=48, sec=20, wday=1, yday=278}},
{ts = 725351500, --Sat Dec 26 06:31:40 1992
tm = {year=92, month=11, day=26, hour=6, min=31, sec=40, wday=6, yday=360}},
{ts = 760389300, --Fri Feb 4 19:15:00 1994
tm = {year=94, month=1, day=4, hour=19, min=15, sec=0, wday=5, yday=34}},
{ts = 763841300, --Wed Mar 16 18:08:20 1994
tm = {year=94, month=2, day=16, hour=18, min=8, sec=20, wday=3, yday=74}},
{ts = 765135800, --Thu Mar 31 17:43:20 1994
tm = {year=94, month=2, day=31, hour=17, min=43, sec=20, wday=4, yday=89}},
{ts = 814930900, --Sun Oct 29 01:41:40 1995
tm = {year=95, month=9, day=29, hour=1, min=41, sec=40, wday=0, yday=301}},
{ts = 834003200, --Wed Jun 5 19:33:20 1996
tm = {year=96, month=5, day=5, hour=19, min=33, sec=20, wday=3, yday=156}},
{ts = 890270800, --Thu Mar 19 01:26:40 1998
tm = {year=98, month=2, day=19, hour=1, min=26, sec=40, wday=4, yday=77}},
{ts = 924445600, --Sun Apr 18 14:26:40 1999
tm = {year=99, month=3, day=18, hour=14, min=26, sec=40, wday=0, yday=107}},
{ts = 960864200, --Tue Jun 13 02:43:20 2000
tm = {year=100, month=5, day=13, hour=2, min=43, sec=20, wday=2, yday=164}},
{ts = 961123100, --Fri Jun 16 02:38:20 2000
tm = {year=100, month=5, day=16, hour=2, min=38, sec=20, wday=5, yday=167}},
{ts = 1014025000, --Mon Feb 18 09:36:40 2002
tm = {year=102, month=1, day=18, hour=9, min=36, sec=40, wday=1, yday=48}},
{ts = 1052514800, --Fri May 9 21:13:20 2003
tm = {year=103, month=4, day=9, hour=21, min=13, sec=20, wday=5, yday=128}},
{ts = 1088760800, --Fri Jul 2 09:33:20 2004
tm = {year=104, month=6, day=2, hour=9, min=33, sec=20, wday=5, yday=183}},
{ts = 1130184800, --Mon Oct 24 20:13:20 2005
tm = {year=105, month=9, day=24, hour=20, min=13, sec=20, wday=1, yday=296}},
{ts = 1182396300, --Thu Jun 21 03:25:00 2007
tm = {year=107, month=5, day=21, hour=3, min=25, sec=0, wday=4, yday=171}},
{ts = 1228566800, --Sat Dec 6 12:33:20 2008
tm = {year=108, month=11, day=6, hour=12, min=33, sec=20, wday=6, yday=340}},
{ts = 1281900200, --Sun Aug 15 19:23:20 2010
tm = {year=110, month=7, day=15, hour=19, min=23, sec=20, wday=0, yday=226}},
{ts = 1284057700, --Thu Sep 9 18:41:40 2010
tm = {year=110, month=8, day=9, hour=18, min=41, sec=40, wday=4, yday=251}},
{ts = 1291652100, --Mon Dec 6 16:15:00 2010
tm = {year=110, month=11, day=6, hour=16, min=15, sec=0, wday=1, yday=339}},
{ts = 1326776200, --Tue Jan 17 04:56:40 2012
tm = {year=112, month=0, day=17, hour=4, min=56, sec=40, wday=2, yday=16}},
{ts = 1382439700, --Tue Oct 22 11:01:40 2013
tm = {year=113, month=9, day=22, hour=11, min=1, sec=40, wday=2, yday=294}},
{ts = 1409796800, --Thu Sep 4 02:13:20 2014
tm = {year=114, month=8, day=4, hour=2, min=13, sec=20, wday=4, yday=246}},
{ts = 1451997500, --Tue Jan 5 12:38:20 2016
tm = {year=116, month=0, day=5, hour=12, min=38, sec=20, wday=2, yday=4}},
{ts = 1463216500, --Sat May 14 09:01:40 2016
tm = {year=116, month=4, day=14, hour=9, min=1, sec=40, wday=6, yday=134}},
{ts = 1499635100, --Sun Jul 9 21:18:20 2017
tm = {year=117, month=6, day=9, hour=21, min=18, sec=20, wday=0, yday=189}},
{ts = 1545460400, --Sat Dec 22 06:33:20 2018
tm = {year=118, month=11, day=22, hour=6, min=33, sec=20, wday=6, yday=355}},
{ts = 1555816400, --Sun Apr 21 03:13:20 2019
tm = {year=119, month=3, day=21, hour=3, min=13, sec=20, wday=0, yday=110}},
{ts = 1585072100, --Tue Mar 24 17:48:20 2020
tm ={year=120, month=2, day=24, hour=17, min=48, sec=20, wday=2, yday=83}},
{ts = 1622181100, --Fri May 28 05:51:40 2021
tm = {year=121, month=4, day=28, hour=5, min=51, sec=40, wday=5, yday=147}},
{ts = 1649451900, --Fri Apr 8 21:05:00 2022
tm = {year=122, month=3, day=8, hour=21, min=5, sec=0, wday=5, yday=97}},
{ts = 1663173600, --Wed Sep 14 16:40:00 2022
tm = {year=122, month=8, day=14, hour=16, min=40, sec=0, wday=3, yday=256}},
{ts = 1707272900, --Wed Feb 7 02:28:20 2024
tm = {year=124, month=1, day=7, hour=2, min=28, sec=20, wday=3, yday=37}},
{ts = 1769495200, --Tue Jan 27 06:26:40 2026
tm = {year=126, month=0, day=27, hour=6, min=26, sec=40, wday=2, yday=26}},
{ts = 1786582600, --Thu Aug 13 00:56:40 2026
tm = {year=126, month=7, day=13, hour=0, min=56, sec=40, wday=4, yday=224}},
{ts = 1831890100, --Wed Jan 19 10:21:40 2028
tm = {year=128, month=0, day=19, hour=10, min=21, sec=40, wday=3, yday=18}},
{ts = 1880735900, --Mon Aug 6 18:38:20 2029
tm = {year=129, month=7, day=6, hour=18, min=38, sec=20, wday=1, yday=217}},
{ts = 1916809300, --Sat Sep 28 07:01:40 2030
tm = {year=130, month=8, day=28, hour=7, min=1, sec=40, wday=6, yday=270}},
{ts = 1955299100, --Wed Dec 17 18:38:20 2031
tm = {year=131, month=11, day=17, hour=18, min=38, sec=20, wday=3, yday=350}},
{ts = 1975234400, --Wed Aug 4 12:13:20 2032
tm = {year=132, month=7, day=4, hour=12, min=13, sec=20, wday=3, yday=216}},
{ts = 1984554800, --Sat Nov 20 09:13:20 2032
tm = {year=132, month=10, day=20, hour=9, min=13, sec=20, wday=6, yday=324}},
{ts = 2023217200, --Fri Feb 10 20:46:40 2034
tm = {year=134, month=1, day=10, hour=20, min=46, sec=40, wday=5, yday=40}},
{ts = 2032882800, --Fri Jun 2 17:40:00 2034
tm = {year=134, month=5, day=2, hour=17, min=40, sec=0, wday=5, yday=152}},
{ts = 2080606700, --Fri Dec 7 02:18:20 2035
tm = {year=135, month=11, day=7, hour=2, min=18, sec=20, wday=5, yday=340}},
{ts = 2092429800, --Mon Apr 21 22:30:00 2036
tm = {year=136, month=3, day=21, hour=22, min=30, sec=0, wday=1, yday=111}},
{ts = 2131903647, --Wednesday July 22, 2037 19:27:27 (pm) in time zone UTC (UTC)
tm = {year=137, month=6, day=22, hour=19, min=27, sec=27, wday=3, yday=202}},
}
local function check_field(entry, timestamp, name, got, exp)
if not got or not exp then
return false , string.format("entry: %d ts: %d error: key[%s] does not exist", entry, timestamp, name)
end
if got ~= exp then
return false, string.format("entry: %d ts: %d error: key[%s] mismatch got %d, expected %d",
entry, timestamp, name, got, exp)
end
return true
end
local passed = 0;
local ok = true;
for _, test in ipairs(tests) do
local s_t = {}
s_t[1] = ""
local out = {}
timefns.gmtime(test.ts, out)
for k, exp in pairs(test.tm) do
local pass, err = check_field(passed, test.ts, k, out[k], exp)
if not pass then
ok = false
s_t[#s_t + 1] = err;
break
end
end
if not ok then
s_t[1] = "FAIL"
rb.splash_scroller(10 * rb.HZ, table.concat(s_t, "\n"))
break;
end
passed = passed + 1
end
if ok then
rb.splash(rb.HZ * 5, tostring(passed) .. " / " .. #tests .. " timestamps match")
end

View file

@ -37,13 +37,13 @@ typedef struct dir_data {
static int make_dir (lua_State *L) {
const char *path = luaL_checkstring (L, 1);
lua_pushboolean (L, !rb->mkdir(path));
lua_pushboolean (L, !mkdir(path));
return 1;
}
static int remove_dir (lua_State *L) {
const char *path = luaL_checkstring (L, 1);
lua_pushboolean (L, !rb->rmdir (path));
lua_pushboolean (L, !rmdir (path));
return 1;
}
@ -57,8 +57,8 @@ static int dir_iter (lua_State *L) {
luaL_argcheck (L, !d->closed, 1, "closed directory");
if ((entry = rb->readdir (d->dir)) != NULL) {
struct dirinfo info = rb->dir_get_info(d->dir, entry);
if ((entry = readdir (d->dir)) != NULL) {
struct dirinfo info = dir_get_info(d->dir, entry);
lua_pushstring (L, entry->d_name);
lua_pushboolean (L, info.attribute & ATTR_DIRECTORY);
if (lua_toboolean (L, lua_upvalueindex(1))) {
@ -77,7 +77,7 @@ static int dir_iter (lua_State *L) {
return 3;
} else {
/* no more entries => close directory */
rb->closedir (d->dir);
closedir (d->dir);
d->closed = 1;
return 0;
}
@ -91,7 +91,7 @@ static int dir_close (lua_State *L) {
dir_data *d = (dir_data *)lua_touserdata (L, 1);
if (!d->closed && d->dir) {
rb->closedir (d->dir);
closedir (d->dir);
d->closed = 1;
}
return 0;
@ -111,7 +111,7 @@ static int dir_iter_factory (lua_State *L) {
luaL_getmetatable (L, DIR_METATABLE);
lua_setmetatable (L, -2);
d->dir = rb->opendir (path);
d->dir = opendir (path);
if (d->dir == NULL)
{
luaL_error (L, "cannot open %s: %d", path, errno);

View file

@ -21,10 +21,22 @@
*
****************************************************************************/
#include "plugin.h"
#define _ROCKCONF_H_ /* Protect against unwanted include */
#include "lua.h"
#include "rocklibc.h" /* ROCKLUA ADDED */
#ifdef PLUGIN
#include "plugin.h"
#include "lib/pluginlib_actions.h"
#define lcd_getstringsize rb->lcd_getstringsize
#define lcd_clear_display rb->lcd_clear_display
#define lcd_putsxy rb->lcd_putsxy
#define lcd_update rb->lcd_update
#define beep_play rb->beep_play
#define get_action rb->get_action
#if 0 /* ndef _WIN32 -- supplied by strfrtime.lua */
#define gmtime_r rb->gmtime_r
#endif
#endif /* def PLUGIN*/
extern const char *strpbrk_n(const char *s, int smax, const char *accept);
@ -54,7 +66,7 @@ int splash_scroller(int timeout, const char* str)
if (!str)
str = "[nil]";
int w, ch_w, ch_h;
rb->lcd_getstringsize("W", &ch_w, &ch_h);
lcd_getstringsize("W", &ch_w, &ch_h);
const int max_w = LCD_WIDTH - (ch_w * 2);
const int max_lines = LCD_HEIGHT / ch_h - 1;
@ -74,7 +86,7 @@ int splash_scroller(int timeout, const char* str)
while (cycles > 0)
{
/* walk whole buffer every refresh, only display relevant portion */
rb->lcd_clear_display();
lcd_clear_display();
curline = 0;
linepos = 0;
linesdisp = 0;
@ -89,7 +101,7 @@ int splash_scroller(int timeout, const char* str)
else if (ch[0] == '\b' && timeout > 0)
{
line[linepos] = ' ';
rb->beep_play(1000, HZ, 1000);
beep_play(1000, HZ, 1000);
}
else if (ch[0] < ' ') /* Dont copy control characters */
line[linepos] = (linepos == 0) ? '\0' : ' ';
@ -97,7 +109,7 @@ int splash_scroller(int timeout, const char* str)
line[linepos] = ch[0];
line[linepos + 1] = '\0'; /* terminate to check text extent */
rb->lcd_getstringsize(line, &w, NULL);
lcd_getstringsize(line, &w, NULL);
/* try to not split in middle of words */
if (w + wrap_thresh >= max_w &&
@ -124,7 +136,7 @@ int splash_scroller(int timeout, const char* str)
realline = curline - firstline;
if (realline >= 0 && realline < max_lines)
{
rb->lcd_putsxy(0, realline * ch_h, line);
lcd_putsxy(0, realline * ch_h, line);
linesdisp++;
}
linepos = 0;
@ -134,10 +146,10 @@ int splash_scroller(int timeout, const char* str)
linepos++;
}
rb->lcd_update();
lcd_update();
if (timeout >= TIMEOUT_BLOCK)
{
action = rb->get_action(CONTEXT_STD, timeout);
action = get_action(CONTEXT_STD, timeout);
switch(action)
{
case ACTION_STD_OK:
@ -198,14 +210,14 @@ long rb_pow(long x, long n)
int strcoll(const char * str1, const char * str2)
{
return rb->strcmp(str1, str2);
return strcmp(str1, str2);
}
#ifndef _WIN32
#if 0 //ndef _WIN32 /* supplied by strfrtime.lua*/
struct tm * gmtime(const time_t *timep)
{
static struct tm time;
return rb->gmtime_r(timep, &time);
return gmtime_r(timep, &time);
}
#endif
@ -220,7 +232,7 @@ int get_current_path(lua_State *L, int level)
lua_getinfo(L, "S", &ar);
const char* curfile = &ar.source[1];
const char* pos = rb->strrchr(curfile, '/');
const char* pos = strrchr(curfile, '/');
if(pos != NULL)
{
lua_pushlstring (L, curfile, pos - curfile + 1);
@ -250,7 +262,7 @@ int filetol(int fd, long *num)
bool neg = false;
long val;
while (rb->read(fd, &chbuf, 1) == 1)
while (read(fd, &chbuf, 1) == 1)
{
if(retn || !isspace(chbuf))
{
@ -275,12 +287,12 @@ int filetol(int fd, long *num)
}
}
while (rb->read(fd, &chbuf, 1) == 1)
while (read(fd, &chbuf, 1) == 1)
{
get_digits:
if(!isdigit(chbuf))
{
rb->lseek(fd, -1, SEEK_CUR);
lseek(fd, -1, SEEK_CUR);
break;
}
else if (count < LUAI_MAXNUMBER2STR - 2)
@ -290,7 +302,7 @@ get_digits:
if(count)
{
buffer[count] = '\0';
val = rb->strtol(buffer, NULL, 10);
val = strtol(buffer, NULL, 10);
*num = (neg)? -val:val;
retn = 1;
}

View file

@ -66,6 +66,13 @@ int splash_scroller(int timeout, const char* str);
#define strtoul rb->strtoul
#define strstr rb->strstr
#define yield() rb->yield()
#define gmtime_r rb->gmtime_r
#define mktime rb->mktime
#define get_time rb->get_time
#define read_line(fd,buf,n) rb->read_line(fd,buf,n)
#define fdprintf(...) rb->fdprintf(__VA_ARGS__)
#define splashf(...) rb->splashf(__VA_ARGS__)
#define rand() rb->rand()
#define srand(i) rb->srand(i)
#endif /* _ROCKCONF_H_ */

View file

@ -308,7 +308,7 @@ RB_WRAP(splash)
{
int timeout = luaL_checkint(L, 1);
const char *str = luaL_checkstring(L, 2);
rb->splashf(timeout, str); /*rockaux.c*/
splashf(timeout, str); /*rockaux.c*/
return 0;
}
@ -392,7 +392,7 @@ RB_WRAP(playlist)
pos = luaL_optint(L, 3, PLAYLIST_INSERT);
queue = lua_toboolean(L, 4); /* default to false */
recurse = lua_toboolean(L, 5); /* default to false */
result = rb->playlist_insert_directory(NULL, dir, pos, queue, recurse);
result = rb->playlist_insert_directory(NULL, dir, pos, queue, recurse, NULL);
break;
case PLAYL_INSERTPLAYL:
filename = luaL_checkstring(L, 2); /* only required parameter */
@ -410,12 +410,12 @@ RB_WRAP(playlist)
RB_WRAP(audio)
{
enum e_audio {AUDIO_STATUS = 0, AUDIO_PLAY, AUDIO_STOP, AUDIO_PAUSE,
AUDIO_RESUME, AUDIO_NEXT, AUDIO_PREV, AUDIO_FFREWIND,
AUDIO_FLUSHANDRELOADTRACKS, AUDIO_GETPOS, AUDIO_LENGTH,
AUDIO_ELAPSED, AUDIO_ECOUNT};
AUDIO_RESUME, AUDIO_NEXT, AUDIO_PREV, AUDIO_PREFFREWIND,
AUDIO_FFREWIND, AUDIO_FLUSHANDRELOADTRACKS, AUDIO_GETPOS,
AUDIO_LENGTH, AUDIO_ELAPSED, AUDIO_ECOUNT};
const char *audio_option[] = {"status", "play", "stop",
"pause", "resume", "next",
"prev", "ff_rewind",
"prev", "pre_ff_rewind", "ff_rewind",
"flush_and_reload_tracks",
"get_file_pos", "length",
"elapsed", NULL};
@ -434,6 +434,7 @@ RB_WRAP(audio)
if (status == (AUDIO_STATUS_PLAY | AUDIO_STATUS_PAUSE))
{
/* not perfect but provides a decent compromise */
rb->audio_pre_ff_rewind();
rb->audio_ff_rewind(elapsed + offset);
rb->audio_resume();
}
@ -456,6 +457,9 @@ RB_WRAP(audio)
case AUDIO_PREV:
rb->audio_prev();
break;
case AUDIO_PREFFREWIND:
rb->audio_pre_ff_rewind();
break;
case AUDIO_FFREWIND:
newtime = (long) luaL_checkint(L, 2);
rb->audio_ff_rewind(newtime);

View file

@ -97,7 +97,7 @@ my @forbidden_functions = ('^atoi$',
'^__.+$',
'^.+_(un)?cached$',
'^audio_(status|get_file_pos|flush_and_reload_tracks)$',
'^audio_(ff_rewind|next|prev|play|pause|resume|stop)$',
'^audio_(pre_ff_rewind|ff_rewind|next|prev|play|pause|resume|stop)$',
'^playlist_(amount|add|create|start|resume|shuffle)$',
'^playlist_(sync|resume_track|remove_all_tracks)$',
'^playlist_(insert_track|insert_directory)$',

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