Compare commits

...

240 commits

Author SHA1 Message Date
Solomon Peachy
814979d49b rbutil: Enforce requirement of QT 6.6 or newer
Change-Id: I96064633c00ca2e13cfd9308a7f5d71cba7933cb
2026-07-09 20:32:34 -04:00
Solomon Peachy
d33d2f0840 rbutil: ttsqt: Bail if TTS engine doesn't support saving to file
Change-Id: Iaac0f77836727e5d8853d32a0b47c5d8d62b3365
2026-07-09 20:32:19 -04:00
Vencislav Atanasov
acba3fcb07 rbutilqt: Add the Qt TextToSpeech module as a new optional TTS engine
Co-authored-by: Qwen3.7-Plus
Change-Id: Ib6ddce52eee30139952e6597504ab96517dc15bd
2026-07-09 15:56:49 -04:00
Solomon Peachy
390d17893f rbutil: Rework TTS classes to use a stringlist for arguments
Instead of passing the entire cmdline as a single string that was
treated as the exectuable name on some platforms

Change-Id: Ic4f043a3a48e1b1bfab82bbfa8983c2d224606ec
2026-07-09 15:00:20 -04:00
Solomon Peachy
a9a4b3316f rbutil: Delete the long-disabled and very obsolete SAPI4 TTS code
Change-Id: I24f69cbe646d5c5ddb488a8a1912d028ec017acf
2026-07-09 14:58:37 -04:00
William Wilgus
ca7399821f FS#13953 - lua add get_files() to its own module
get_files(path, recurse, finddir, findfile, sort_by, cancel_fn, f_t, d_t)

get_files returns a sorted tables of directories and (another) of files

path is the starting path; recurse == false.. only that path will be searched

findfile & finddir are definable search functions
 if not defined all files/dirs are returned if false is passed.. none
  or you can provide your own function

sort_by can be by "name" "size" "date" or "none" to perform no sorting
 note: for "size" and "date" you may need to strip the attribute data to use
 the returned filename

cancel_fn if not defined or not a function no user cancel otherwise supply
    your own cancel function which returns true to cancel searching for files

f_t and d_t allow you to pass your own tables for re-use but isn't necessary

Change-Id: Ic4c2ad9c9b5abeeeeaf572880edbc8873d52066b
2026-07-09 12:45:05 -04:00
Solomon Peachy
097403e1a2 Update the RealName and AI sections in docs/CONTRIBUTING
Change-Id: I8cb7b3b8847b8cc9934cc8c055b8ce6a7d0a0add
2026-07-08 10:44:14 -04:00
Vencislav Atanasov
3967180c62 rbutilqt: Simplify Utils::mountpoints() using QStorageInfo
Co-authored-by: Qwen3.7-Plus
Change-Id: I5832963d1a176754315dc28ffab75fa0a06f0334
2026-07-08 03:16:28 +03:00
Vencislav Atanasov
db1ca7c5c1 rbutilqt: Remove Utils::filesystemSize()
Implement the available/total functions using QStorageInfo. Unfortunately, QStorageInfo does not provide cluster size, so there's still some platform-specific code left extracted to Utils::filesystemClusterSize().

Co-authored-by: Qwen3.7-Plus
Change-Id: Iacec829b7d12afb65a966fe15e319d305c7384fd
2026-07-08 03:16:28 +03:00
Vencislav Atanasov
d06fa10485 rbutilqt: Simplify Utils::filesystemType() using QStorageInfo
Co-authored-by: Qwen3.7-Plus
Change-Id: Ia3b51be02d6848199ab573399f566eed7a2df085
2026-07-07 23:38:00 +03:00
Vencislav Atanasov
f62e29f311 rbutilqt: Simplify Utils::findExecutable() using QStandardPaths
Co-authored-by: Qwen3.7-Plus
Change-Id: I8f6f4003ebc7b9a4a8139f5dd4dfca3ae6cff273
2026-07-07 23:35:43 +03:00
Vencislav Atanasov
f9504df7bd rbutilqt: Simplify Utils::recursiveFolderSize() using QDirIterator
Co-authored-by: Qwen3.7-Plus
Change-Id: I73ee0f25c0b06d120364e245f8adf66e9fa09bbf
2026-07-07 23:33:30 +03:00
William Wilgus
40b9d09022 [bugfix] lua ipod mini gen 2 can't quit scripts while under load
I rewrote some of the problematic scripts to use an event loop which
fixed most of the issues but it turns out the underlying issue is
that when the device is under load the timeout that detects a repeat press
makes the key a repeat press and we miss the initial press completely
due to being under load and under the gun

Adds entries for PLA_EXIT and PLA_CANCEL with a Repeat press

Change-Id: I8247b0ebd37fc58608f6be126c49e56f8375e9cf
2026-07-05 22:19:14 -04:00
Solomon Peachy
ebf42dae68 skin_parser: Fix regression in 0d5afa6d
Typo in the #ifdef, accidently didn't get committed.

Change-Id: If74de478ed8f236b78e16cd3cb3957ecde3339b3
2026-07-05 19:12:25 -04:00
mojyack
40c2200152 usb: iap: format
Change-Id: I7ce4a484c8e8f412abc418f1ca9ff1cd14551708
2026-07-05 17:42:06 -04:00
Solomon Peachy
0d5afa6d66 skin_parser: Fix build warnings when included in the theme editor
skin_buffer_to_offset() call can never return a "negative" pointer
(since it just returns the pointer as-is) so don't bother to check.

Change-Id: Id86d53abd7ab1fb071ca54421ebe3b5ff2981c02
2026-07-05 13:57:10 -04:00
Solomon Peachy
8e89f8a5d6 voicefont: Detect when the encoded filename overflows the buffer
...And handle it gracefully.

This shuts up 2 of the 3 remaining rbutil build warnings.

Change-Id: I03b057e566ba663a72cbae159e78070b9934fa0d
2026-07-05 10:07:36 -04:00
Solomon Peachy
7437f7b214 rbutil: Fix up the last of the windows-specific compile warnings.
The remaining ones apply to all targets

Change-Id: Iadb33dfe12349c6fd8329dbba68e762e7bc2095b
2026-07-05 09:59:48 -04:00
Solomon Peachy
04a7a60f8b lubucl: Update from upstream v1.01 to v1.03
Should hopefully address the small pile of windows build warnings

Change-Id: I0bc493ce5c76591eb2e663894702d003933fe14b
2026-07-05 08:06:53 -04:00
Solomon Peachy
f69d40564d rbutil: Add file missing from mspack update
Change-Id: Ie764ed422c328da10e0a6c4144bf3abd30b98d68
2026-07-05 07:59:42 -04:00
Christian Soffke
78ec149555 allow softlock in additional screens
not sure if there's a reason these weren't included
in g#3229

- simple lists
- playlist viewer
- browse_id3
- option select

Change-Id: I0e15aaeb563e68ea21bf5df667ce134d01a95195
2026-07-05 12:59:27 +02:00
Christian Soffke
85adf518ac shortcuts: go to WPS for ACTION_TREE_WPS
Change-Id: Ieab19f90d9cf13b19ce7fe108f3ecb734af1fde0
2026-07-05 06:58:44 -04:00
Christian Soffke
e6b4ec81ff simplelist: support ACTION_TREE_WPS
Also enables support for left/right scrolling

Change-Id: Ic5888b1f17cca429febdab031e158db88a632a4e
2026-07-05 06:58:21 -04:00
Solomon Peachy
a82396b0be rbutil: Update embedded 'mspack' library from 0.10.1alpha to 0.11alpha
Change-Id: I37210d1dc2c5cecdf8256f9e0294dcbd8516e8c8
2026-07-04 21:42:33 -04:00
Michael McAllister
adbb185f7b hibyr1: fix USB gadget UDC unbind (empty write is a no-op)
usb_enable(false) wrote "" to the gadget UDC attribute to unbind it, but
sysfs_set_string("") doesn't do a write syscall.

This meant that live USB-mode switches did nothing and required a reboot to take effect.


Change-Id: I0fc9f54fdb2f529bfe24d5c1ed472c873401080e
2026-07-04 13:50:01 -04:00
Solomon Peachy
b54b10dc6d sansapatcher: Correct use of FormatMessageA() for windows builds
Change-Id: I3e026400fa0440221b4fd6d8c96f515737e36433
2026-07-04 13:04:05 -04:00
Solomon Peachy
aa4ea8e279 ipodpatcher: Correct use of FormatMessageA() for windows builds
When called with FORMAT_MESSAGE_ALLOCATE_BUFFER you need to pass in
a pointer to an LPSTR, not the LPSTR itself.

Change-Id: Iecc6d79edceb2142d61034d61364262126957b46
2026-07-04 12:36:38 -04:00
Solomon Peachy
96f1b19149 rbutil: define USE_LIBUSBAPI for Linux builds
Resolves "DFU not working at all" under rbutil on Linux

And fix some related warnings

Change-Id: Ie44ebc960cfc0c5d0121e8ceb24576ed427746a8
2026-07-04 11:51:49 -04:00
Solomon Peachy
9e6135ecd2 rbutil: Update version in the '.desktop' file
Change-Id: Ifa4a852f8bbc01e9662fae9e5b9ee2140a54116c
2026-07-04 11:13:56 -04:00
Solomon Peachy
9a31255ff8 rbutil: Fix some compile warnings under Windows
Change-Id: I8abfbd61066c17297962de1432144692604cf245
2026-07-04 11:13:56 -04:00
Solomon Peachy
a3be8d1a12 rbutil: Documentation updates
Change-Id: I4782c034593e011d51ec213af1db3a82e6f832f3
2026-07-04 09:39:09 -04:00
Solomon Peachy
55d15b17b7 rbutil: Use 'English' as the default voice in the selection box
Instead of the first one on the (alphabetically sorted) list, currently
Bulgarian.

Ideally we'd try to discern this from the current system/UI language

Change-Id: I82a14716afb484fbaea22f78fe4dd7f00c24252e
2026-07-04 09:35:46 -04:00
Solomon Peachy
6351b64fff rbutil: Change phrasing of message when system quazip is not found
It's not a fatal error (as we build in-tree instead) but the
builder infrastruture was treating it as one.

Change-Id: I7c0d00e36184f8d15642bce4a3bbbd5542943ed6
2026-07-03 16:01:33 -04:00
Solomon Peachy
a097c23db2 usb: Fix warning introduced in f11c89aae2
'usb_power_only' only should exist for USB_FULL_INIT

Change-Id: I23d14477ba55e81048ab29dada8d7d2ee44532b0
2026-07-03 14:45:21 -04:00
Solomon Peachy
f11c89aae2 usb: Fix usb mode not initialized/restored on the DX50/DX90
* Devices with ADB now have HAVE_USB_ADB
 * DX50/DX90 no longer set USB_NONE
   * stub out necessary functions
 * usb_set_mode() and global_settings.usb_mode are now:
   * called for all devices with (HAVE_USB_ADB | HAVE_USB_POWER)
   * wrapped with consistent #ifdefs

Fixes regression in ce88de54b8

Change-Id: Ib0c16082fe237e8159cd42847355186ea5c74589
2026-07-03 12:26:34 -04:00
Solomon Peachy
412a78dd5f mks5lboot/rbutil: When building for Windows, link with 'setupapi'
Change-Id: I92b1be12f7512eb58c3136349cb1f21b552a6477
2026-07-02 17:22:21 -04:00
Roman Artiukhin
ce88de54b8 hosted: Fix USB mode not properly initialized for some targets
All required code is already present in the left usb_set_mode call.
Affects iBasso DX50, iBasso DX90, HiBy R1 and HiBy R3 PRO II.

Fixes FS#13890

Change-Id: Ib554ca98a36ceeaa48c0aa699c3671a40d4fee47
2026-07-02 16:09:10 +03:00
William Wilgus
8a1a3d745d [Bugfix] FS#13947 - Sansa Clip+: High FM background noise when unboosted
Boost the CVDD1 voltage a bit to get rid of static when FM is playing

Change-Id: Id059882ffb5f10bb104b848ee0b646e36fdbe274
2026-07-02 02:57:22 -04:00
William Wilgus
ddc31e8ddc Revert "[Bugfix] FS#13943 - Single mode tracks shorter than one second do not play"
This reverts commit f4e9ba7f17.

Reason for revert: Wasn't the issue??

Change-Id: Ib25ec4b7f90d2ddb0b8a414e18469a9bf5c88140
2026-07-02 01:56:46 -04:00
Vencislav Atanasov
1ded71b751 mks5lboot: Mark uint8_t[] struct members that are initialized from a character array as not containing a null terminator
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I77c3d4b907b175447fef522378d6e61d65f4d2cf
2026-07-01 21:03:49 -04:00
elishay
5c02cf3b3c bidi: do not pass non-ASCII codepoints to ispunct()
bidi_l2v() classified each character with ispunct((int)c), but c is
a decoded Unicode codepoint. ispunct() is only defined for values
that fit in an unsigned char (or EOF); a larger value is undefined
behaviour, and glibc then reads past the ctype table and reports
some codepoints as punctuation.

Hebrew final kaf (U+05DA) and gimel (U+05D2) land on such entries,
so a string ending in one had that letter trimmed off its RTL block
as if it were trailing punctuation and moved to the wrong end of
the line. Limit the punctuation test to ASCII so the result is
well-defined.

Change-Id: Ie6c3d8413f35ec3652e9228e3d5af05ef5bb811a
2026-07-01 21:03:38 -04:00
Vencislav Atanasov
c7d5603c63 mkimxboot: Fix potentially unaligned pointer access of a packed structure
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I437ae173a8f1304a33082e62b86110c9bc4488ba
2026-07-01 17:27:49 +03:00
William Wilgus
f4e9ba7f17 [Bugfix] FS#13943 - Single mode tracks shorter than one second do not play
Change-Id: I8eceb8179231fc7d4c6b8d9c08844a67240c926f
2026-06-30 14:20:01 -04:00
William Wilgus
acff6143c4 FS#13938 - Line disappears after %Vf tag and %Vb tag
As far as I can tell this was indtroduced during this commit
32ff4e93bd
basically they added a NOBREAK flag
to all the commands that had '\n'
where as
    { SKIN_TOKEN_VIEWPORT_FGCOLOUR,       "Vf" , "S"},
    { SKIN_TOKEN_VIEWPORT_BGCOLOUR,       "Vb" , "S"},
do not have \n yet they were changed to have the NOBREAK flag applied
    { SKIN_TOKEN_VIEWPORT_FGCOLOUR,       "Vf" , "S", NOBREAK },
    { SKIN_TOKEN_VIEWPORT_BGCOLOUR,       "Vb" , "S", NOBREAK },
this causes anything after the command to be ignored

-- Note added to manual this will be a won't fix
due to the possibility of breaking existing themes

Change-Id: I0135f04c344bf817c104f951a657e2690f2d36bb
2026-06-30 13:55:03 -04:00
William Wilgus
d87755c535 FS#13944 - FONT_UI loads the last loaded font not global_status.font_id
FONT_UI scans from MAXFONTS-1 to 0 to maximize the chances of getting a loaded
font but this may result in global_status.font_id being ignored even
if set through setuifont

this should take care of all the plugin woes dues to this
by setting the lcd font to the ui font before loading the plugin
and also making FONT_UI map to this font when font_get(FONT_UI) is called
if the desired font is not loaded then fallback to the previous behavior

Change-Id: I101d6f91910c17b08fca2b988a0a99c9e6899bee
2026-06-30 13:29:23 -04:00
Vencislav Atanasov
3ba63d667e libspeex: Fix compile warnings on Apple Clang 21
- unused function parameters
- signed/unsigned comparisons
- unused local variable

Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I64e9e2573174377465b10e5912d10ca2a22da0e1
2026-06-30 10:28:55 -04:00
Vencislav Atanasov
3d3df07c45 bspatch: Fix compile warnings on Apple Clang 21
- signed/unsigned comparisons
- unambiguous fclose() result code handling

Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I6c4184ddef39281610de01b5c6ab402450d9a3ec
2026-06-29 23:11:33 -04:00
Vencislav Atanasov
9e3b38c863 rbutilqt: Remove unused macOS includes from utils
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I603e327acbad48bb1dd2ff8be8a2953c7155f5b9
2026-06-29 21:18:23 -04:00
Vencislav Atanasov
379c056299 rbutilqt: Replace Utils::ejectDevice() on macOS with a diskutil process invocation
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Icedf758af6f1f0843c58e7ea5bb3efb2e7177b4a
2026-06-29 21:16:30 -04:00
Vencislav Atanasov
1039eb305a rbutilqt: Add error handling to TTSCarbon::generateSettings()
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Iad04028853e930b508e72c2c9c3e9ebd9504d4bb
2026-06-29 21:16:19 -04:00
Vencislav Atanasov
92d62cf6ac cmake: Make sure pip is upgraded before using it to install dmgbuild
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I4221aab7dd031bd79548a94b30ce5978d81e282b
2026-06-29 20:13:50 -04:00
Vencislav Atanasov
174a2330e9 rbutilqt/themeeditor: Fix compiler warnings
- match sign in integer comparison
- remove unused RBViewport member

Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I9a59d701593a4290523bf4b837ab0794bea2ebaa
2026-06-29 20:13:29 -04:00
Vencislav Atanasov
6aa8d80ba2 rbutilqt: Replace Utils::findRunningProcess() on macOS with a libproc implementation
GetNextProcess, GetProcessPID and GetProcessInformation are replaced by proc_listallpids() and proc_pidpath()

Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Ic4fe13c405e11b658b1a9540e49741d4e69069f3
2026-06-29 20:13:09 -04:00
Vencislav Atanasov
45bd7c4400 rbutilqt: Simplify Utils::filesystemName()
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Ib8851f27c473afa0d656ea3885e4d65342d10ab5
2026-06-29 20:12:48 -04:00
Vencislav Atanasov
204684f3e2 themeeditor: Fix class member initialization by calling the getter
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I5137c7c5094200809f79880bc425b0f31fee02cc
2026-06-29 20:12:32 -04:00
Vencislav Atanasov
05de3651d2 rbutilqt: Simplify conversion from UTF-16 string to QString for proxy host
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Idf3437f66c6ac95d38cad997143b995b2fe9a5f2
2026-06-29 17:41:25 -04:00
Vencislav Atanasov
cf2872af11 rbutilqt: Replace insecure sprintf() with snprintf()
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Ic2abe417f17a6f104cc4523b155ca6fdb5965bb1
2026-06-29 17:41:06 -04:00
Vencislav Atanasov
e3e416c51b rbutilqt/themeeditor: Fix Qt6 deprecations
- insertMulti() -> insert()
- QString::fromUtf16() with a parameter type other than char16_t*
- enterEvent() parameter type changed from QEvent to QEnterEvent
- QVariant -> QMetaType

Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Ia9c6c93e281475856e8355a8aa0e64c474eed80c
2026-06-29 17:28:53 -04:00
Vencislav Atanasov
d618846a8f ipodpatcher: Remove unused functions
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Iedb2d42612d543e7761dd1c2628310cd053652e3
2026-06-29 16:56:16 -04:00
Vencislav Atanasov
dcc997e4e4 rbutilqt: Switch to a Qt API to get macOS version number, get system architecture using a compiler macro
This removes usage of the deprecated macOS Gestalt() API (2/2)

Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Id10386285469c06f082a7dcdcc3284b97519b10a
2026-06-29 16:55:47 -04:00
Vencislav Atanasov
1cbf61607e rbutilqt: Switch to a Qt API to get the CPU cores count
This removes usage of the deprecated macOS Gestalt() API (1/2)

Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: Ia3af510412a97258dcd9fc9134708900c04c62c4
2026-06-29 16:54:27 -04:00
Vencislav Atanasov
cac0be6af5 rbutilqt: Replace deprecated macro Q_OS_MACX with Q_OS_MACOS
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I0c51044574b8ec96ceaf0b953c6735ccf5d19e5e
2026-06-29 16:53:48 -04:00
Vencislav Atanasov
e0ac7a75a3 macOS 12.0 Deprecation: kIOMasterPortDefault -> kIOMainPortDefault
Co-authored-by: ChatGPT (GPT-5.3 Mini) <chatgpt@openai.com>
Change-Id: I4b5d6b73b87b7ea9e79ed20bbd27fb88fc8647ab
2026-06-29 16:53:21 -04:00
William Wilgus
b99b2e98df [Bugfix] lua FS#13940 - FONT_UI using last selected font instead of the UI font
FONT_UI is a placeholder when it gets assigned it isn't resolved
immediately

when its time to resolve the font it is processed with font_get(int font)
first it sets it to the last slot
and then decrements till it gets a valid font

Change-Id: I3c203d58ed2d813d206f5b435e6b55ed196cf213
2026-06-29 01:06:34 -04:00
William Wilgus
d9b1819e0b FS#13942 - Lua strftime os.date("%C")
Change-Id: I5a4cb8d362a69d12c2d7e5013dcf179cc20d01b3
2026-06-28 14:32:33 -04:00
William Wilgus
24b0254d96 metadata.c small cleanup
add get_metadata_afmt function so we don't have to extra functions
remove unneeded bounds check on audio_format in rbcodec_format_is_atomic()
add bounds check on audio_format in get_metadata_afmt()

Change-Id: I76bd869100b000579c6546f0670ba4ba2c541f22
2026-06-28 14:24:02 -04:00
William Wilgus
3cd286d8f8 metadata add audio_fmt to get_metadata_ex
tagcache.c add_tagcache() and potentially
skin_tokens.c wps_playlist_percent_prepare()

make calls to probe_file_format() prior to calling get_metadata_ex
resulting in some small amout of duplicated work
especially in the case of add_tagcache this can add
up to a lot of duplicated work

breaks out audio_fmt so these can supply the afmt other callers just
supply probe_file_format(trackname) in the function call

Change-Id: I8084213b8ee7e04d76dce0986beb83d443ac804b
2026-06-27 14:14:01 -04:00
William Wilgus
3e08b86e4b FixRed a824085 skin: add %pX tag checkwps, ATA builds
ata_disk_isssd() return 0 for SIMULATOR

Change-Id: If281b5ce7a98f338dfd81635c8936dd90c41b9bb
2026-06-27 13:27:35 -04:00
Adam N. Burke
a824085057 skin: add %pX tag for time-based playlist progress
%pP reports playlist progress by position index, which treats every
track as equally long. For playlists with tracks of unequal length --
audiobooks with chapters anywhere from two minutes to an hour are the
motivating case -- position is a poor proxy for listening progress.

%pX reports the played percentage of the whole playlist by time: the
summed length of all preceding tracks plus the elapsed time in the
current one, relative to the playlist's total duration. It can be
used as a value, in a conditional, with %if(), or as a bar tag like
%pb.

If a playlist contains more than 500 tracks or the scan is taking too
long and the user aborts the tag will fallback to the behavior of %pP
except the progress through the current track will be included in the
returned percentage

--------------------------------------
Computing this needs every track's length, and reading metadata for
every track is too slow and disk-heavy for a tag that refreshes on the
WPS. Instead each track's length is estimated from its file size: the
skin engine scans the playlist in the background, a batch of files each
skin refresh, opening each file only to read its size (directory
metadata, no header parse). Size is turned into time by calibrating one
file of each type -- the first file of each extension is parsed once
with get_metadata to learn its bytes-per-second, and every later file
of that type reuses it. A single-format playlist, the usual audiobook
case, parses exactly one file and stat's the rest.

The result is an estimate -- bitrate varies within a type, especially
for VBR -- but it is cheap and accurate enough for a progress
indicator, and the playing track always contributes its exact elapsed
time. Per-track lengths are stored as two bytes of minutes each in a
movable buffer sized to the track count and allocated only while the
tag is in use; the cache is keyed on the track count and a crc of the
first, middle and last filenames, so a playlist swap or reshuffle is
caught. If the buffer cannot be allocated (a very large playlist on a
low-memory target) the tag falls back to position-based progress.

The buffer is allocated when playback starts (and when the now-playing
screen is opened with playback already active) rather than lazily on the
first WPS refresh, so the one-time allocation happens at a playback
boundary instead of during steady-state playback; it falls back to
allocating on first use if that point is missed.

Until the scan finishes the tag does not blank: it returns an instant
equal-weight estimate -- (completed tracks + fraction through the
current one) / track count -- which sharpens into the size-based value
as the scan fills in. So a theme can just use %pX and it is correct
from the first frame, and %?pX is true whenever a playlist is loaded.

Tested on a Sansa Clip Zip and in the simulator. On a 216-track,
~745 MB single-format audiobook playlist the length scan dropped from
~4150 ms (get_metadata on every track) to ~174 ms (one parse plus 215
file-size stats), roughly 24x lighter.

Change-Id: I6e572e78a10444bd513ddc77e30da04aa5153ef2
2026-06-27 12:29:31 -04:00
Solomon Peachy
02f7dabc67 rbutil: Port TTS preview to QT6
Change-Id: Ib4a5b1ef1cd3927792e0022e387b6abc8e5f099e
2026-06-27 11:42:50 -04:00
Solomon Peachy
5462f203d3 bidi: Expand+Correct the list of RTL codepoints in is_rtl_char()
Was missing:

 * Arabic Supplement
 * Arabic Extended B
 * Arabic Extended A
 * Rumi Numerals
 * Arabic Extended C
 * Indic Isqaq Numerals
 * Ottoman Siyaq Numerals
 * Arabic Mathematical Alphabet Symbols

Worth noting that most of these are vanishingly unlikely to ever show up
in the context of Rockbox.  (The exceptions are "Arabic Supplement" and
possibly the Mathematical Symbols)

Also corrected "Arabic Presentation" into two distint blocks, as
the characters between them (fe00-fe6f) are NOT indicative of RTL.

Change-Id: I0c5c547921c789d32425682c8c75edb21428f549
2026-06-27 10:20:03 -04:00
elishay
0e3355de50 keyboard: fix RTL (Hebrew/Arabic) on-screen keyboard
Commit d1be73c ("keyboard.c Use viewports, move text box pos")
moved the picker and edit line into dedicated viewports. Under an
RTL UI language these viewports get VP_FLAG_ALIGN_RIGHT, so
lcd_putsxy mirrors every call; with the per-character cell drawing
this reversed the picker grid and the edit line (Hebrew shown
reversed, Latin filenames backwards, wrong caret).

- Clear the alignment flag on the keyboard own viewports so the
  picker grid and cell layout are no longer mirrored.
- Draw the edit line as a single string so the bidi engine reorders
  mixed Hebrew/Latin correctly, and use the full line width.
- Compute the caret from the bidi (LTR-base) visual layout so it
  lands at the insertion point, including mixed Hebrew+Latin text.
- Pick the edit-line direction and invert the left/right cursor
  keys based on the text first strong character.

Change-Id: I79f1c444bc9121fd5018ad5f6f4148afe2c1a3e1
2026-06-27 07:45:12 -04:00
Solomon Peachy
0db37606b0 rbutilqt: Handle translation load failures, part deux
This set happens on startup, when we try to load a translation
matching the system locale

Change-Id: Ib1d3effa7aa738550841023a14f733d8d5b48837
2026-06-27 07:35:21 -04:00
Solomon Peachy
4875f706c2 rbutil: Cleanly handle translation loading errors at runtime
Change-Id: I2d8c566437b9a6224db41608bf3cbab8aed76763
2026-06-27 07:29:21 -04:00
Solomon Peachy
a700dcdfb0 rbutil: Use add_compile_definitions instead of add_compile_options
Change-Id: Iaeca86f89ccfb961456a10b96f3257d444cc0971
2026-06-27 07:29:21 -04:00
Solomon Peachy
44713c3014 themeeditor: Fix a pile of unusued argument warnings
Change-Id: I919c239a410e0ff708276d5ca9d1046b70af536b
2026-06-27 07:29:21 -04:00
Solomon Peachy
5d3723bbf4 rbutil: Use QT_NO_USE_NODISCARD_FILE_OPEN everywhere
Not sure why we needed to specify this in three different places, but eh

Change-Id: If8d7304971f176bcfca839f5d6da626908621be4
2026-06-26 21:38:57 -04:00
Solomon Peachy
3c41d6a1c1 rbutil: Eliminate more pre-QT6 workarounds
Change-Id: I7b5cf428ef626543aa8e932622f4658e789e9236
2026-06-26 21:38:57 -04:00
Solomon Peachy
202243a1ab tools: fix up build warnings
Change-Id: Ib1b11f2361d4a20a8cd3c4107f8e546f8ece3f49
2026-06-26 21:38:57 -04:00
Vencislav Atanasov
115b2ae800 rbutilqt: Add a CODESIGN_IDENTITY CMake variable for macOS builds
It can be used to choose which Apple Developer ID to use when signing the build of the Qt apps. By default, it uses ad-hoc signing, i.e. no Apple Developer ID is needed.

Change-Id: I5634e318f4949107eb954b729b2f8f1d60fad115
2026-06-27 02:31:11 +03:00
Solomon Peachy
e0bbf8f9da rbutil: Drop support for QT5, start cleaning up the warnings
* All deprecation warnings fixed
 * Explicitly set QT_NO_USE_NODISCARD_FILE_OPEN

Change-Id: Ice52133e93d4a01f12ff845a3056a81b100ed891
2026-06-26 16:53:17 -04:00
William Wilgus
22b4cd3232 metadata.c get_metadata_ex add flag METADATA_EXCLUDE_NORMALIZE
no need to normalize data you don't intend to use

Change-Id: Ieef5474fef47b2f96db3d02875db95a1de02eb5e
2026-06-25 13:43:20 -04:00
Solomon Peachy
949a99a24d rbutil: Support linux non-x86_64 appimage deployments
Change-Id: I6d95e45b3a013941e131ee89b50c7225b21931bf
2026-06-23 20:16:56 -04:00
Solomon Peachy
9a85d01a32 FS#13933 - Updated Romanian and Moldavian translations (Mihai Alexandru Vasiliu)
Change-Id: Ia2aad85d518f4037b39565036940622aac52812b
2026-06-23 17:31:04 -04:00
Solomon Peachy
30567451b1 mkimxboot: Fix up a large pile of compile warnings with -Wextra
Change-Id: Ida1eae89e4a2cc99e8e2ed734c4d669c1a2a8cb2
2026-06-22 20:59:18 -04:00
Solomon Peachy
b6db69e7ef build: Move utf8proc build decision into configure script.
It is always enabled, except in the following situations:

 * bootloaders
 * warble or checkwps applications
 * devices with less than 4MB of RAM
 * imx233-based devices

imx233 is a special case; that will be backed out we figure out why
it fails to boot if the binary size exceeds 1MB.

Change-Id: If4a89e389f562bb5791a565fba99c830213473d3
2026-06-22 17:31:15 -04:00
Solomon Peachy
aeb42039f9 rbutil: Explicitly use C++17 and C11 for building (was "compiler default")
Change-Id: I9757a77520fc9d7d39a52185b92615d5eb9c0cbc
2026-06-22 10:27:38 -04:00
Solomon Peachy
cf10fa5243 FS#13929 - Updated Latvian translation (Renalds Belaks)
Change-Id: Id5fd597b16be8e93823d89129256fcb0dfd3e36b
2026-06-21 17:22:29 -04:00
Solomon Peachy
13bcd68346 FS#13928 - Updated Simplified Chinese Translations (Wang Ji)
Change-Id: Ibf63047e9ade0397a29599d127ff77c51a167113
2026-06-21 11:43:49 -04:00
Solomon Peachy
f42d95b4a6 rbutil: Update vendored quazip from v1.3 to v1.5
Change-Id: Ife2678a7ef1f48020a3cc3b75dc87f725dd14068
2026-06-21 11:20:55 -04:00
Solomon Peachy
1e3301388c rbutil: Update vendored quazip from v1.1 to v1.3
Change-Id: Icd6f010adbc9712f381a409eca31506fe31bb304
2026-06-21 08:55:26 -04:00
Solomon Peachy
18237a3c1f rbutil: Refresh all translations using lupdate-qt6
Change-Id: Ie355d1a5422ab28e5e195b67ee5591bc973a1210
2026-06-20 19:48:33 -04:00
Solomon Peachy
278a5a9bc2 rbutil: Refresh all translations using lupdate-qt6
Change-Id: Ie355d1a5422ab28e5e195b67ee5591bc973a1210
2026-06-20 19:36:27 -04:00
Solomon Peachy
1d33585686 FS#13927 - Updated Simplified Chinese Rockbox Utility translation (Wang Ji)
Change-Id: I82af403ec32b7c0021b65cc8dce89bb4578f773c
2026-06-20 19:32:50 -04:00
Vencislav Atanasov
2dc466229e rbutilqt: change the macdeployqt command line
- Remove libpath as the dirs are already in the search path. It doesn't help with QtPdf, QtVirtualKeyboardQml or QtVirtualKeyboard not being found (at least on my system). The native libraries are properly found and copied to the app bundle.
- Remove "|| true" at the end, as even though macdeployqt shows a bunch of "ERROR: " messages, it still exits with code 0

Note: This is a partial revert of bf273149. codesign is still required, the binary is killed with SIGKILL by the OS if the libraries are modified but the signature is not updated.
Change-Id: I2d7d4e32ed8043f302c163db4f89fc90cc921f88
2026-06-20 14:00:59 -04:00
Vencislav Atanasov
005826b630 rbutilqt: Clarify if a setting comes from rbutil.ini or build-info
Also implement a fast path for QVariant PlayerBuildInfo::value(BuildInfo item)

Change-Id: Ice4e2dfbf9d7e3ba2e0f6692c320d50e3918b0d4
2026-06-20 12:57:11 -04:00
William Wilgus
ad64336e69 [Bugfix] Autoscan when radio off hangs player, record static
Clipzip, ClipPlus other devices may be similar
Autoscan from the main menu and the device hangs at scanning 88.1

try to record with no station set and it just records static

Change-Id: I59fe17dde80736e4fae8445c0aea7fcf5e476317
2026-06-20 11:43:02 -04:00
William Wilgus
81962808a2 use core_alloc for Radio Presets
saves around 1.2k off the top &
allocates a movable alloc when FM radio used

Change-Id: I0ea8c646f919fc8e62de2b02c1c089620e7ef020
2026-06-20 11:23:55 -04:00
Solomon Peachy
39e7f3f29d rbutil: Move all URLs other than build-info out of rbutil.ini
Now there is zero overlap between what can be found in rbutil.ini
and the downloadable build-info.

Change-Id: Iba84dec39b062f69098bea62a286acfd36479226
2026-06-20 10:07:53 -04:00
Solomon Peachy
fba3021ffd rbutil: add Ingenic jz4740, jz4760, and x1000 recovery modes to the blacklist
Change-Id: I661c8cd005c95bbb00a9a693859a3852dc445f29
2026-06-20 10:07:53 -04:00
Vencislav Atanasov
bf273149b7 Fix CMake build of RockboxUtility and RockboxThemeEditor on macOS (part 2)
Add search path for the Qt libraries, ignore the signature verification error and then re-sign again.

Co-authored-by: Qwen3.7-Plus
Change-Id: Ifa6232cd56e78e593b3395384dd2a98fa9cc67e5
2026-06-19 21:03:17 -04:00
Vencislav Atanasov
2e126ee3ba Fix CMake build of RockboxUtility and RockboxThemeEditor on macOS (part 1)
Create a new target dmgbuild_venv which is added as a dependency of both RockboxUtility and RockboxThemeEditor so CMake understands that it's a shared dependency.

Co-authored-by: Qwen3.7-Plus
Change-Id: I417de25356885574546a7ae2a53ddbd44f6be557
2026-06-19 21:02:52 -04:00
Vencislav Atanasov
53d2a99a2a Hack to fix ipodpatcher on macOS - ignore exit code from unmount
ipodpatcher tries to unmount volumes that are not mounted e.g. the firmware partition, before making any changes. On macOS this fails with a non-zero exit code, causing the whole process (bootloader installation or uninstallation) to fail.

A proper fix would be to trace every path that uses ipod_reopen_rw(), and only call unmount if we expect the volume to be currently mounted.

Change-Id: Ieaa58da336216d5060465cfc2b7f5f8c729fe8b9
2026-06-19 21:02:37 -04:00
Solomon Peachy
a269a1360a rbutilqt: Add a bunch of missing player icons
Change-Id: I4126fd35e69b58e93e5fb63c70292c592e05ebe5
2026-06-19 20:55:52 -04:00
Solomon Peachy
f2f92dd8e1 rbutil: Update erosq/k hw4 version listing
Change-Id: I7a692a5dabb887cf7aefd98819b0b3a04be4dace
2026-06-19 17:01:07 -04:00
Solomon Peachy
3de8814fb8 Fix build of rbutil
Regression introduced in db0d7649e0

Change-Id: I395dc1d5046f3cf93dade08d2bb781c1afbef632
2026-06-19 16:50:57 -04:00
Christian Soffke
cd699e5448 configure: darwin: update GCC, use SDL threads
The simulator on macOS has been broken since macOS 26.4
was introduced. On macOS 26.4, 26.5, and the 27 beta,
thread setup fails in make_context (firmware/asm/thread-
unix.c), because sigaltstack returns an "Operation not
permitted" error. Fall back to SDL threads until this
can be fixed.

Also update GCC to keep it in sync with the latest
Homebrew formula
(https://formulae.brew.sh/formula/gcc).

Change-Id: Ib08ac81ede00c577f28a85c7886f716e7504bbe9
2026-06-19 21:40:11 +02:00
William Wilgus
7a32c8b5e3 [Bugfix] lua splash_scroller line formatting
I accidentally added an extra character wittthe last patch by changing
< to <= in the process of testing this I realized spaces were sometimes
being included at the beginning of the line and also that sometime
sentences were being cut short even though they fit on the screen

Change-Id: Iee0ed64e18defad2acb3c107d334ea2a49bd5b6f
2026-06-18 22:21:16 -04:00
Solomon Peachy
c0027abd0e misc: Update gitignore to cover a bunch of utils/* binaries
Change-Id: If78f82aa09f7b4008f44d9c3101438968b9bd69d
2026-06-17 13:56:29 -04:00
Solomon Peachy
5a838851ed utils: More warning fixes
Change-Id: Ie7af33ab0e3ac43f93a4cf2df50ddac10243b9f7
2026-06-17 13:56:29 -04:00
William Wilgus
ca2edad012 [Bugfix] FS#13926 -lua Crash when displaying error splash
fix lua strpbrk function skipping the first accept chr

lua splash_scroller fix NULL pointer in brk due to lastbreak
not being reset on a new line

Change-Id: Ica0c9ee5f9194f5be54ab90ad16309adead1c207
2026-06-17 13:55:43 -04:00
mojyack
7154fcd9a8 usb: iap: workaround cur/set freq mismatch
Change-Id: I75a36c9dfd33e7f9192101220633137e5ad98411
2026-06-17 11:01:34 -04:00
Solomon Peachy
0fc352da0f utils: Fix a small pile of warnings
Change-Id: Idf95fc0a6ce94ebb2282bc3b017bc7ba8aeb42fc
2026-06-17 10:39:57 -04:00
Solomon Peachy
3403e3cfb9 imxtools: Fix several build warnings
Change-Id: Idebf0445d3e861ff27e152730c5bed64c2e4489b
2026-06-17 10:39:57 -04:00
Solomon Peachy
db0d7649e0 ipodpatcher: Fix build warning and 'make clean'
Change-Id: I9e546b0e4e0bcc30efccfca334281398e358ae8d
2026-06-17 10:39:57 -04:00
William Wilgus
d737cbb931 Sansa As3525 OS stacks debug menu change scroll buttons
the other items that scroll use the menu button and reset on STD_OK

OS stacks use STD_OK to scroll and any other button to reset

Change-Id: I1fa1caa322fe761c6f92d2d08cc418e78843863b
2026-06-17 10:26:22 -04:00
Le Khanh Binh
d00a53a1f0 iap: Fix dead remote at boot & ghost clicks on held buttons
Fix FS#13832
If the remote is already plugged in when Rockbox boots, it stays dead
until you replug it. These remotes only send their identify packet
once at power-up, so we never see it and then throw away all button
events because lingo 0x02 was never negotiated. The OF doesn't care,
so accept ContextButtonStatus from unidentified devices too. Stray
bytes received before iap_setup() also made iap_getc() return false,
which the serial driver takes as "sync found" and locks autobaud onto
the wrong bitrate.

The ghost clicks come from the repeatbtn handshake. A held button
resends its down event every 30-100ms and each one re-armed
iap_repeatbtn, which stalls handling of the following packet. So
during a long press packets pile up, the event queue overflows, and
the leftovers replay as keypresses after you let go. Skipping fires
on button release which is why next/prev showed it the worst. Now
repeatbtn is only re-armed when the button state actually changes,
and iap_handlepkt() drains whatever complete packets are in the RX
buffer rather than relying on one queued event per packet.

While at it, fix two more things found along the way: the button
state is now written in one go (the temporary BUTTON_NONE could be
picked up by the button tick mid-update), and iap_rxlen is
decremented when a frame is received so the overflow check actually
does something.

Tested on ipodmini2g with an A1018 remote.

Change-Id: Ie18512e47d642fe6957fc010eaf79b6d2af4c070
2026-06-16 21:36:02 +07:00
William Wilgus
c3ad489738 [BugFix] Sandisk ClipZip Display Type 0 has no partial X updates
Type 0 displays had to update the whole x line due to anything other
than a full line causing corruption and tearing

I figured out that flipping x and x_end
(LCD_W - x and LCD_W - x_end)
makes it work properly

Lowered the refresh rate to 95 Hz
Removed Fade in on screen enable

Change-Id: I0b8f76ad01ce7e48bd0a56aa321c30c30f91ce8d
2026-06-16 00:38:43 -04:00
William Wilgus
32b8af9840 [BugFix] ClipZip Type1 Display init gamma correction
Now that we have a datasheet for the type 1 display controller
it turns out the gamma correction was not being applied
the screen looks much better with it actually applied

also lowers display refresh from 120 HZ to 90 Hz and applied a mentioned
sleep mode (0x14) to save some power

Adds comments for the LCD commands ala type 0

Change-Id: I2d72df4d24b8bf9f3627bdb96ec9ce43ddd8b10a
2026-06-15 00:12:26 -04:00
Adam N. Burke
383e227671 Sansa Clip Zip: Implement LCD flip (180 degree rotation)
Enable HAVE_LCD_FLIP for the Clip Zip and implement lcd_set_flip()
in the LCD driver, making the Display -> Flip Display setting work.
This lets the player be used upside down, e.g. clipped to clothing
with the control buttons pointing up and screen on the bottom.

Defining HAVE_LCD_FLIP also activates the existing button remap in
button_flip() (firmware/drivers/button.c) for this target: while the
display is flipped, LEFT/RIGHT, UP/DOWN and the volume keys are all
swapped to match the new orientation, so the whole device is usable
upside down, not just readable.

The flip is done in hardware by reversing the controller's GRAM write
direction and mirroring the write window in lcd_setup_rect, so partial
updates keep working and there is no per-frame cost. Both panel
variants are handled: the type 0 WiseChip/SEPS114A via MEMORY_WRITE/READ
(1Dh, 0x02), and the type 1 Visionox/LD7134 via the Graphic RAM Writing
Direction register (05h, 0x03). The direction register is written in
lcd_enable(), so it is set while the panel is powered and is re-applied
after display standby; lcd_set_flip() cycles the panel off and on so a
change to the setting takes effect immediately.

For the simulator, which has no real LCD controller, lcd_set_flip() is
implemented in the SDL LCD driver (lcd-bitmap.c) as a software mirror of
the framebuffer, so the flip is visible in theme previews; the generic
uisimulator stub is guarded out when HAVE_LCD_FLIP is defined.

Tested on real type 1 / LD7134 hardware in both orientations: display
content, button remapping and album art are all correct, and test_fps
shows partial updates run at full speed when flipped (1/4 frame 325 fps,
matching the non-flipped rate). The type 0 / SEPS114A path uses the same
approach; the 0x02 direction value was confirmed to flip a type 0 panel
by William Wilgus during review.

Change-Id: I99ef13949102b344826e72d1d90c71e2271448a6
2026-06-14 23:16:17 -04:00
William Wilgus
58ce77fbe2 [BugFix] tagtree voiced Letter menus with talkmenu off
Change-Id: I671f795061a63bcf5db3c94728e98dd7506329a7
2026-06-14 16:50:54 -04:00
William Wilgus
f07e977d7c Sansa ClipZip add Display type to debug update comment on LCD controller
display display type 0 / 1 in debug menu

update the comment on type 1 lcd I believe it to be a LDT LD7134 controller
the commands match up down to the gamma correction tables

Change-Id: Ic5d1d8db994a022a61db4a83a9f476cfafbcf51b
2026-06-13 12:56:55 -04:00
William Wilgus
4d773a3329 onplay wps context menu plugin item rework namebuf
only load the namebuf once unless user changes the plugin
also displays the plugin name when user selects the whole context menu

Change-Id: I32b53729a3dcc2bf2c42393876407df7f3d38d8c
2026-06-11 09:52:09 -04:00
Solomon Peachy
f1bdf1e3c2 fix yellow from 59a42fbf61
Change-Id: Id696c20639cdcc987c228c9faec5a1ff8744797d
2026-06-10 11:28:04 -04:00
Solomon Peachy
59a42fbf61 pcm: Pull pcm_is_ready back out of the sink structure
It is referenced by multiple threads, and as such needs to be both
volatile and SHAREDBSS to keep everyone happy.

...should address hangs on startup observed on nano2g and mini2g when
voiced menus are enabled

Regression introduced in dfa33c2 and made far worse by 759ef27

Change-Id: I202ec6c0d5825ff3a319b7d95d600b4ce06dd685
2026-06-10 09:21:21 -04:00
William Wilgus
0a1858b9d1 [BugFix] prevent infinite loop to return to wps from plugins
if there is nothing to resume then it will return to the plugin endlessly
hanging the device

Change-Id: I7d6a0c7ec5a9e049cf62f88542bedaa1081556ac
2026-06-10 01:26:51 -04:00
William Wilgus
fee00f1f3c [BugFix] pcm-s5l8700 ipod nano 2g audio init hang
pcm_dma_set_freq expects the frequency index not the actual frequency

bug introduced in Commit dfa33c2 pcm: introduce pcm_sink

Change-Id: Idc521cfe1da22b112a16f81611dac720837eeea9
2026-06-10 00:47:56 -04:00
Roman Artiukhin
c5c39a3fdb pcm_mixer: fix auto frequency switch stopping playback on some targets
Regression from cb04b816. Restores sound by re‑adding
pcm_play_stop, previously invoked in mixer_reset.

Known affected targets: x1600 hosted hiby port (Hiby R1, Hiby R3 Pro II)
Discussion: https://forums.rockbox.org/index.php/topic,55125.msg258435.html#msg258435

Change-Id: I5fadac0b47f609e38baad5c7151354ee8f7e9871
2026-06-09 12:51:53 +03:00
William Wilgus
513365713a [FixRed] sonybootloader has a glyphcache but no open_pathfmt
Change-Id: Iaf8522d4a72f78da26434b60757fe3421a3622f2
2026-06-09 02:01:29 -04:00
William Wilgus
a81d3fa10e [Bugfix] open_plugins.rock add 'add' item regardless & voice improvements
also fixes a bug where synclist viewport could be empty if the list isn't
initialized

voices path and parameters now

adds the item [Add] as the last item in the list

Change-Id: I1aad62baf3c19a67d04fa1fb3db8a7573e0a467f
2026-06-09 00:39:31 -04:00
William Wilgus
dfe965d81e font.c glyph_cache_load() reduce stack
open the glyph cache in a separate function so we can
get the MAX_PATH alloc off the stack quickly and
deal with the fd instead

Change-Id: I0e991a1286b29c781e3f03b6a49e100c70809920
2026-06-08 22:31:20 -04:00
William Wilgus
e5c7f0c41c open_plugins.rock add title to main menu, add scroll stop on close
Have a report of a hanging scrolling item, ensure the lists are stopped
on exit with gui_synclist_scroll_stop()

Change-Id: If670806f710118c79377bf8c5de6c1a5168e37fc
2026-06-08 12:03:05 -04:00
Aidan MacDonald
722e4f10ad Cleanup some unnecessary HAVE_HOTSWAP uses
Always define storage_removable() and storage_present() so
that ifdefs are unnecessary. They were already defined as
constant for the CONFIG_STORAGE_MULTI case, but not in the
case of a single storage type.

Change-Id: I13073b3a72b201b5b11167deb050e6f27139c61c
2026-06-08 10:32:49 -04:00
William Wilgus
9b0516e4e1 [BugFix] openplugins.rock 0 is a valid file descriptor
Change-Id: Id7d9c2c4b9d13433c8aa2260b20f5d74e4b3add8
2026-06-07 11:19:08 -04:00
Christian Soffke
1add6b0dd5 shortcuts: eliminate unnecessary nesting
Reduces GNU Complexity scores for:

* shortcut_menu_speak_item: 66 -> 10
* do_shortcut_menu: 39 -> 20
* readline_cb: 29 -> 16

Change-Id: Ic648a7eb1e51d4a116bc8af61f1ed1c617cee024
2026-06-06 19:18:17 -04:00
Christian Soffke
86decaab9e root_menu: Start Screen: don't try to resume finished playlist
Go to root menu when Start Screen has been set to "Resume Playback"
but playlist is finished

https://forums.rockbox.org/index.php?topic=55770

Change-Id: I6939fa313dd5fd6485628e22a2d860763492d5cf
2026-06-06 11:34:18 -04:00
Christian Soffke
292e8a17a2 keymap: erosq: fix keylock button handling
Only react to Power button release if previous
button code was Power button press, so that
screen doesn't lock when device may have just
been turned on

Change-Id: I1ba228103efedeeceaaa00c49b1b1da66b63bb75
2026-06-06 17:23:58 +02:00
Christian Soffke
f123dbc04a misc: shutdown: fix backdrop glitches
Clearing the display makes the backdrop come to the foreground.
which can look odd or glitchy, particularly for themes that do
custom drawing on the backdrop buffer (2c71aa9). It also causes
issues if the shutdown has to be canceled.

Instead, enable theme, then clear the UI vp.

Change-Id: Ia96d1e766a9b86ec133522f7cd259e8b88f64216
2026-06-05 20:20:06 -04:00
William Wilgus
2b96380641 [Feature] FS#13884 #2 allow merging imported native keymaps
allows you to import a file and merge native keymaps

pops a yes no prompt to erase existing

duplicates will be overwritten

Change-Id: I167c6fac65775754b2a9874185d14f65638db9d7
2026-06-05 12:08:53 -04:00
William Wilgus
7517674513 FS#13920 text_editor.c plugin do not terminate last line with \n
you can still add a \n by inserting a blank line

Change-Id: Ic3e69fce83ccc9c050857a03877545a7452ce8a2
2026-06-05 02:17:38 -04:00
Christian Soffke
74905f4796 skin_engine: settings_apply_skins: remove get_skin_filename
Has no effect anymore since commit d66592b

Change-Id: Ibefc834378518c7e73e9e9b2489b6c072499bbe8
2026-06-05 00:04:17 +02:00
Christian Soffke
0836ebbd45 shortcuts: fix 'File' shortcuts may fail when dir filter set
Only apply dir filter to 'Browse' shortcuts, so that,
when trying to run a file from Shortcuts that is hidden
due to current dir filter settings, you don't get a 'Failed
reading Unknown' message (LANG_READ_FAILED/LANG_UNKNOWN)
because the tree entry can't be found in ft_enter.

Change-Id: I4eaad2ec415c9bac352a409922848e4407dac993
2026-06-04 21:32:54 +02:00
William Wilgus
ad05e23b72 [Feature] FS#13884 allow merging imported text keymaps
allows you to import a file and merge text keymaps

pops a yes no prompt to erase existing

duplicates will be overwritten

Change-Id: I0f4425e765f0a2ff6b73b830bcaea1b3f31e83cb
2026-06-04 12:10:03 -04:00
William Wilgus
e80e1448f1 [bugfix] Remember position in plugin browser menu
make the struct static so we can keep using the same
browse context between invocations

Change-Id: Ia154a78935755e1decb6abe50291d49e4404fb95
2026-06-04 02:33:44 -04:00
Solomon Peachy
3152beee32 chore: Don't embed $Revision$ tags in auto-generated files
I was going to convert them to a git hash instead, but that would
break builds from tarballs.

Change-Id: I76213b8b65df2c6cfb73cba299a4975a22725f36
2026-06-03 08:31:05 -04:00
Christian Soffke
a39e4f2a06 skin_engine: get rid of skin_unload_all
The skin is not unloaded using skin_unload_all in
settings_apply_skins anymore since commit 0ca4b38.

usb_screen was last remaining user until commit a969e1f.

Change-Id: I65a41ed220165587a04e699a7f210c575c00a4eb
2026-06-02 19:49:13 +02:00
Vencislav Atanasov
4469b95ef2 Update the Bulgarian translation
Change-Id: I285c5d71054b8c245ad40bd7c7a6d76e9b45fd01
2026-06-02 01:07:00 +03:00
Solomon Peachy
addcc159c2 tools: Update mp3info perl module to final upstream version
1.20 -> 1.26

  https://github.com/dsully/perl-mp3-info/commits/master/Info.pm

Change-Id: I0d58f56265a463784f45673764b9fdc054887c2a
2026-06-01 16:08:00 -04:00
Solomon Peachy
d54b9e6f8d chore: Get rid of *all* vestigal CVS '$Id:$' tags
Change-Id: I35c13a9768c582e4851aa252dd3ea5c89f760c8c
2026-06-01 16:01:18 -04:00
William Wilgus
3b2555bd4d onplay wps context menus small cleanup
no functional changes just cleaning up some code / logic

Change-Id: Ic03918a70997cfb170a29175361e2df9a9d242d1
2026-06-01 10:47:07 -04:00
Roman Artiukhin
c052d11673 skin: touchscreen: fix rewind in long files
Fix a possible overflow in the elapsed time calculation.

Change-Id: I211777d8144f76889003239b9a49e4fc56184c8f
2026-06-01 04:26:06 -04:00
William Wilgus
a7754eee71 [Bugfix] FS#13912 - splash_scroller with cyrillic crashes
I think they mean corrupted not crashes as I couldn't repro that

splash_scroller stepped by individual chars and split multibyte
sequences leaving corrupted chars

now it uses the new font_measurestring() to get the max_w and chops
it at break chars instead

this required a bit of a logic change to the function but should be
as good with less complications

Change-Id: I692db8b4737f41aec08dbc122fb844028498326d
2026-05-31 19:05:51 -04:00
Solomon Peachy
1c84362f3e FS#13915 - Updated Italian Translation (Alessio Lenzi)
Change-Id: Icc52476aa680361ee912468d9e47d67ac8324bad
2026-05-31 13:03:49 -04:00
Christian Soffke
16900c7fee root_menu: fix skin glitch when rebuilding tagcache
Only clear the UI vp instead of the whole display

Change-Id: Iab39094184a6749df743af268a4d9923cb18a73a
2026-05-31 11:50:11 -04:00
Roman Artiukhin
892fbe8d8f action: touchscreen: fix stuck repeated state of last action
This fixes the repeat_mode being stuck on Repeat Shuffle on the Hiby R1 WPS, and quick settings values being stuck at the last values for touch actions.

Regression from 9e254aca. The repeated state is used by the quick screen to detect repeated actions (see b918ec5) so I also removed "historical baggage" note.

Change-Id: Ic2a97058bbd17d232954ffe37f31a480ee11fe54
2026-05-31 13:20:39 +03:00
Solomon Peachy
d72a93836c nwztools: Update database generator script to work with python3
Change-Id: I662de90b57a3836755b88ff51537eb1597f226f4
2026-05-29 23:36:45 -04:00
Christian Soffke
3507f32d01 plugins: properties: further reduce stack pressure
Follow-up to 9f20c45.

tagtree.c's retrieve_entries has significant stack usage
(>1.5k) and is called from tagtree_entries_iterate.

Further Reduce stack usage of tagtree_entries_iterate,
going from 784 B to 72 B, by using static memory allocation
for the the tagcache_search struct in the Properties plugin.

Change-Id: I75a170bea1c5392c18a891844a0ff31fbd2114eb
2026-05-29 20:40:36 +02:00
Solomon Peachy
8af98332ab convttf: Add sanity checking to specified defaultchar
It now matches the logic in convbdf

Change-Id: Ic17fdd4dbed41fad4d3353b9dd314cd24a8ded58
2026-05-29 07:33:36 -04:00
Solomon Peachy
f17effbe8f gitignore: Add the utils/imxtools/sbtools binaries
Change-Id: Ie767ddb2a54898698f6cbb1d2ab9339ea03f89ab
2026-05-29 07:22:55 -04:00
Solomon Peachy
d1f1d1da5e button: Fix a set-but-unused variable without HAVE_SW_POWEROFF
So wrap the definition and setting of repeat_count with the
same #ifdef

Change-Id: I8c06ea68eca7e5db960e4fa08a866761e856293e
2026-05-28 22:35:51 -04:00
Solomon Peachy
8e5efb6850 convbdf: Make explicit when the "default" glyph is used
When a font doesn't have a glpyh for a given codepoint, the convertor
points it at the "default glyph".   The plan is to replace this pointer
with a canary value so that rockbox genuinely knows this glpyh
does not exist, allowing a fallback path to be implemented.

(The plan is for the fallback path to attempt to compose a glpyh from
 its decomposed codepoints, but this would make it be possible to
 implement a true fallback/subsitute font mechanism)

Change-Id: If6fea29f5393a6d4b9d5747c911a36fdc8dda5ae
2026-05-28 20:56:23 -04:00
Solomon Peachy
e1534d8065 convttf: Allow default glyph to be specified
Formerly fixed at the first glpyh in the converted font; now it can be
explicitly set.  This mirrors the functionality available from using the
DEFAULT_CHAR property of BDF fonts

Change-Id: Ibd754faff3fd4d393c4781e8faa685612e3301f0
2026-05-28 20:56:23 -04:00
Christian Soffke
35270d08e9 apps: bookmark: stop scrolling when leaving select screen
Missing from commit 6a25257, which only stopped scrolling
when you entered the context menu.

Change-Id: Id8a586103ea71a2b965a24f8797253eb248f1078
2026-05-28 20:13:10 -04:00
Christian Soffke
160905b1b8 gui: list: update skin in gui_synclist_set_title
Moving the skin update from gui_synclist_set_title to
gui_synclist_draw (c41beeb) had the inadvertent side
effect that, if gui_synclist_select_item was called in
between, it may have missed a configured skinlist that
only got enabled by the skin update. Which could lead
to a selection appearing off screen.

This was mainly an issue if you had popped an activity,
which resets the skinlist cfg to NULL, but didn't perform
a skin update before the call to gui_synclist_select_item.

Now that GUI_EVENT_ACTIONREDRAW can be used instead of
GUI_EVENT_ACTIONUPDATE to prevent the display from being
updated, we may as well update the skin immediately in
gui_synclist_set_title again.

Change-Id: Iaee98d670ffb8d7b6590bd2ba11827fef5fba5a8
2026-05-28 20:12:35 -04:00
Christian Soffke
9f20c45a5e plugins: properties: fix stack overflow in db
Stack overflow in splash_progress called from
tagtree_subentries_do_action with stack protector
enabled on mips

Change-Id: Ia71e0493e279af0531ae792d41442198555664f6
2026-05-28 19:58:21 -04:00
Christian Soffke
f0d3d76b26 gui: list: clear skinlist cfg when selected_size isn't 1
This disables custom scroll bars when initializing lists
that are currently always un-skinned, in scenarios where
there is neither a new activity to be pushed, nor is the
theme toggled.

Change-Id: I1bb05fc9be956c71e1adb70e764094082d9bb904
2026-05-29 01:39:42 +02:00
mojyack
fa67d29909 rbcodec: flac: cleanup around LOGF
Change-Id: I0c3798b8f09e1365712c6173bc5d587f9ea728a8
2026-05-28 17:28:07 +09:00
mojyack
543c8de861 rbcodec: enable logf only when LOGF_ENABLE is defined
currently logf() in codec are printed unconditionally when
ROCKBOX_HAS_LOGF, which is confusing.
Gate them behind LOGF_ENABLE to align with the main binary.

Change-Id: I4eb44604000acded55d0af8869145c4f3d77efcb
2026-05-28 17:28:07 +09:00
mojyack
abaac894f9 plugins: lastfm_scrobbler: fix build error with LOGF
Change-Id: Iefb4b7e4fefb366987627bfd32c27b3252ca34c8
2026-05-28 17:28:07 +09:00
mojyack
e62ac0d2c6 ovl_offset: use elf symbols instead of refmap
add a plugin_ram_end symbol to plugin.lds and rewrite ovl_offset.pl
to read plugin_ram_end and plugin_load_end_addr from the elf via nm.
this removes all dependence on the linker map file format, which
differs between gnu ld and lld.

Change-Id: I66e623d9a2b44eb84ae7035155c84d8afe46df23
2026-05-27 17:55:33 -04:00
Christian Soffke
018994e8c7 gui: skinned lists: fix off-screen selection
The skinlist cfg may not have been restored in time
after leaving the onplay tree menu, because the skin
isn't updated before gui_synclist_select_item is called.

This can result in the wrong number of visible lines
being calculated for the list, and a selection that
appears off-screen.

Regression introduced in commit dfd9c10, or later.
Due to the recent drawing changes, reverting the
changes to onplay.c doesn't re-introduce any visual
glitches.

Change-Id: I853bdfe6b6ba39e2eb281534ca302a0a828253b9
2026-05-27 22:03:46 +02:00
Christian Soffke
358c6056ef gui: skinned list: always set cfg to NULL when toggling theme
Takes care of disabling scroll bars when the current activity
doesn't change, but the theme is toggled. Applies to confirmation
prompts, for example.

Since we're updating the skin immediately afterwards, the cfg
will be reset as needed.

Change-Id: I8a62b6b4ad0abf5176ab6b3e39281021108cb59f
2026-05-27 19:10:23 +02:00
Solomon Peachy
6e64cb8043 gigabeat-s: fix red in 216b576c9
Change-Id: I388ac7bbc60d06beede5461f99e0612086d1bfc3
2026-05-27 09:00:39 -04:00
mojyack
6e31703289 fix incompatible pointer errors with clang
clang uses "unsigned int" for "uint32_t", which does not match gcc's
"unsigned long".
fix errors caused by this.

Change-Id: I05aaf23934167a56a6e400f49fcaf8b70bfaca13
2026-05-27 08:43:49 -04:00
Christian Soffke
0c464c3d49 gui: list-skinned: fix scrollbar not disappearing
In some scenarios, when leaving a skinned
list, the scroll bar remained visible.

Change-Id: I0aa08cc95b4cf315834f83f57c09ed3e0f43de70
2026-05-27 12:42:52 +02:00
Solomon Peachy
72af66bc8b FS#13910 - Updated German Translation (Karl Huber)
Change-Id: I0f6a6b7f758b929ed9c7e3127c548a036c381b1a
2026-05-26 19:10:51 -04:00
mojyack
e75e9d22fa bootloader: rk27xx: fix duplicate symbol error in enter_rkusb
since it's a static function, it may be inlined.
use local labels to fix duplicate-symbol errors.

Change-Id: Icba6e6876077e874ab5cfcdc3c774acb663356a1
2026-05-26 11:42:53 -04:00
mojyack
e6b62b0dbb unwarminder: safe_read.S: hide data_abort_handler for non-classic arms
"subs pc, lr, #4" is invalid on cortex-m

Change-Id: I3809691ee3a9e3864c592316216178d32ab278fc
2026-05-26 11:42:42 -04:00
mojyack
d75a5d5769 target: mips: mark .startup.spl section as "ax"
this fixes "has non-ABS relocation R_MIPS_26 against symbol 'spl_main'"
error when linked with lld.

Change-Id: I6b584d8fdcae3f509f322b8557249bc2870904a3
2026-05-26 11:42:25 -04:00
Solomon Peachy
9936d93fea Translation updates:
* Korean (Hoseok Seo)
 * Polish (Adam Rak)
 * Slovak (Matej Golian)
 * US English (Myself)

Change-Id: I1fe9b5bde585691d40288d933d286448c36421e4
2026-05-26 10:17:20 -04:00
Christian Soffke
2a29dedeb6 gui: skin_display: draw album art first
Some themes, such as Themify, FreshOS, iPod reFresh, Jive,
iPodOS, iPone, iClassic, AbsoluteBlack320, and possibly
others, draw a mask over the album art on the foreground
layer, in order to add rounded corners or to apply a fake
camera perspective (instead of taking advantage of the
backdrop layer).

This results in rendering glitches that can be fixed by
drawing the album art first.

Change-Id: Ie373c51304ab0d0a09b8663a8adff343a32ae5bb
2026-05-26 10:10:51 -04:00
Skye
0c8365a286 x1000: add basic UART implementation
Change-Id: Ic5a6d66b7280b924e6a106f07849a057c72d5c4c
2026-05-26 07:14:22 -04:00
mojyack
a019f19b1c rbcodec: libgme: fix byte-order detection for mips with clang
clang defines both of __LITTLE_ENDIAN__ and __mips__, causing
confusion in the byte order detection.

Change-Id: If95255974e9e3e5d0554410bbab65bc2af1bb1c7
2026-05-26 06:54:48 -04:00
William Wilgus
239ba599fd [Bugfix] FS#13908 hotkeys not saved when language is changed
Lang IDs get localized, if using them in a setting they should be
converted to english

adds lang_id_to_english() which walks the core builtins to return the lang id in english

Change-Id: Iced0d70be1318e512a8f3756e2bef1102dc511d8
2026-05-26 01:28:19 -04:00
William Wilgus
e471fe4115 [FixRed] Tree Hotkey on devices without HAVE_HOTKEY
Change-Id: I36f2fd8fc5edb2ac019a176cb9d3a3d014f1970d
2026-05-25 15:04:22 -04:00
William Wilgus
21e9d3f449 Hotkey Tree share code with WPS Context / Hotkey Wps
Change-Id: I0d81601bdb8279e845a874486ac4c1516b9d7dfc
2026-05-25 14:50:33 -04:00
Solomon Peachy
ff3155be9a lcd: Fix possible unset-before-use variable in 4bit alpha blending
Change-Id: I39e779e9452239b00731f31f55225cd979afe911
2026-05-25 13:05:49 -04:00
Solomon Peachy
c2344070ac xworld: Fix set-but-unused variable warning with GCC16
Change-Id: I5e20a32d84ebc7ca56278988b8add9ee644138ba
2026-05-25 13:00:30 -04:00
William Wilgus
bf0fa29a30 WPS Context Menu configurable entry
Allow setting context menu items

reuses WPS hotkey items

Runs the item
displays the item

Open plugin shows the item name

Pitch shows the pitch speed amount

add 'Show In Files' hotkey item

devices without a hotkey get an extra item

added Manual entries

Change-Id: I427e70e1cad15364ac5d2a7114032e97cc9eee1a
2026-05-25 11:07:59 -04:00
Solomon Peachy
9a142ee02d checkwps: Fix warning uncovered with GCC16
/home/rbbuild/rockbox/tools/checkwps/checkwps.c: In function 'main':
/home/rbbuild/rockbox/tools/checkwps/checkwps.c:329:21: warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
329 | char *ext = strrchr(name, '.');
| ^~~~~~~

Change-Id: I0c62600f269456cb81d0e3eaf77839c9103f2e41
2026-05-25 09:10:08 -04:00
mojyack
44e8d8226a configure: switch from -std=gnu99 to -std=gnu11
which is required for u"" unicode string literals used in the USB stack.
gcc allows this even in gnu99, but clang does not.

Change-Id: I1700fe503f20f31ba4704f8bef1ccca45f822620
2026-05-25 08:47:51 -04:00
mojyack
2291aa24f2 usb: refactor control request handling
this commit is a combination of the following changes, which
significantly refactors usb core and class drivers.

1. unify usb buffers of each class driver to reduce iram usage
currently, many class drivers allocate their own buffer to receive
control out data, which is a waste of iram.
share one common buffer for that usage to address the issue.

2. simplify control request handling by implicitly receiving write
   request data packets
change 1 above fixed the data destination. therefore, having the core
receive the data allows us to reduce the class driver's work and
simplifies the api.

3. enhance usb core's control request handling and unify the legacy
   driver api
in order to implement change 2, both the legacy and new driver apis
should be supported. so that, using the designware driver as a
reference, the new driver api functionality is move into usb core.
this simplifies the usb device drivers by requiring them to implement
only the functionalities equivalent to the legacy api.

tested with ipodvideo(arc) and erosqnative(designware)

Change-Id: I3627daa90278751f599e2108ec150ec3f8f6c524
2026-05-25 12:42:36 +01:00
mojyack
64b1f09e06 usb: designware: cleanup irq handler
Change-Id: Ic1926a8277d32721e3c736472dfc41a57ba0d433
2026-05-25 07:38:37 -04:00
Christian Soffke
edecad823e gui: list-skinned: fix scrollbar lag
The skin engine is responsible for drawing custom
scroll bars, but isn't kept in sync with list redraws.

Change-Id: Ieb457a4eb8442d4521c67a46a94c4d2132814c64
2026-05-25 07:33:57 -04:00
Christian Soffke
c0a8303a9c gui: simplify screen updates
Eliminate the somewhat circuitous skin_defer_rendering
and skin_render_deferred functions introduced in commit
c145d19e85.

skin_render (and thus skin_update and sb_skin_update),
along with skinlist_draw, list_draw (and thus
gui_synclist_draw), and quickscreen_draw, will never
update the screen anymore. Instead, the skin is only
marked as dirty now.

GUI_EVENT_ACTIONUPDATE redraws the skin as necessary,
and updates the screen afterwards, if the skin is dirty.
This event is sent from get_action, just like before.

A new event, GUI_EVENT_ACTIONREDRAW allows you to redraw
the skin without causing an immediate update at the same
time.

Change-Id: Ib20644853ead901e32f639000f044d6935135bae
2026-05-25 07:33:53 -04:00
Christian Soffke
727cb798e1 usb: disable status event debouncing
commit 3307b04 didn't fully get rid of the PANICs observed on the
Fiio M3K after adding a debounce interval for USB status by event
in e75a3fb, so this reverts to the previous behavior

Change-Id: I42b45a545eb1e26fa3ae3150504712079678f96e
2026-05-25 07:01:49 -04:00
Christian Soffke
04e557898f playlist: delay loading splash when adding indices
For playlists whose indices can be quickly added,
we should not be showing a splash.

Change-Id: Ib58fe8e28201f519e410fa99b2cb19e7e9a70fc9
2026-05-24 22:21:45 -04:00
Christian Soffke
ae17d606be playlist_viewer: provide UI feedback when loading is delayed
If Playlist Viewer can't open instantaneously due
to the retrieval of metadata, or on devices with disk
storage, make sure the UI doesn't feel unresponsive

Change-Id: Ib7a837515b4fb89ee0ee34ec04541200248b1d6f
2026-05-24 22:21:38 -04:00
Solomon Peachy
cfbbf5b488 pdbox: Fix up a pile of set-but-unused variable warnings with GCC16
Change-Id: I8de93d879ade61251fdde205353120a8e583b157
2026-05-23 21:31:25 -04:00
Solomon Peachy
95df5fdec0 doom: Fix set-but-unused warnings with GCC16
Change-Id: Iecd8ea9f5dc95f37955bed5e4892a90a93472cc6
2026-05-23 21:22:52 -04:00
Solomon Peachy
eb6746c1d6 albumart: fix warning with GCC16
apps/recorder/albumart.c:68:9: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
68 | sep = strrchr(fullpath, '/');
| ^

Change-Id: Ifd25623c8fa649302e44421316671aec2de9f037
2026-05-23 21:11:40 -04:00
William Wilgus
4ffd098ac9 [bugfix] text_viewer plugin, wonky word wrap, line pos buffer overflow
IpodVT reported odd word wrapping in the case of a perfectly fitting line on a space
which carried over to the next line

in the process I got a ASAN overflow on the line buffer due to
the possibility that lines_per_page - 1 might be -1 and then
reading off in space for an offset into the file
not sure that this would really cause an issue since it would presumably
be bounded within the boundries of the file anyway

Change-Id: Ib5b2c5a30b58faf8bda653f9b9d8d7f76cfb8069
2026-05-23 18:24:01 -04:00
Skye
557694a07f libc: add sscanf to core
Change-Id: Ia4162132a500e4d06305eab724250b7714091b9e
2026-05-23 08:03:09 -04:00
Christian Soffke
6a252576f5 bookmark: stop scrolling list item for skinned context menu
Lists with a selection size of >1 aren't skinned, so we
we have to manually take care of calling scroll_stop on
the un-skinned bookmark list before displaying the
(skinned) context menu.

Change-Id: Ie7ce627b5ea073be03304b7c676403cdfb4d3243
2026-05-23 12:05:07 +02:00
William Wilgus
f456dbfa52 [Bugfix] FS#13902 lua strfrtime wrong month field, did not add one to month
posix month field is called mon not month
mon goes from 0-11 so strfrtime needs to add 1 to the number for %m
day of week goes 0-6 where 0 = sunday
day of year goes 0-365 (365 on a leap year)

according to lua everything starts at 1
so month is 1-12
day of week goes 1-7 1 = sunday
day of year is 1-365 (366 on a leap year)

added some fields in the time_date example

Change-Id: Icd502b172285d23133488aa3456786d756667bfa
2026-05-22 18:10:36 -04:00
Skye
b5597a1c38 erosqnative: add HW4 BT pins
Change-Id: I2569f4db70261b454a1e1444ec529f8e714adc80
2026-05-20 10:24:12 -04:00
Solomon Peachy
bf8328fbe0 rbcodec: Fix build failure with DEBUG but without LOGF
Regression from 39497d1c74

Change-Id: I09ae974b56cd94753caa8bd4630d7ffcfe057846
2026-05-19 19:48:41 -04:00
Christian Soffke
1c39495ec2 playlist_viewer: simplify format_line
Reduces GNU Complexity score from 33 to 2.

Additionally:

- Allocate MAX_PATH, instead of MAX_PATH+1,
  for formatted id3 info (NULL terminator is
  already included)

- Ensure minimum name buffer size of 2*MAX_PATH,
  instead of MAX_PATH+1, so that there is space for
  both the formatted track name and, if enabled, the
  id3 info of a single track

Change-Id: Ie60590f6c0da4fe3a515b5643494a29cfc56de50
2026-05-19 19:37:29 -04:00
Christian Soffke
0492021247 fix yellow in commit 13a0e58b1c
Change-Id: Id2ec3d0ace5aab9d67aeda54f4cef52d0d111b01
2026-05-19 23:23:39 +02:00
Christian Soffke
13a0e58b1c gui: usb_screen: drawing adjustments
- Eliminate separate display update for USB screen UI vp;
  wait for skin_render instead

- Eliminate outer loop around handle_usb_events

- Use handle_usb_events in Simulator as well.
  Fixes USB screen being dismissed by any button presses,
  or by system events.

- When USB keypad mode is changed, only redraw the title viewport

- Delete unused MODE_NAME_LEN #define

- Hide "USB keypad mode:" prefix. Only display current mode setting,
  which requires less scrolling and ensures that the new setting
  is always visible immediately after it has been changed

- Change comment from:

  /* Don't return until we get SYS_USB_DISCONNECTED or SYS_TIMEOUT */
  to: /* Don't return until we get SYS_USB_DISCONNECTED */

  which reflects existing behavior (comment may have been
  copy-pasted from usb_wait_for_disconnect_w_tmo)

- Don't scroll USB keypad mode unless UI vp's width is > 1, since
  some themes try to hide the USB viewport and display a custom UI
  instead

Change-Id: I9b9703025b00ad807920ee60a843f269f414f6f9
2026-05-19 17:06:47 -04:00
Roman Artiukhin
69b6c97e58 Codecs: mp4: Improve support for long files
Load stts (time to sample) table on demand if it doesn't fit in RAM.

Fixes FS#13889 (in most cases I've seen files with single element in this table and problematic one has 111200 elements)

Change-Id: I719f92a4512a45472739587e81861b9bc545f349
2026-05-19 16:28:50 -04:00
Christian Soffke
aae46a822a simulator: support usb_inserted %bu tag (FS#13843)
Change-Id: Ia236c51f338bd333795f17991eb9e3659e722c6c
2026-05-19 13:37:28 -04:00
Christian Soffke
29d62e933f plugins: text_editor: fix list items that continue to scroll (FS#13900)
When using a theme with custom skinned lists
(e.g. Themify 2), a line in Text Editor will
continue to scroll after opening the context
menu, because you're switching from an un-
skinned list to a skinned list, which means
that list-skinned.c/list_draw isn't calling
scroll_stop_viewport for the list_text_vp,
as would be the case for un-skinned lists.

Change-Id: I952937166d8f17c9d57f4d93e715de970c49e5e8
2026-05-19 12:20:11 -04:00
Christian Soffke
1a8efac956 manual: fix skinned list tag mixup (FS#13895)
Change-Id: I890fe8800aa6e8640f445cd79ee3fa192398ad0c
2026-05-19 17:11:42 +02:00
William Wilgus
58f75311d8 merge font_getstringnsize and font_measurestring
measure string just needed a bit more to be a replacement

Change-Id: I25c760df5edd7224b50c0522b4e44b1f9b574c51
2026-05-18 01:36:50 -04:00
William Wilgus
6e27ba80e4 [bugfix] splash.c /t as last char should not add extra spaces
small bug, /t as the last character should left justify without
adding spaces to the end of string
/t also added too many spaces to the end of tabbed lines

adds info comment for new usage

ifdef removes some functionality for the bootloader

Change-Id: Ia4ba80f631f8bac3a13441912a8560616fa2c784
2026-05-18 00:12:18 -04:00
Solomon Peachy
d97e4425c6 playlist_viewer: Use 'NULL' instead of '0' when calling playlist_viewer_init
For some reason this resolves an apparently-unrelated warning about a const
violation inside playlist_viewer_init().

Change-Id: Ifd4eb008335876707abe64da04a3afd0d1c46633
2026-05-17 16:45:47 -04:00
Solomon Peachy
39497d1c74 build: Silence a pile of set-but-not-used warnings in codecs
GCC16 is stricter about reporting these, and while we can rely on
the compiler to optimize away dead stores, we're better off eliminating
them from the source code.

Change-Id: I14570a986811a77ca656c60d792593ff8c458571
2026-05-17 16:39:06 -04:00
Christian Soffke
8abc859c32 fix regression in cae4336
Change-Id: I026fe919401bbe13cef161a6eb6ce44e5fbbbb6f
2026-05-17 14:49:46 +02:00
Solomon Peachy
cae433608f build: Silence a pile of set-but-not-used warnings with GCC16 in apps/
The compiler is smart enough to optimize away dead stores but let's
just get rid of them in the first place

Change-Id: I5c85d7c05ef03b084205356a21248f7b049296b0
2026-05-17 08:03:44 -04:00
mojyack
2c0381a34e plugins: mpegplayer: libmpeg2: idct_armv6.S: use explicit register pair for ldrd
Change-Id: I65c7516f500cfe9f2b4990f769e9d85708f7fc62
2026-05-17 07:36:11 -04:00
mojyack
a446c06b21 recorder: jpeg_idct_arm.S: use explicit register pair for ldrd
Change-Id: Ic76b4ed4d2a3bea16937a5880502f0a57dd4e556
2026-05-17 07:35:00 -04:00
William Wilgus
d8db60b34a [bugfix] splash goes into infinite loop when vp is too small
chris_s reported that a vp width of 1 wpuld cause the trxt reflow to go into an endless loop

check for this and skip displaying the splash
add a warning to the sim for catching unintentional cases of this

Change-Id: I9e1c561f745b5bcf113d0a6cdff57a00cd190fd4
2026-05-16 17:33:20 -04:00
William Wilgus
7c2e84ad2f FS#13898 expand date_time.lua example
os.date(*t) did not return table when *t supplied because
require("strfrtime.lua") was not loaded

Change-Id: I89b02adad633dca0106b571bdb4b10ffb39cbcf6
2026-05-16 15:54:42 -04:00
William Wilgus
17d28b96b6 lua rocklib.c add splash_progress function
Change-Id: I864a301368c3144a7808ecfa9644e679af2ac727
2026-05-16 14:56:51 -04:00
mojyack
b350d6e066 target: arm: s5l8702: crt0.S: use APSR_nzcv instead of r15 in mrc operand
Change-Id: I7e0cf0325407cade9d95d73af6f8dceb92bf3155
2026-05-16 12:02:32 -04:00
mojyack
c4abbdd718 target: arm: mmu-arm.S: use APSR_nzcv instead of r15 in mrc operand
Change-Id: Ie27d323ac497fe8d63cee89d2c0722caa293cd25
2026-05-16 12:02:11 -04:00
mojyack
127428e32d bootloader: ipodnano2g: fix mcr/mrc usage for clang
Change-Id: I0e328c2d0d4243783cbede843a6451c45f5ba914
2026-05-16 12:01:36 -04:00
mojyack
6fc41c7cdf target: arm: s5l8700: fix mcr/mrc usage in crt0.S for lld
Change-Id: I6d25e4759e1d86f8de3047d10f5fcac8030afc6e
2026-05-16 12:00:45 -04:00
William Wilgus
21fe45caad [Bugfix] splash adjust string split logic, tab justify
only split a long word across lines if it is larger than screen width
also consider \0 as a valid place to split so we still run through the space finding loop

make /t left justify the splash window (in RTL langs it right justifies)

Change-Id: Id2955878a178c66cb0a1c644e62f943247666d8b
2026-05-16 11:51:53 -04:00
Solomon Peachy
1beafb9290 FS#13891 - Updated Romanian and Moldavian translations (Mihai Alexandru Vasiliu)
Change-Id: Ida441f2324fad443c89da82a9d4d58fcbb9e2f6f
2026-05-16 07:37:40 -04:00
Solomon Peachy
6ee85ce61a imx233: Increase the memory region reserved for loading firmware
The imx233 bootloader reserves the first 1MB of DRAM for loading the
main firmware, but the recent utf8proc changes means we now exceed that
size on most imx233 targets.  Bump this up to 1.5MB to give us more headroom

Change-Id: I1b8bede85d06d40338ea6e3d9abb4e5da34423be
2026-05-15 11:41:23 -04:00
William Wilgus
b4c308d698 splash, rework word wrap, support some escape characters
Fixes issues with multiple spaces
adds support for \n and multiple \n
adds support for \t (only at start of line)

adds utf8 aware string splitting

locks to max width/height

adds \f to reset min width / height

larger buffer for units with ram > 8mb

make splash buffer static

Needs testing
Change-Id: I46915043719dce0d696c5ab0da3ed92e4755829c
2026-05-15 11:13:12 -04:00
Solomon Peachy
89cb41c322 pdbox: Add a keymap for the ErosQ family, enable it in the build
Change-Id: I9df8d8a8eac161aeaa133e234cc0c2a60b2f3f93
2026-05-15 10:54:08 -04:00
Solomon Peachy
f774de61b6 xworld, pdbox: Fix issues with using strncpy
Change-Id: Iaed18b7c856b7febef443d1e3e5f6b527b32ecae
2026-05-15 10:37:35 -04:00
Solomon Peachy
a977c19338 fix broken bootloader builds, regression from 5951f6e5e9
Change-Id: I0daf76c362c9e50bf6593e3c8f40847a121dd3ea
2026-05-15 10:25:25 -04:00
Skye
5951f6e5e9 libc: move strncpy to core
Change-Id: If005a0305cedbab85905536238d0f799f19213e1
2026-05-15 10:04:06 -04:00
Solomon Peachy
4c60fe95fc Revert "pp5020: ata: do not yield in ata_wait_intrq()"
This reverts commit e13befb925.

Reason for revert:  Significant performance regressions, especially with respect to UI interactivity when the database is in use; see https://forums.rockbox.org/index.php/topic,55703.0.html

Change-Id: I0428711871480b74f7faeecb0536f7ed63f631cc
2026-05-14 14:42:53 -04:00
Skye
7d3f738b3f libc: fix firmware assert.h
Change-Id: Id7cc3e4656519fee908083d3b551c5228d220ef7
2026-05-14 11:54:52 -04:00
William Wilgus
db32a7f07e [bugfix] font_getstringnsize() incorrect count, add font_measurestring()
maxbytes counted final characters not actual bytes

font_measurestring() returns the number of bytes of a string that will
fit in a given width

Change-Id: Id73b763267e399bd558f87872b5e715076f9b7f7
2026-05-14 09:51:58 -04:00
3852 changed files with 23201 additions and 15365 deletions

21
.gitignore vendored
View file

@ -82,7 +82,15 @@ __pycache__
/utils/bspatch/bspatch /utils/bspatch/bspatch
# imxtools # imxtools
/utils/imxtools/misc/io_pins
/utils/imxtools/misc/wiki_gen
/utils/imxtools/scsitools/scsitool /utils/imxtools/scsitools/scsitool
/utils/imxtools/sbtools/elftosb
/utils/imxtools/sbtools/elftosb1
/utils/imxtools/sbtools/rsrctool
/utils/imxtools/sbtools/sbloader
/utils/imxtools/sbtools/sbtoelf
/utils/mkimxboot/mkimxboot
# /utils/rbutilqt/ # /utils/rbutilqt/
/utils/rbutilqt/build /utils/rbutilqt/build
@ -100,16 +108,22 @@ __pycache__
# /utils/rbutilqt/lang/ # /utils/rbutilqt/lang/
/utils/rbutilqt/lang/*.qm /utils/rbutilqt/lang/*.qm
# More rbutil # More target-specific utilities
/utils/*/buildposix /utils/*/buildposix
/utils/*/uninstall_script.[ch] /utils/*/uninstall_script.[ch]
/utils/*/install_script.[ch] /utils/*/install_script.[ch]
/utils/mkimxboot/mkimxboot /utils/e200tool/e200load
/utils/mknwzboot/mknwzboot /utils/mknwzboot/mknwzboot
/utils/mkzenboot/mkzenboot /utils/mkzenboot/mkzenboot
/utils/sansapatcher/sansapatcher /utils/sansapatcher/sansapatcher
/utils/jztool/jztool /utils/jztool/jztool
/utils/tools/bin2c /utils/tools/bin2c
/utils/rk27utils/nandextract/nandextract
/utils/rk27utils/rk27load/rk27load
/utils/rk27utils/rkwtool/rkwtool
/utils/rk27utils/rkusbtool/rkusbtool
/utils/mkmpioboot/mkmpioboot
/utils/mktccboot/mktccboot
# /tools/ # /tools/
/tools/bdf2bmp /tools/bdf2bmp
@ -188,8 +202,9 @@ __pycache__
# /utils/nwztools # /utils/nwztools
/utils/nwztools/scsitools/scsitool /utils/nwztools/scsitools/scsitool
/utils/nwztools/upgtools/upgtool /utils/nwztools/upgtools/upgtool
/utils/nwztools/emmctools/emmctool
# utils/rk27utils # utils/rk27utils
/utils/rk27utils/rkboottool/rkboottool /utils/rk27utils/rkboottool/rkboottool
# /utils/themeeditor/ # /utils/themeeditor/

View file

@ -4,7 +4,6 @@
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/ # \/ \/ \/ \/ \/
# $Id$
# #
PACKAGE=org.rockbox PACKAGE=org.rockbox

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 Thomas Martitz * Copyright (C) 2011 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Thomas Martitz * Copyright (C) 2010 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Thomas Martitz * Copyright (C) 2010 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Thomas Martitz * Copyright (C) 2010 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Jonathan Gordon * Copyright (C) 2010 Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Thomas Martitz * Copyright (C) 2010 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Thomas Martitz * Copyright (C) 2010 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Jonathan Gordon * Copyright (C) 2010 Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 Thomas Martitz * Copyright (C) 2011 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 Thomas Martitz * Copyright (C) 2011 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Thomas Martitz * Copyright (C) 2010 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org> * Copyright (C) 2011 Antoine Cellerier <dionoea at videolan dot org>
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 Ray Lambert * Copyright (C) 2005 Ray Lambert
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 Ray Lambert * Copyright (C) 2005 Ray Lambert
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2006 Jonathan Gordon * Copyright (C) 2006 Jonathan Gordon
* Copyright (C) 2017 William Wilgus * Copyright (C) 2017 William Wilgus
@ -430,6 +429,7 @@ static inline bool get_action_touchscreen(action_last_t *last, action_cur_t *cur
{ {
intptr_t data = button_get_data(); intptr_t data = button_get_data();
long now = current_tick; long now = current_tick;
last->repeated = false;
if (has_flag(last->button, BUTTON_TOUCHSCREEN) && if (has_flag(last->button, BUTTON_TOUCHSCREEN) &&
!has_flag(last->button, BUTTON_REL)) !has_flag(last->button, BUTTON_REL))
@ -439,7 +439,6 @@ static inline bool get_action_touchscreen(action_last_t *last, action_cur_t *cur
if (!has_flag(cur->button, BUTTON_REL)) if (!has_flag(cur->button, BUTTON_REL))
last->ts_data = data; last->ts_data = data;
/* Historical baggage... may be unnecessary. */
if (has_flag(cur->button, BUTTON_REPEAT)) if (has_flag(cur->button, BUTTON_REPEAT))
last->repeated = true; last->repeated = true;
} }

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2003 Uwe Freese * Copyright (C) 2003 Uwe Freese
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2003 Uwe Freese * Copyright (C) 2003 Uwe Freese
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2008 by Jonathan Gordon * Copyright (C) 2008 by Jonathan Gordon
* *
@ -73,11 +72,13 @@ enum {
/** Generic GUI class events **/ /** Generic GUI class events **/
enum { enum {
GUI_EVENT_STATUSBAR_TOGGLE = (EVENT_CLASS_GUI|1), /* Redraw skin as needed (or by force) */
GUI_EVENT_ACTIONREDRAW = (EVENT_CLASS_GUI|1),
/* Redraw skin, and update the screen if it's dirty */
GUI_EVENT_ACTIONUPDATE, GUI_EVENT_ACTIONUPDATE,
GUI_EVENT_THEME_CHANGED, GUI_EVENT_THEME_CHANGED,
/* Called when the UI viewport is cleared in the skin engine to /* Called when the UI viewport is cleared in the skin engine to
* notify the current screen that it needs to do an update */ * notify the current screen that it needs to redraw itself */
GUI_EVENT_NEED_UI_UPDATE, GUI_EVENT_NEED_UI_UPDATE,
}; };

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Linus Nielsen Feltzing * Copyright (C) 2002 Linus Nielsen Feltzing
* *

View file

@ -4,7 +4,6 @@
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/ # \/ \/ \/ \/ \/
# $Id$
# #
INCLUDES += -I$(APPSDIR) $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA))) INCLUDES += -I$(APPSDIR) $(patsubst %,-I$(APPSDIR)/%,$(subst :, ,$(APPEXTRA)))

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Audio signal path management APIs * Audio signal path management APIs
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005-2007 Miika Pekkarinen * Copyright (C) 2005-2007 Miika Pekkarinen
* Copyright (C) 2007-2008 Nicolas Pennequin * Copyright (C) 2007-2008 Nicolas Pennequin

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005-2007 Miika Pekkarinen * Copyright (C) 2005-2007 Miika Pekkarinen
* Copyright (C) 2007-2008 Nicolas Pennequin * Copyright (C) 2007-2008 Nicolas Pennequin

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (c) 2011 Michael Sevakis * Copyright (c) 2011 Michael Sevakis
* *

View file

@ -4,7 +4,6 @@
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/ # \/ \/ \/ \/ \/
# $Id$
# #
BITMAPDIR = $(ROOTDIR)/apps/bitmaps BITMAPDIR = $(ROOTDIR)/apps/bitmaps

View file

@ -959,14 +959,15 @@ static bool delete_bookmark(const char* bookmark_file_name, int bookmark_id)
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
/* This displays the bookmarks in a file and allows the user to */ /* Displays bookmarks in a file, so user can select one to play. */
/* select one to play. */ /* */
/* *selected_bookmark contains a non NULL value on successful bookmark */ /* Returns */
/* selection. */ /* BOOKMARK_SUCCESS A bookmark or 'Don't Resume' was selected */
/* Returns BOOKMARK_SUCCESS on successful bookmark selection, BOOKMARK_FAIL*/ /* BOOKMARK_FAIL No selection was made */
/* if no selection was made and BOOKMARK_USB_CONNECTED if the selection */ /* BOOKMARK_USB_CONNECTED USB connection forced exit of menu */
/* menu is forced to exit due to a USB connection. */ /* */
/* ------------------------------------------------------------------------*/ /* *selected_bookmark will point to bookmark if selected, or will be NULL */
/* ----------------------------------------------------------------------- */
static int select_bookmark(const char* bookmark_file_name, static int select_bookmark(const char* bookmark_file_name,
bool show_dont_resume, bool show_dont_resume,
char** selected_bookmark) char** selected_bookmark)
@ -979,6 +980,7 @@ static int select_bookmark(const char* bookmark_file_name,
bool exit = false; bool exit = false;
bool refresh = true; bool refresh = true;
int ret = BOOKMARK_FAIL; int ret = BOOKMARK_FAIL;
*selected_bookmark = NULL;
bookmarks = plugin_get_buffer(&size); bookmarks = plugin_get_buffer(&size);
bookmarks->buffer_size = size; bookmarks->buffer_size = size;
@ -996,9 +998,9 @@ static int select_bookmark(const char* bookmark_file_name,
while (!exit) while (!exit)
{ {
if (refresh) if (refresh)
{ {
refresh = false;
int count = get_bookmark_count(bookmark_file_name); int count = get_bookmark_count(bookmark_file_name);
bookmarks->total_count = count; bookmarks->total_count = count;
@ -1007,8 +1009,7 @@ static int select_bookmark(const char* bookmark_file_name,
/* No more bookmarks, delete file and exit */ /* No more bookmarks, delete file and exit */
splash(HZ, ID2P(LANG_BOOKMARK_LOAD_EMPTY)); splash(HZ, ID2P(LANG_BOOKMARK_LOAD_EMPTY));
remove(bookmark_file_name); remove(bookmark_file_name);
*selected_bookmark = NULL; break;
return BOOKMARK_FAIL;
} }
if (bookmarks->show_dont_resume) if (bookmarks->show_dont_resume)
@ -1032,80 +1033,61 @@ static int select_bookmark(const char* bookmark_file_name,
gui_synclist_draw(&list); gui_synclist_draw(&list);
cond_talk_ids_fq(VOICE_EXT_BMARK); cond_talk_ids_fq(VOICE_EXT_BMARK);
gui_synclist_speak_item(&list); gui_synclist_speak_item(&list);
refresh = false;
} }
list_do_action(CONTEXT_BOOKMARKSCREEN, HZ / 2, &list, &action); list_do_action(CONTEXT_BOOKMARKSCREEN, HZ / 2, &list, &action);
item = gui_synclist_get_sel_pos(&list) / 2; item = gui_synclist_get_sel_pos(&list) / 2;
if (bookmarks->show_dont_resume) if (bookmarks->show_dont_resume)
{
item--; item--;
}
if (action == ACTION_STD_CONTEXT) if (action == ACTION_STD_CONTEXT)
{ {
MENUITEM_STRINGLIST(menu_items, ID2P(LANG_BOOKMARK_CONTEXT_MENU), gui_synclist_scroll_stop(&list);
NULL, ID2P(LANG_BOOKMARK_CONTEXT_RESUME), MENUITEM_STRINGLIST(menu_items, ID2P(LANG_BOOKMARK_CONTEXT_MENU), NULL,
ID2P(LANG_DELETE)); ID2P(LANG_BOOKMARK_CONTEXT_RESUME),
static const int menu_actions[] = ID2P(LANG_DELETE));
{ static const int menu_actions[] = {ACTION_STD_OK,
ACTION_STD_OK, ACTION_BMS_DELETE ACTION_BMS_DELETE};
};
int selection = do_menu(&menu_items, NULL, NULL, false); int selection = do_menu(&menu_items, NULL, NULL, false);
refresh = true; refresh = true;
if (selection >= 0 && selection <= if (selection >= 0 && selection <=
(int) (sizeof(menu_actions) / sizeof(menu_actions[0]))) (int) (sizeof(menu_actions) / sizeof(menu_actions[0])))
{
action = menu_actions[selection]; action = menu_actions[selection];
}
} }
switch (action) switch (action)
{ {
case ACTION_STD_OK: case ACTION_STD_OK:
if (item >= 0)
{
talk_shutup();
*selected_bookmark = bookmarks->items[item - bookmarks->start];
return BOOKMARK_SUCCESS;
}
exit = true;
ret = BOOKMARK_SUCCESS; ret = BOOKMARK_SUCCESS;
break; if (item >= 0)
*selected_bookmark = bookmarks->items[item - bookmarks->start];
/* fall through */
case ACTION_TREE_WPS: case ACTION_TREE_WPS:
case ACTION_STD_CANCEL: case ACTION_STD_CANCEL:
exit = true; exit = true;
break; break;
case ACTION_BMS_DELETE: case ACTION_BMS_DELETE:
if (item >= 0) if (item < 0)
break;
if (confirm_delete_yesno("", str(LANG_BOOKMARK_CONTEXT_MENU)) == YESNO_YES)
{ {
if (confirm_delete_yesno("", str(LANG_BOOKMARK_CONTEXT_MENU)) == YESNO_YES) delete_bookmark(bookmark_file_name, item);
{ bookmarks->reload = true;
delete_bookmark(bookmark_file_name, item);
bookmarks->reload = true;
}
refresh = true;
} }
refresh = true;
break; break;
default: default:
if (default_event_handler(action) == SYS_USB_CONNECTED) if (default_event_handler(action) == SYS_USB_CONNECTED)
{ {
ret = BOOKMARK_USB_CONNECTED; ret = BOOKMARK_USB_CONNECTED;
exit = true; exit = true;
} }
break; break;
} }
} }
gui_synclist_scroll_stop(&list);
talk_shutup(); talk_shutup();
*selected_bookmark = NULL;
return ret; return ret;
} }

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 Nicolas Pennequin * Copyright (C) 2007 Nicolas Pennequin
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 Nicolas Pennequin * Copyright (C) 2007 Nicolas Pennequin
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005-2007 Miika Pekkarinen * Copyright (C) 2005-2007 Miika Pekkarinen
* Copyright (C) 2007-2008 Nicolas Pennequin * Copyright (C) 2007-2008 Nicolas Pennequin

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 Miika Pekkarinen * Copyright (C) 2005 Miika Pekkarinen
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Björn Stenberg * Copyright (C) 2002 Björn Stenberg
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2020 by William Wilgus * Copyright (C) 2020 by William Wilgus
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2020 by William Wilgus * Copyright (C) 2020 by William Wilgus
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 Nicolas Pennequin, Jonathan Gordon * Copyright (C) 2007 Nicolas Pennequin, Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 Nicolas Pennequin, Jonathan Gordon * Copyright (C) 2007 Nicolas Pennequin, Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Heikki Hannikainen * Copyright (C) 2002 Heikki Hannikainen
* *
@ -219,6 +218,22 @@ static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
} }
#if LCD_WIDTH <= 128 #if LCD_WIDTH <= 128
int *x_offset = ((int*) lists->data); int *x_offset = ((int*) lists->data);
#if CONFIG_CPU == AS3525v2
if (action == ACTION_STD_MENU)
{
*x_offset += 1;
action = ACTION_REDRAW;
}
else if (IS_SYSEVENT(action))
{
return ACTION_REDRAW;
}
else if (action == ACTION_STD_OK)
{
*x_offset = 0;
action = ACTION_REDRAW;
}
#else
if (action == ACTION_STD_OK) if (action == ACTION_STD_OK)
{ {
*x_offset += 1; *x_offset += 1;
@ -232,6 +247,7 @@ static int dbg_threads_action_callback(int action, struct gui_synclist *lists)
{ {
*x_offset = 0; *x_offset = 0;
} }
#endif
#else #else
(void) lists; (void) lists;
#endif #endif

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Heikki Hannikainen * Copyright (C) 2002 Heikki Hannikainen
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2006 Michael Sevakis * Copyright (C) 2006 Michael Sevakis
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2006 Michael Sevakis * Copyright (C) 2006 Michael Sevakis
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Björn Stenberg * Copyright (C) 2002 Björn Stenberg
* Copyright (C) 2024 William Wilgus * Copyright (C) 2024 William Wilgus

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Björn Stenberg * Copyright (C) 2002 Björn Stenberg
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Björn Stenberg * Copyright (C) 2005 by Björn Stenberg
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Björn Stenberg * Copyright (C) 2005 by Björn Stenberg
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* *
* $Id$
* *
* Copyright (C) 2007 Jonathan Gordon * Copyright (C) 2007 Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Henrik Backe * Copyright (C) 2002 Henrik Backe
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2022 by Aidan MacDonald * Copyright (C) 2022 by Aidan MacDonald
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2022 Aidan MacDonald * Copyright (C) 2022 Aidan MacDonald
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2006 Dave Chapman * Copyright (C) 2006 Dave Chapman
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2006 Dave Chapman * Copyright (C) 2006 Dave Chapman
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2011 by Jonathan Gordon * Copyright (C) 2011 by Jonathan Gordon
* *
@ -44,6 +43,7 @@
static struct listitem_viewport_cfg *listcfg[NB_SCREENS] = {NULL}; static struct listitem_viewport_cfg *listcfg[NB_SCREENS] = {NULL};
static struct gui_synclist *current_list; static struct gui_synclist *current_list;
static bool needs_scrollbar[NB_SCREENS];
static int current_row; static int current_row;
static int current_column; static int current_column;
@ -56,6 +56,7 @@ void skinlist_set_cfg(enum screen_type screen,
if (listcfg[screen]) if (listcfg[screen])
screens[screen].scroll_stop_viewport(&listcfg[screen]->selected_item_vp.vp); screens[screen].scroll_stop_viewport(&listcfg[screen]->selected_item_vp.vp);
listcfg[screen] = cfg; listcfg[screen] = cfg;
needs_scrollbar[screen] = false;
current_list = NULL; current_list = NULL;
current_column = -1; current_column = -1;
current_row = -1; current_row = -1;
@ -145,7 +146,6 @@ int skinlist_get_line_count(enum screen_type screen, struct gui_synclist *list)
static int current_item; static int current_item;
static int current_nbitems; static int current_nbitems;
static bool needs_scrollbar[NB_SCREENS];
bool skinlist_needs_scrollbar(enum screen_type screen) bool skinlist_needs_scrollbar(enum screen_type screen)
{ {
return needs_scrollbar[screen]; return needs_scrollbar[screen];
@ -281,7 +281,7 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
} }
current_column = -1; current_column = -1;
current_row = -1; current_row = -1;
skin_render_deferred(display, parent);
current_drawing_line = list->selected_item; current_drawing_line = list->selected_item;
sb_skin_force_next_update(); /* update scroll bar */
return true; return true;
} }

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 by Jonathan Gordon * Copyright (C) 2007 by Jonathan Gordon
* *
@ -446,7 +445,6 @@ void list_draw(struct screen *display, struct gui_synclist *list)
callback_draw_item(&list_info); callback_draw_item(&list_info);
} }
skin_render_deferred(display, parent);
display->set_viewport(last_vp); display->set_viewport(last_vp);
} }

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) Jonathan Gordon (2006) * Copyright (C) Jonathan Gordon (2006)
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) Jonathan Gordon (2006) * Copyright (C) Jonathan Gordon (2006)
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 Jonathan Gordon * Copyright (C) 2007 Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2013 Thomas Martitz * Copyright (C) 2013 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2013 Thomas Martitz * Copyright (C) 2013 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *
@ -49,8 +48,6 @@
void list_draw(struct screen *display, struct gui_synclist *list); void list_draw(struct screen *display, struct gui_synclist *list);
static long last_dirty_tick; static long last_dirty_tick;
static bool sb_title_is_dirty;
static bool theme_enabled;
static struct viewport parent[NB_SCREENS]; static struct viewport parent[NB_SCREENS];
static struct gui_synclist *current_lists; static struct gui_synclist *current_lists;
@ -183,6 +180,9 @@ void gui_synclist_init(struct gui_synclist * gui_list,
gui_list->data = data; gui_list->data = data;
gui_list->scroll_all = scroll_all; gui_list->scroll_all = scroll_all;
gui_list->selected_size = selected_size; gui_list->selected_size = selected_size;
if (selected_size != 1)
FOR_NB_SCREENS(i)
skinlist_set_cfg(i, NULL);
gui_list->title = NULL; gui_list->title = NULL;
gui_list->title_icon = Icon_NOICON; gui_list->title_icon = Icon_NOICON;
@ -221,32 +221,11 @@ int gui_list_get_item_offset(struct gui_synclist * gui_list,
return item_offset; return item_offset;
} }
static void sb_title_cb(unsigned short id, void *data, void *userdata)
{
(void)id;
(void)data;
theme_enabled = true;
gui_synclist_draw((struct gui_synclist *) userdata);
}
/* /*
* Force a full screen update. * Force a full screen update.
*/ */
void gui_synclist_draw(struct gui_synclist *gui_list) void gui_synclist_draw(struct gui_synclist *gui_list)
{ {
if (sb_title_is_dirty)
{
sb_title_is_dirty = theme_enabled = false;
/* tell skin engine to refresh, then call us back */
add_event_ex(GUI_EVENT_NEED_UI_UPDATE, true, sb_title_cb, gui_list);
send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
remove_event_ex(GUI_EVENT_NEED_UI_UPDATE, sb_title_cb, gui_list);
/* sb_title_cb was only called if theme is enabled */
if (theme_enabled)
return;
}
if (list_is_dirty(gui_list)) if (list_is_dirty(gui_list))
{ {
list_init_viewports(gui_list); list_init_viewports(gui_list);
@ -258,6 +237,7 @@ void gui_synclist_draw(struct gui_synclist *gui_list)
{ {
if (!skinlist_draw(&screens[i], gui_list)) if (!skinlist_draw(&screens[i], gui_list))
list_draw(&screens[i], gui_list); list_draw(&screens[i], gui_list);
skin_mark_dirty(i);
} }
} }
@ -461,7 +441,7 @@ void gui_synclist_set_title(struct gui_synclist * gui_list,
gui_list->title_icon = icon; gui_list->title_icon = icon;
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
sb_set_title_text(title, icon, i); sb_set_title_text(title, icon, i);
sb_title_is_dirty = true; send_event(GUI_EVENT_ACTIONREDRAW, (void*)1);
} }
void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items) void gui_synclist_set_nb_items(struct gui_synclist * lists, int nb_items)
@ -952,7 +932,7 @@ bool simplelist_show_list(struct simplelist_info *info)
while(1) while(1)
{ {
list_do_action(CONTEXT_LIST, info->timeout, &lists, &action); list_do_action(CONTEXT_TREE|ALLOW_SOFTLOCK, info->timeout, &lists, &action);
/* We must yield in this case or no other thread can run */ /* We must yield in this case or no other thread can run */
if (info->timeout == TIMEOUT_NOBLOCK) if (info->timeout == TIMEOUT_NOBLOCK)
@ -978,6 +958,11 @@ bool simplelist_show_list(struct simplelist_info *info)
info->selection = -1; info->selection = -1;
break; break;
} }
else if (action == ACTION_TREE_WPS)
{
info->selection = -2;
break;
}
else if (action == ACTION_STD_OK) else if (action == ACTION_STD_OK)
{ {
info->selection = gui_synclist_get_sel_pos(&lists); info->selection = gui_synclist_get_sel_pos(&lists);

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* Copyright (C) 2007 by Jonathan Gordon * Copyright (C) 2007 by Jonathan Gordon
@ -533,7 +532,7 @@ bool option_screen(const struct settings_list *setting,
if (!allow_wrap) if (!allow_wrap)
lists.wraparound = false; lists.wraparound = false;
if (list_do_action(CONTEXT_LIST, HZ, /* HZ so the status bar redraws */ if (list_do_action(CONTEXT_LIST|ALLOW_SOFTLOCK, HZ, /* HZ so the status bar redraws */
&lists, &action)) &lists, &action))
{ {
/* setting changed */ /* setting changed */

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Björn Stenberg * Copyright (C) 2002 Björn Stenberg
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2008 Thomas Martitz * Copyright (C) 2008 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2008 by Jonathan Gordon * Copyright (C) 2008 by Jonathan Gordon
* *
@ -40,6 +39,7 @@
#include "debug.h" #include "debug.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "appevents.h" #include "appevents.h"
#include "statusbar-skinned.h"
/* 1 top, 1 bottom, 2 on either side, 1 for the icons /* 1 top, 1 bottom, 2 on either side, 1 for the icons
* if enough space, top and bottom have 2 lines */ * if enough space, top and bottom have 2 lines */
@ -233,7 +233,7 @@ static void quickscreen_draw(struct quickscreen *qs, enum screen_type screen)
(vp_icons->width/2) - 4, vp_icons->height - 8, 7, 8); (vp_icons->width/2) - 4, vp_icons->height - 8, 7, 8);
} }
skin_render_deferred(display, parent); skin_mark_dirty(display->screen_type);
display->set_viewport(last_vp); display->set_viewport(last_vp);
} }
@ -418,13 +418,11 @@ static void quickscreen_run(struct quickscreen * qs)
can_quit = true; can_quit = true;
else if (button == ACTION_QS_VOLUP) { else if (button == ACTION_QS_VOLUP) {
adjust_volume(1); adjust_volume(1);
FOR_NB_SCREENS(i) sb_skin_force_next_update();
skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_NON_STATIC);
} }
else if (button == ACTION_QS_VOLDOWN) { else if (button == ACTION_QS_VOLDOWN) {
adjust_volume(-1); adjust_volume(-1);
FOR_NB_SCREENS(i) sb_skin_force_next_update();
skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_NON_STATIC);
} }
else if (button == ACTION_STD_CONTEXT) else if (button == ACTION_STD_CONTEXT)
{ {

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) Markus Braun (2002) * Copyright (C) Markus Braun (2002)
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 Kevin Ferrare * Copyright (C) 2005 Kevin Ferrare
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Jonathan Gordon * Copyright (C) 2010 Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002-2007 Björn Stenberg * Copyright (C) 2002-2007 Björn Stenberg
* Copyright (C) 2007-2008 Nicolas Pennequin * Copyright (C) 2007-2008 Nicolas Pennequin
@ -71,8 +70,20 @@
#include "statusbar-skinned.h" #include "statusbar-skinned.h"
#include "skin_display.h" #include "skin_display.h"
static bool dirty[NB_SCREENS];
void skin_render(struct gui_wps *gwps, unsigned refresh_mode); void skin_render(struct gui_wps *gwps, unsigned refresh_mode);
bool skin_is_dirty(enum screen_type screen)
{
return dirty[screen] && !(dirty[screen] = false);
}
void skin_mark_dirty(enum screen_type screen)
{
dirty[screen] = true;
}
/* update a skinned screen, update_type is WPS_REFRESH_* values. /* update a skinned screen, update_type is WPS_REFRESH_* values.
* Usually it should only be WPS_REFRESH_NON_STATIC * Usually it should only be WPS_REFRESH_NON_STATIC
* A full update will be done if required (skin_do_full_update() == true) * A full update will be done if required (skin_do_full_update() == true)
@ -90,6 +101,7 @@ void skin_update(enum skinnable_screens skin, enum screen_type screen,
skin_render(gwps, skin_do_full_update(skin, screen) ? skin_render(gwps, skin_do_full_update(skin, screen) ?
SKIN_REFRESH_ALL : update_type); SKIN_REFRESH_ALL : update_type);
skin_mark_dirty(screen);
} }
#ifdef AB_REPEAT_ENABLE #ifdef AB_REPEAT_ENABLE
@ -198,6 +210,23 @@ void draw_progressbar(struct gui_wps *gwps, struct skin_viewport* skin_viewport,
length = 100; length = 100;
end = battery_level(); end = battery_level();
} }
else if (pb->type == SKIN_TOKEN_PLAYLIST_PROGRESSBAR)
{
unsigned long pl_elapsed, pl_total;
if (id3 && wps_get_playlist_percent(id3,
id3->elapsed + state->ff_rewind_count,
&pl_elapsed, &pl_total)
&& pl_total > 0)
{
length = pl_total;
end = pl_elapsed;
}
else
{
length = 1;
end = 0;
}
}
else if (pb->type == SKIN_TOKEN_PEAKMETER_LEFTBAR || else if (pb->type == SKIN_TOKEN_PEAKMETER_LEFTBAR ||
pb->type == SKIN_TOKEN_PEAKMETER_RIGHTBAR) pb->type == SKIN_TOKEN_PEAKMETER_RIGHTBAR)
{ {
@ -397,8 +426,17 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
(void)vp; (void)vp;
struct wps_data *data = gwps->data; struct wps_data *data = gwps->data;
struct screen *display = gwps->display; struct screen *display = gwps->display;
struct skin_token_list *list = SKINOFFSETTOPTR(get_skin_buffer(data), data->images);
/* Start with album art, as it may be drawn over by mask images */
#ifdef HAVE_ALBUMART
struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
if (aa && aa->draw_handle >= 0)
{
draw_album_art(gwps, aa->draw_handle, false);
aa->draw_handle = -1;
}
#endif
struct skin_token_list *list = SKINOFFSETTOPTR(get_skin_buffer(data), data->images);
while (list) while (list)
{ {
struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(data), list->token); struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(data), list->token);
@ -420,15 +458,6 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
} }
list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next); list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next);
} }
#ifdef HAVE_ALBUMART
/* now draw the AA */
struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
if (aa && aa->draw_handle >= 0)
{
draw_album_art(gwps, aa->draw_handle, false);
aa->draw_handle = -1;
}
#endif
display->set_drawmode(DRMODE_SOLID); display->set_drawmode(DRMODE_SOLID);
} }

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002-2007 Björn Stenberg * Copyright (C) 2002-2007 Björn Stenberg
* Copyright (C) 2007-2008 Nicolas Pennequin * Copyright (C) 2007-2008 Nicolas Pennequin

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Jonathan Gordon * Copyright (C) 2010 Jonathan Gordon
* *
@ -50,9 +49,6 @@ char* wps_default_skin(enum screen_type screen);
char* default_radio_skin(enum screen_type screen); char* default_radio_skin(enum screen_type screen);
static bool skins_initialised = false; static bool skins_initialised = false;
static char* get_skin_filename(char *buf, size_t buf_size,
enum skinnable_screens skin, enum screen_type screen);
struct gui_skin_helper { struct gui_skin_helper {
void (*process)(enum screen_type screen, struct wps_data *data, bool preprocess); void (*process)(enum screen_type screen, struct wps_data *data, bool preprocess);
char* (*default_skin)(enum screen_type screen); char* (*default_skin)(enum screen_type screen);
@ -153,11 +149,6 @@ void gui_sync_skin_init(void)
} }
} }
void skin_unload_all(void)
{
gui_sync_skin_init();
}
static void skin_reset_buffers(int item, int screen) static void skin_reset_buffers(int item, int screen)
{ {
skin_data_free_buflib_allocs(&skins[item][screen].data); skin_data_free_buflib_allocs(&skins[item][screen].data);
@ -174,7 +165,6 @@ static void skin_reset_buffers(int item, int screen)
void settings_apply_skins(void) void settings_apply_skins(void)
{ {
int i; int i;
char filename[MAX_PATH];
if (audio_status() & AUDIO_STATUS_PLAY) if (audio_status() & AUDIO_STATUS_PLAY)
audio_stop(); audio_stop();
@ -197,7 +187,6 @@ void settings_apply_skins(void)
{ {
FOR_NB_SCREENS(j) FOR_NB_SCREENS(j)
{ {
get_skin_filename(filename, MAX_PATH, i,j);
gui_skin_reset(&skins[i][j]); gui_skin_reset(&skins[i][j]);
skins[i][j].gui_wps.display = &screens[j]; skins[i][j].gui_wps.display = &screens[j];
if (skin_helpers[i]->load_on_boot) if (skin_helpers[i]->load_on_boot)

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 Nicolas Pennequin * Copyright (C) 2007 Nicolas Pennequin
* Copyright (C) 2009 Jonathan Gordon * Copyright (C) 2009 Jonathan Gordon
@ -50,12 +49,8 @@ void skin_disarm_touchregions(struct gui_wps *gwps);
/* Do a update_type update of the skinned screen */ /* Do a update_type update of the skinned screen */
void skin_update(enum skinnable_screens skin, enum screen_type screen, void skin_update(enum skinnable_screens skin, enum screen_type screen,
unsigned int update_type); unsigned int update_type);
void skin_mark_dirty(enum screen_type screen);
/* Defer updates in skin_render */ bool skin_is_dirty(enum screen_type screen);
void skin_defer_rendering(bool deferred);
/* Render viewport together with deferred updates */
void skin_render_deferred(struct screen *display, struct viewport *vp);
bool skin_has_sbs(struct gui_wps *gwps); bool skin_has_sbs(struct gui_wps *gwps);
@ -83,8 +78,6 @@ void skin_load(enum skinnable_screens skin, enum screen_type screen,
struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen); struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen);
void gui_sync_skin_init(void); void gui_sync_skin_init(void);
void skin_unload_all(void);
bool skin_do_full_update(enum skinnable_screens skin, enum screen_type screen); bool skin_do_full_update(enum skinnable_screens skin, enum screen_type screen);
void skin_request_full_update(enum skinnable_screens skin); void skin_request_full_update(enum skinnable_screens skin);
void skin_request_update_locked(bool locked); void skin_request_update_locked(bool locked);

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 Nicolas Pennequin, Dan Everton, Matthias Mohr * Copyright (C) 2007 Nicolas Pennequin, Dan Everton, Matthias Mohr
* 2010 Jonathan Gordon * 2010 Jonathan Gordon
@ -1235,6 +1234,13 @@ static int parse_progressbar_tag(struct skin_element* element,
token->type = SKIN_TOKEN_VOLUMEBAR; token->type = SKIN_TOKEN_VOLUMEBAR;
else if (token->type == SKIN_TOKEN_BATTERY_PERCENT) else if (token->type == SKIN_TOKEN_BATTERY_PERCENT)
token->type = SKIN_TOKEN_BATTERY_PERCENTBAR; token->type = SKIN_TOKEN_BATTERY_PERCENTBAR;
else if (token->type == SKIN_TOKEN_PLAYLIST_ELAPSED_PERCENT)
{
#ifndef __PCTOOL__
wps_playlist_percent_enable(); /* enable scanning track lengths */
#endif
token->type = SKIN_TOKEN_PLAYLIST_PROGRESSBAR;
}
else if (token->type == SKIN_TOKEN_TUNER_RSSI) else if (token->type == SKIN_TOKEN_TUNER_RSSI)
token->type = SKIN_TOKEN_TUNER_RSSI_BAR; token->type = SKIN_TOKEN_TUNER_RSSI_BAR;
else if (token->type == SKIN_TOKEN_PEAKMETER_LEFT) else if (token->type == SKIN_TOKEN_PEAKMETER_LEFT)
@ -2417,6 +2423,7 @@ static int skin_element_callback(struct skin_element* element, void* data)
case SKIN_TOKEN_PROGRESSBAR: case SKIN_TOKEN_PROGRESSBAR:
case SKIN_TOKEN_VOLUME: case SKIN_TOKEN_VOLUME:
case SKIN_TOKEN_BATTERY_PERCENT: case SKIN_TOKEN_BATTERY_PERCENT:
case SKIN_TOKEN_PLAYLIST_ELAPSED_PERCENT:
case SKIN_TOKEN_PLAYER_PROGRESSBAR: case SKIN_TOKEN_PLAYER_PROGRESSBAR:
case SKIN_TOKEN_PEAKMETER_LEFT: case SKIN_TOKEN_PEAKMETER_LEFT:
case SKIN_TOKEN_PEAKMETER_RIGHT: case SKIN_TOKEN_PEAKMETER_RIGHT:

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id: skin_parser.c 26752 2010-06-10 21:22:16Z bieber $
* *
* Copyright (C) 2010 Jonathan Gordon * Copyright (C) 2010 Jonathan Gordon
* *
@ -84,8 +83,6 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer,
unsigned long refresh_type); unsigned long refresh_type);
static char* skin_buffer; static char* skin_buffer;
static bool defer_rendering;
static bool dirty[NB_SCREENS];
static inline struct skin_element* static inline struct skin_element*
get_child(OFFSETTYPE(struct skin_element**) children, int child) get_child(OFFSETTYPE(struct skin_element**) children, int child)
@ -230,6 +227,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_PLAYLIST_PERCENTBAR: case SKIN_TOKEN_PLAYLIST_PERCENTBAR:
case SKIN_TOKEN_SETTINGBAR: case SKIN_TOKEN_SETTINGBAR:
case SKIN_TOKEN_PROGRESSBAR: case SKIN_TOKEN_PROGRESSBAR:
case SKIN_TOKEN_PLAYLIST_PROGRESSBAR:
case SKIN_TOKEN_TUNER_RSSI_BAR: case SKIN_TOKEN_TUNER_RSSI_BAR:
case SKIN_TOKEN_LIST_SCROLLBAR: case SKIN_TOKEN_LIST_SCROLLBAR:
{ {
@ -843,29 +841,6 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
wps_display_images(gwps, &skin_viewport->vp); wps_display_images(gwps, &skin_viewport->vp);
} }
void skin_defer_rendering(bool deferred)
{
defer_rendering = deferred;
}
void skin_render_deferred(struct screen *display, struct viewport *vp)
{
if (defer_rendering)
return;
if (dirty[display->screen_type])
{
dirty[display->screen_type] = false;
display->set_viewport(NULL);
display->update();
}
else
{
display->set_viewport(vp);
display->update_viewport();
}
}
void skin_render(struct gui_wps *gwps, unsigned refresh_mode) void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
{ {
const int vp_is_appearing = (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE); const int vp_is_appearing = (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE);
@ -957,19 +932,14 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
skin_backdrop_show(data->backdrop_id); skin_backdrop_show(data->backdrop_id);
#endif #endif
dirty[display->screen_type] = defer_rendering;
if (((refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL)) if (((refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL))
{ {
defer_rendering = true;
/* If this is the UI viewport then let the UI know /* If this is the UI viewport then let the UI know
* to redraw itself */ * to redraw itself */
send_event(GUI_EVENT_NEED_UI_UPDATE, NULL); send_event(GUI_EVENT_NEED_UI_UPDATE, NULL);
defer_rendering = dirty[display->screen_type];
} }
/* Restore the default viewport */ /* Restore the default viewport */
display->set_viewport_ex(NULL, VP_FLAG_VP_SET_CLEAN); display->set_viewport_ex(NULL, VP_FLAG_VP_SET_CLEAN);
if (!defer_rendering)
display->update();
} }
static __attribute__((noinline)) static __attribute__((noinline))

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002-2007 Björn Stenberg * Copyright (C) 2002-2007 Björn Stenberg
* Copyright (C) 2007-2008 Nicolas Pennequin * Copyright (C) 2007-2008 Nicolas Pennequin
@ -42,10 +41,15 @@
#include "misc.h" #include "misc.h"
#include "led.h" #include "led.h"
#include "peakmeter.h" #include "peakmeter.h"
#include "splash.h"
/* Image stuff */ /* Image stuff */
#include "albumart.h" #include "albumart.h"
#include "playlist.h" #include "playlist.h"
#include "playback.h" #include "playback.h"
#include "metadata.h"
#include "crc32.h"
#include "file.h"
#include "core_alloc.h"
#include "tdspeed.h" #include "tdspeed.h"
#include "viewport.h" #include "viewport.h"
#include "tagcache.h" #include "tagcache.h"
@ -69,6 +73,10 @@
#include "option_select.h" #include "option_select.h"
#include "wps.h" #include "wps.h"
#if (CONFIG_STORAGE & STORAGE_ATA)
#include "ata.h" /* ata_disk_isssd() */
#endif
#define NOINLINE __attribute__ ((noinline)) #define NOINLINE __attribute__ ((noinline))
static const char* get_codectype(const struct mp3entry* id3) static const char* get_codectype(const struct mp3entry* id3)
@ -199,6 +207,167 @@ const char *get_cuesheetid3_token(struct wps_token *token, struct mp3entry *id3,
return NULL; return NULL;
} }
/* Whole-playlist progress by time (%pX). if track count exceeds MAX_TRACKS
* the tag falls back to position-based progress.
* The cache is keyed on the track count and a crc of the
* first, middle and last filenames, so a playlist change, same-length swap,
* or reshuffle causes a reload of the length data. */
#define PLPCT_MAX_TRACKS 500
static struct {
uint32_t sig; /* signature of the playlist to detect changed playlist or reshuffle*/
int amount;
bool nomem; /* allocation failed -> position fallback */
bool enabled; /* tag was parsed */
uint16_t track_mins[PLPCT_MAX_TRACKS];
unsigned long total_min;
} plpct = { .amount = -1, .enabled = false };
static uint32_t plpct_sig(void)
{
struct playlist_info *pl = playlist_get_current();
/* changes on any playlist swap or reshuffle */
return pl->seed ^ pl->first_index ^ pl->amount ^ pl->last_insert_pos ^ pl->dirlen
^ pl->created_tick ^ pl->max_playlist_size ^ pl->last_shuffled_start;
}
/* Equal-weight estimate (every track the same length)
scaled by 1000 as %pX is percent-only. */
static void plpct_estimate(const struct mp3entry *id3, unsigned long elapsed_ms,
int index, int amount,
unsigned long *elapsed_s, unsigned long *total_s)
{
unsigned long frac = 0; /* 0..1000 through the current track */
if (id3->length)
frac = MIN(1000UL, 1000UL * elapsed_ms / id3->length);
*elapsed_s = (unsigned long)(index - 1) * 1000 + frac;
*total_s = (unsigned long)amount * 1000;
}
void wps_playlist_percent_enable(void)
{
plpct.enabled = true;
}
void wps_playlist_percent_prepare(void)
{
if (!plpct.enabled)
return;
plpct.nomem = true;
int amount = playlist_amount();
plpct.sig = plpct_sig();
plpct.amount = amount;
if (amount <= 0 || amount > PLPCT_MAX_TRACKS) /* too many tracks abort */
{
return;
}
struct playlist_track_info info;
struct mp3entry *tmp = get_temp_mp3entry(NULL); /* shared scratch */
if (!tmp)
return;
#if (CONFIG_STORAGE & STORAGE_ATA) /* Harddrive estimate length based on filesize */
unsigned int last_afmt = AFMT_UNKNOWN;
uint32_t last_bps = 0;
#endif
for (int n = 0; n < amount; n++)
{
unsigned long secs = 0;
uint16_t mins = 0;
if (playlist_get_track_info(NULL, n, &info) < 0) /* couldn't get track filename abort */
goto abort;
int slot = info.display_index - 1;
if (slot < 0 || slot >= amount)
goto abort;
#if (CONFIG_STORAGE & STORAGE_ATA) /* Harddrive */
int fd = open(info.filename, O_RDONLY);
if (fd >= 0)
{
unsigned int afmt = probe_file_format(info.filename);
off_t size = filesize(fd);
if (size > 0)
{
if (afmt != last_afmt || last_bps == 0
|| amount <= 50 || (amount <= 250 && ata_disk_isssd())) // TODO tune this for harddisk devices
{
if (get_metadata_afmt(tmp, fd, info.filename, afmt,
METADATA_EXCLUDE_ID3_PATH | METADATA_EXCLUDE_NORMALIZE))
{
secs = tmp->length / 1000;
last_bps = (uint32_t)((uint64_t)size * 1000 / tmp->length);
last_afmt = afmt;
}
}
else /* file size only -- no per-track metadata parse */
{
secs = (unsigned long)((uint64_t)size / last_bps);
}
mins = MIN(MAX(1, (secs + 30) / 60), 65535ul);/* minutes, rounded to nearest */
}
close(fd);
}
#else
if (get_metadata_ex(tmp, -1, info.filename,
METADATA_EXCLUDE_ID3_PATH | METADATA_EXCLUDE_NORMALIZE))
{
secs = tmp->length / 1000;
mins = MIN(MAX(1, (secs + 30) / 60), 65535ul);/* minutes, rounded to nearest */
}
#endif
/* unreadable tracks count as zero length */
plpct.track_mins[slot] = mins;
}
plpct.total_min = 0;
for (int t = 0; t < plpct.amount; t++)
plpct.total_min += plpct.track_mins[t];
plpct.nomem = false;
abort:
get_temp_mp3entry(tmp); /* release scratch */
}
bool wps_get_playlist_percent(struct mp3entry *id3, unsigned long elapsed_ms,
unsigned long *elapsed_s, unsigned long *total_s)
{
int amount = playlist_amount();
int index = playlist_get_display_index(); /* 1-based */
if (!id3 || amount <= 0 || index < 1 || index > amount)
return false;
uint32_t sig = plpct_sig();
if (amount != plpct.amount || sig != plpct.sig)
{
splashf(0, ID2P(LANG_WAIT));
wps_playlist_percent_enable();
wps_playlist_percent_prepare();
}
/* error parsing playlist or more than MAX_TRACKS fall back to
position-based progress rather than blank */
if (plpct.nomem)
{
plpct_estimate(id3, elapsed_ms, index, amount, elapsed_s, total_s);
return true;
}
unsigned long before_min = 0;
for (int t = 0; t < index - 1; t++)
before_min += plpct.track_mins[t];
*elapsed_s = before_min * 60 + elapsed_ms / 1000;
*total_s = plpct.total_min * 60;
if (*elapsed_s > *total_s)
*elapsed_s = *total_s;
return true;
}
static const char* get_filename_token(struct wps_token *token, char* filename, static const char* get_filename_token(struct wps_token *token, char* filename,
char *buf, int buf_size) char *buf, int buf_size)
{ {
@ -334,6 +503,24 @@ const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
snprintf(buf, buf_size, "%lu", 100 * elapsed / length); snprintf(buf, buf_size, "%lu", 100 * elapsed / length);
return buf; return buf;
case SKIN_TOKEN_PLAYLIST_ELAPSED_PERCENT:
{
unsigned long pl_elapsed, pl_total;
if (!wps_get_playlist_percent(id3, elapsed,
&pl_elapsed, &pl_total)
|| pl_total == 0)
return NULL;
/* %pX always yields a value for a valid playlist now (the
equal-weight estimate until the scan finishes, then the exact
time-weighted figure), so it behaves like any percent tag;
%?pX<...> is true whenever the tag applies (a sized playlist). */
if (intval && limit == TOKEN_VALUE_ONLY)
*intval = 100 * pl_elapsed / pl_total;
snprintf(buf, buf_size, "%lu", 100 * pl_elapsed / pl_total);
return buf;
}
case SKIN_TOKEN_TRACK_STARTING: case SKIN_TOKEN_TRACK_STARTING:
{ {
unsigned long time = token->value.i * (HZ/TIMEOUT_UNIT); unsigned long time = token->value.i * (HZ/TIMEOUT_UNIT);
@ -510,7 +697,7 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
if (preset < 0) if (preset < 0)
preset += preset_count; preset += preset_count;
if (token->type == SKIN_TOKEN_PRESET_NAME) if (token->type == SKIN_TOKEN_PRESET_NAME)
snprintf(buf, buf_size, "%s", radio_get_preset_name(preset)); radio_get_preset_name(preset, buf, buf_size);
else if (token->type == SKIN_TOKEN_PRESET_FREQ) else if (token->type == SKIN_TOKEN_PRESET_FREQ)
format_freq_MHz(radio_get_preset_freq(preset), format_freq_MHz(radio_get_preset_freq(preset),
region_data->freq_step, buf, buf_size); region_data->freq_step, buf, buf_size);

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2009 - Jonathan Gordon * Copyright (C) 2009 - Jonathan Gordon
* *
@ -204,24 +203,11 @@ int skin_get_touchaction(struct gui_wps *gwps, int* edge_offset)
if (!gwps->id3) if (!gwps->id3)
break; break;
if (gevent.id == GESTURE_HOLD || audio_pre_ff_rewind();
gevent.id == GESTURE_DRAGSTART || gwps->id3->elapsed = gwps->id3->length / 1000 * (*edge_offset);
gevent.id == GESTURE_DRAG)
{
audio_pre_ff_rewind();
gwps->id3->elapsed = gwps->id3->length * (*edge_offset) / 1000;
}
else if (gevent.id == GESTURE_RELEASE)
{
audio_ff_rewind(gwps->id3->elapsed);
}
else
{
gwps->id3->elapsed = gwps->id3->length * (*edge_offset) / 1000;
audio_pre_ff_rewind();
audio_ff_rewind(gwps->id3->elapsed);
}
if (gevent.id == GESTURE_TAP || gevent.id == GESTURE_RELEASE)
audio_ff_rewind(gwps->id3->elapsed);
} break; } break;
case ACTION_TOUCH_VOLUME: case ACTION_TOUCH_VOLUME:

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2007 Nicolas Pennequin * Copyright (C) 2007 Nicolas Pennequin
* *
@ -429,6 +428,12 @@ const char *get_cuesheetid3_token(struct wps_token *token, struct mp3entry *id3,
int offset_tracks, char *buf, int buf_size); int offset_tracks, char *buf, int buf_size);
const char *get_id3_token(struct wps_token *token, struct mp3entry *id3, const char *get_id3_token(struct wps_token *token, struct mp3entry *id3,
char *filename, char *buf, int buf_size, int limit, int *intval); char *filename, char *buf, int buf_size, int limit, int *intval);
/* whole-playlist progress backing %pX (number and bar forms) */
bool wps_get_playlist_percent(struct mp3entry *id3, unsigned long elapsed_ms,
unsigned long *elapsed_s, unsigned long *total_s);
void wps_playlist_percent_enable(void);
void wps_playlist_percent_prepare(void);
#if CONFIG_TUNER #if CONFIG_TUNER
const char *get_radio_token(struct wps_token *token, int preset_offset, const char *get_radio_token(struct wps_token *token, int preset_offset,
char *buf, int buf_size, int limit, int *intval); char *buf, int buf_size, int limit, int *intval);

View file

@ -5,9 +5,9 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) Daniel Stenberg (2002) * Copyright (C) Daniel Stenberg (2002)
* Copyright (C) William Wilgus (2026)
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -39,109 +39,235 @@
static long progress_next_tick, talked_tick; static long progress_next_tick, talked_tick;
#define MAXLINES (LCD_HEIGHT/6) #define MAXLINES (LCD_HEIGHT/6)
#define MAXBUFFER 512
#ifndef BOOTLOADER
#if MEMORYSIZE > 8
#define MAXBUFFER MAX(1024, (LCD_WIDTH/SYSFONT_WIDTH) * MAXLINES + 1)
#else
#define MAXBUFFER MAX(512, (LCD_WIDTH/SYSFONT_WIDTH) * MAXLINES + 1)
#endif
#else
#define MAXBUFFER (512)
#endif
#define RECT_SPACING 3 #define RECT_SPACING 3
#define SPLASH_MEMORY_INTERVAL (HZ) #define SPLASH_MEMORY_INTERVAL (HZ)
/* splash_internal does the actual drawing of the splash box and text
* each call to splash remembers the max size and will not shrink the splash box
* until it is reset by an activity change or \f at the beginning of a string
*
* splash supports several escape sequences ("\n\t\f\r\v\b")
* '\n' (new line) indicates the end of a line of text and starts a new one
* ("\n\n" will end a line and create a blank line)
* '\n' as the first character of the text will create a blank line
*
* '\t' (tab) starts a new line and adds several spaces to the beginning of the
* new line it also left/right justifies the splash text box
* (RTL languages will right justify)
* '\t' as the last character of the text will left/right justify
* without adding any tabs to the text output
*
* '\f' (form feed) as the first character of the text will reset the text box
* width and height
*
* Others:
* '\f', \r', '\v' '\b' will be treated as a breaking space character
* they will not be displayed as output and multiple sequences will be
* treated as a single character
* eg. "\b\v\f\r" will break the line but only once and will not show as a space
* where as "\n\n" will break a line and add a blank line
* "\t\t" would break a line and add a total of 4 spaces to the next line
*/
static bool splash_internal(struct screen * screen, const char *fmt, va_list ap, static bool splash_internal(struct screen * screen, const char *fmt, va_list ap,
struct viewport *vp, int addl_lines) struct viewport *vp, int addl_lines)
{ {
static int max_width[NB_SCREENS] = {2*RECT_SPACING}; static const char matchstr[] = "\r\n\f\v\t\b";
static int max_width[NB_SCREENS] = {0};
static int max_height[NB_SCREENS] = {0};
#ifndef BOOTLOADER #ifndef BOOTLOADER
static char splash_buf[MAXBUFFER] = {0};
static enum current_activity last_act = ACTIVITY_UNKNOWN; static enum current_activity last_act = ACTIVITY_UNKNOWN;
enum current_activity act = get_current_activity(); enum current_activity act = get_current_activity();
if (last_act != act) /* changed activities reset max_width */ if (last_act != act) /* changed activities reset width / height */
{ {
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
max_width[i] = 2*RECT_SPACING; {
max_width[i] = 0;
max_height[i] = 0;
}
last_act = act; last_act = act;
} }
#else /*def BOOTLOADER*/
char splash_buf[MAXBUFFER] = {0}; /* on the stack for the bootloader */
#endif #endif
/* prevent screen artifacts by keeping the max width seen */
int min_width = max_width[screen->screen_type];
char splash_buf[MAXBUFFER];
struct splash_lines { struct splash_lines {
const char *str; const char *str;
size_t len; uint16_t x;
uint16_t len;
} lines[MAXLINES]; } lines[MAXLINES];
const char *next; memset(lines, 0, sizeof(lines));
const char *lastbreak = NULL;
const char *store = NULL; char *buf = splash_buf;
const char *next, *store;
bool has_tabs = false;
int line = 0; int line = 0;
int x = 0; int x = 0, w = 0;
int y, i; int y;
int space_w, w, chr_h; int space_w, chr_h;
int width, height; int width = vp->width - RECT_SPACING*2;
int maxw = min_width - 2*RECT_SPACING; int height = vp->height;
/* prevent screen artifacts by keeping the max width / height seen */
int maxw = max_width[screen->screen_type];
int maxh = max_height[screen->screen_type];
int fontnum = vp->font; int fontnum = vp->font;
char lastbrkchr; size_t next_len;
size_t len, next_len;
const char matchstr[] = "\r\n\f\v\t ";
font_getstringsize(" ", &space_w, &chr_h, fontnum);
y = chr_h + (addl_lines * chr_h);
vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap); font_getstringsize(" ", &space_w, &chr_h, fontnum);
y = (addl_lines * chr_h);
int res = vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
va_end(ap); va_end(ap);
/* break splash string into display lines, doing proper word wrap */ if (res <= 0 || width < space_w || height < chr_h)
next = strptokspn_r(splash_buf, matchstr, &next_len, &store);
if (!next)
return false; /* nothing to display */
lines[line].len = next_len;
lines[line].str = next;
while (true)
{ {
w = font_getstringnsize(next, next_len, NULL, NULL, fontnum); #ifdef SIMULATOR
if (lastbreak) if (res <= 0)
printf("ERROR: %s %d\n", __func__, res);
else
printf("WARNING: %s vp too small\n", __func__);
#endif
return false; /* nothing to display */
}
const char *lastbreak = splash_buf;
if (*lastbreak == '\f') /* only as first character - Reset splash box size */
{
maxw = 0;
maxh = 0;
}
while(true) /* break splash string into display lines, doing proper word wrap */
{
#ifndef BOOTLOADER
while (*lastbreak != '\0') /* handle escape chars*/
{ {
len = next - lastbreak; switch (*lastbreak) /* all chars in matchstr */
int next_w = len * space_w;
if (x + next_w + w > vp->width - RECT_SPACING*2 || lastbrkchr != ' ')
{ /* too wide, or control character wrap */
if (x > maxw)
maxw = x;
if ((y + chr_h * 2 > vp->height) || (line >= (MAXLINES-1)))
break; /* screen full or out of lines */
x = 0;
y += chr_h;
/* split when it fits since we didn't find a valid token to break on */
size_t nl = next_len;
while (w > vp->width && --nl > 0)
w = font_getstringnsize(next, nl, NULL, NULL, fontnum);
if (nl > 1 && nl != next_len)
{
next_len = nl;
store = next + nl; /* move the start pos for the next token read */
}
lines[++line].len = next_len;
lines[line].str = next;
}
else
{ {
/* restore & calculate spacing */ case '\t': /*fallthrough*/
lines[line].len += next_len + 1; has_tabs = true; /* left justify (right justify for RTL)*/
x += next_w; case '\n':
{
if (lines[line].len > 0 || *lastbreak != '\t')
{
x += w;
if (x > maxw)
maxw = x;
x = 0;
y += chr_h;
if (y >= height || line >= MAXLINES-1)
{
break; /* out of lines */
}
line++;
}
/* /t as last char left justifies only */
if (lastbreak[0] == '\t' && lastbreak[1] != '\0')
{
/* add offset for tab */
lines[line].x += space_w * 2;
x += space_w * 2;
}
break;
}
case '\b': /*fallthrough*/
case '\f': /*fallthrough*/
case '\v': /*fallthrough*/
case '\r':
break; /* acts the same as a space character */
default: /* No valid break chars */
lastbreak = " "; /* exit */
break;
} }
lastbreak++;
} }
x += w; #endif
if (lines[line].len > 0)
lastbreak = next + next_len; {
lastbrkchr = *lastbreak; x += w;
next = strptokspn_r(NULL, matchstr, &next_len, &store);
if (!next)
{ /* no more words */
if (x > maxw) if (x > maxw)
maxw = x; maxw = x;
x = 0;
y += chr_h;
if (y >= height || line >= MAXLINES-1)
{
if (y > maxh)
maxh = y;
break; /* out of lines */
}
line++;
}
next = strptokspn_r(buf, matchstr, &next_len, &store);
if (!next)
{
x += w;
if (x > maxw)
maxw = x;
if (y > maxh)
maxh = y;
break; break;
} }
buf = NULL; /* uses store for continuation */
lines[line].str = next;
lines[line].len = next_len;
w = font_getstringnsize(next, next_len, NULL, NULL, fontnum);
if (w > width)
{
const char *nxp, *nx = next;
int nw, newlen;
int oldlen = next_len;
while (nx - next < oldlen) /* try to split at a space char */
{
nxp = nx;
nx++;
if (*nxp != ' ' && *nx != '\0') /* split on space or EOL */
continue;
newlen = nxp - next;
nw = font_getstringnsize(next, newlen, NULL, NULL, fontnum);
if (nw > width)
{
/* is next word larger than max width & room left on this line? */
if (nw - w > width && w + space_w * 8 < width)
w = nw;
break;
}
w = nw;
next_len = newlen;
store = nx; /* we want to skip the space char */
}
if (w > width) /* split when it fits */
{
w = width;
next_len = font_measurestring(next, oldlen, w, &w, NULL, fontnum);
store = next + next_len;
}
lines[line].len = next_len;
}
lastbreak = next + next_len;
} }
/* prepare viewport /* prepare viewport
@ -151,22 +277,25 @@ static bool splash_internal(struct screen * screen, const char *fmt, va_list ap,
screen->scroll_stop(); screen->scroll_stop();
width = maxw + 2*RECT_SPACING; width = maxw + 2*RECT_SPACING;
height = y + 2*RECT_SPACING; height = maxh + 2*RECT_SPACING;
if (width > vp->width) if (width > vp->width)
width = vp->width; width = vp->width;
if (height > vp->height) if (height > vp->height)
height = vp->height; height = vp->height;
/* center the vp in the screen area */
vp->x += (vp->width - width) / 2; vp->x += (vp->width - width) / 2;
vp->y += (vp->height - height) / 2; vp->y += (vp->height - height) / 2;
vp->width = width; vp->width = width;
vp->height = height; vp->height = height;
if (!has_tabs)
vp->flags |= VP_FLAG_ALIGN_CENTER;
/* prevent artifacts by locking to max width observed on repeated calls */ /* prevent artifacts by locking to max width & height observed on repeated calls */
max_width[screen->screen_type] = width; max_width[screen->screen_type] = width - 2*RECT_SPACING;
max_height[screen->screen_type] = height - 2*RECT_SPACING;
vp->flags |= VP_FLAG_ALIGN_CENTER;
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
unsigned fg = 0, bg = 0; unsigned fg = 0, bg = 0;
bool broken = false; bool broken = false;
@ -203,11 +332,22 @@ static bool splash_internal(struct screen * screen, const char *fmt, va_list ap,
screen->draw_border_viewport(); screen->draw_border_viewport();
/* center y within the available splash box */
if (y < maxh)
y = (maxh - y) / 2;
else
y = RECT_SPACING;
/* print the message to screen */ /* print the message to screen */
for(i = 0, y = RECT_SPACING; i <= line; i++, y+= chr_h) for(int i = 0; i < line && y < height; i++, y+= chr_h)
{ {
screen->putsxyf(0, y, "%.*s", lines[i].len, lines[i].str); if (lines[i].len > 0)
{
x = lines[i].x;
screen->putsxyf(x, y, "%.*s", lines[i].len, lines[i].str);
}
} }
return true; /* needs update */ return true; /* needs update */
} }

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *
@ -29,6 +28,9 @@
* Puts a splash message centered on all the screens for a given period * Puts a splash message centered on all the screens for a given period
* - ticks : how long the splash is displayed (in rb ticks) * - ticks : how long the splash is displayed (in rb ticks)
* - fmt : what to say *printf style * - fmt : what to say *printf style
* /f at the beginning of a string will reset the max width and height seen
* /n will end a line /n/n will add a blank line
* /t will start a new line and indent the string on that line
*/ */
extern void splashf(int ticks, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3); extern void splashf(int ticks, const char *fmt, ...) ATTRIBUTE_PRINTF(2, 3);

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2009 Thomas Martitz * Copyright (C) 2009 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2009 Thomas Martitz * Copyright (C) 2009 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) Robert E. Hak (2002), Linus Nielsen Feltzing (2002) * Copyright (C) Robert E. Hak (2002), Linus Nielsen Feltzing (2002)
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Björn Stenberg * Copyright (C) 2002 Björn Stenberg
* *
@ -53,55 +52,63 @@
#include "ata_mmc.h" #include "ata_mmc.h"
#endif #endif
#ifdef USB_ENABLE_HID struct usb_screen_vps_t
int usb_keypad_mode;
static bool usb_hid;
#endif
#ifndef SIMULATOR
static int handle_usb_events(void)
{ {
#if (CONFIG_STORAGE & STORAGE_MMC) struct viewport parent;
int next_update=0; struct viewport logo;
#endif /* STORAGE_MMC */ #ifndef USB_ENABLE_HID
};
#else
struct viewport title;
};
/* Don't return until we get SYS_USB_DISCONNECTED or SYS_TIMEOUT */ int usb_keypad_mode;
static void draw_usb_keypad_mode(struct viewport *title)
{
struct screen *screen = &screens[SCREEN_MAIN];
struct viewport *last_vp = screen->set_viewport(title);
screen->clear_viewport();
title->flags |= VP_FLAG_ALIGN_CENTER;
if (title->width > 1)
screen->puts_scroll(0, 0, str(keypad_mode_name_get(usb_keypad_mode)));
screen->set_viewport(last_vp);
}
#endif /* USB_ENABLE_HID */
static void handle_usb_events(struct viewport *title)
{
#if (CONFIG_STORAGE & STORAGE_MMC) && !defined(SIMULATOR)
int next_update = 0;
#endif /* STORAGE_MMC */
int button;
/* Don't return until we get SYS_USB_DISCONNECTED */
while(1) while(1)
{ {
int button; #ifndef USB_ENABLE_HID
#ifdef USB_ENABLE_HID (void)title;
if (usb_hid) #else
if (global_settings.usb_hid)
{ {
button = get_hid_usb_action(); button = get_hid_usb_action();
/* On mode change, we need to refresh the screen */
if (button == ACTION_USB_HID_MODE_SWITCH_NEXT || if (button == ACTION_USB_HID_MODE_SWITCH_NEXT ||
button == ACTION_USB_HID_MODE_SWITCH_PREV) button == ACTION_USB_HID_MODE_SWITCH_PREV)
{ draw_usb_keypad_mode(title);
break;
}
} }
else else
#endif #endif
{ {
button = button_get_w_tmo(HZ/2);
/* hid emits the event in get_action */ /* hid emits the event in get_action */
send_event(GUI_EVENT_ACTIONUPDATE, NULL); send_event(GUI_EVENT_ACTIONUPDATE, NULL);
button = button_get_w_tmo(HZ/2);
} }
if (button == SYS_USB_DISCONNECTED)
return;
if (button == SYS_CHARGER_DISCONNECTED)
reset_runtime();
switch(button) /* USB-MMC bridge can report activity */
{ #if (CONFIG_STORAGE & STORAGE_MMC) && !defined(SIMULATOR)
case SYS_USB_DISCONNECTED:
return 1;
case SYS_CHARGER_DISCONNECTED:
reset_runtime();
break;
case SYS_TIMEOUT:
break;
}
#if (CONFIG_STORAGE & STORAGE_MMC) /* USB-MMC bridge can report activity */
if(TIME_AFTER(current_tick,next_update)) if(TIME_AFTER(current_tick,next_update))
{ {
if(usb_inserted()) { if(usb_inserted()) {
@ -111,21 +118,7 @@ static int handle_usb_events(void)
} }
#endif /* STORAGE_MMC */ #endif /* STORAGE_MMC */
} }
return 0;
} }
#endif /* SIMULATOR */
#define MODE_NAME_LEN 32
struct usb_screen_vps_t
{
struct viewport parent;
struct viewport logo;
#ifdef USB_ENABLE_HID
struct viewport title;
#endif
};
static void usb_screen_fix_viewports(struct screen *screen, static void usb_screen_fix_viewports(struct screen *screen,
struct usb_screen_vps_t *usb_screen_vps) struct usb_screen_vps_t *usb_screen_vps)
@ -178,7 +171,7 @@ static void usb_screen_fix_viewports(struct screen *screen,
logo->height = logo_height; logo->height = logo_height;
#ifdef USB_ENABLE_HID #ifdef USB_ENABLE_HID
if (usb_hid) if (global_settings.usb_hid)
{ {
struct viewport *title = &usb_screen_vps->title; struct viewport *title = &usb_screen_vps->title;
int char_height = font_get(parent->font)->height; int char_height = font_get(parent->font)->height;
@ -211,11 +204,9 @@ static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
&bm_remote_usblogo, &bm_remote_usblogo,
#endif #endif
}; };
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
{ {
struct screen *screen = &screens[i]; struct screen *screen = &screens[i];
struct usb_screen_vps_t *usb_screen_vps = &usb_screen_vps_ar[i]; struct usb_screen_vps_t *usb_screen_vps = &usb_screen_vps_ar[i];
struct viewport *parent = &usb_screen_vps->parent; struct viewport *parent = &usb_screen_vps->parent;
struct viewport *logo = &usb_screen_vps->logo; struct viewport *logo = &usb_screen_vps->logo;
@ -223,29 +214,14 @@ static void usb_screens_draw(struct usb_screen_vps_t *usb_screen_vps_ar)
last_vp = screen->set_viewport(parent); last_vp = screen->set_viewport(parent);
screen->clear_viewport(); screen->clear_viewport();
screen->backlight_on(); screen->backlight_on();
screen->set_viewport(logo); screen->set_viewport(logo);
screen->bmp(logos[i], 0, 0); screen->bmp(logos[i], 0, 0);
if (i == SCREEN_MAIN)
{
#ifdef USB_ENABLE_HID
if (usb_hid)
{
char modestring[100];
screen->set_viewport(&usb_screen_vps->title);
usb_screen_vps->title.flags |= VP_FLAG_ALIGN_CENTER;
snprintf(modestring, sizeof(modestring), "%s: %s",
str(LANG_USB_KEYPAD_MODE),
str(keypad_mode_name_get(usb_keypad_mode)));
screen->puts_scroll(0, 0, modestring);
}
#endif /* USB_ENABLE_HID */
}
screen->set_viewport(parent);
screen->set_viewport(last_vp); screen->set_viewport(last_vp);
screen->update_viewport();
} }
#ifdef USB_ENABLE_HID
if (global_settings.usb_hid)
draw_usb_keypad_mode(&usb_screen_vps_ar[SCREEN_MAIN].title);
#endif
} }
void gui_usb_screen_run(bool early_usb, intptr_t seqnum) void gui_usb_screen_run(bool early_usb, intptr_t seqnum)
@ -258,6 +234,7 @@ void gui_usb_screen_run(bool early_usb, intptr_t seqnum)
#endif #endif
struct usb_screen_vps_t usb_screen_vps_ar[NB_SCREENS]; struct usb_screen_vps_t usb_screen_vps_ar[NB_SCREENS];
struct viewport *title = NULL;
#if defined HAVE_TOUCHSCREEN #if defined HAVE_TOUCHSCREEN
enum touchscreen_mode old_mode = touchscreen_get_mode(); enum touchscreen_mode old_mode = touchscreen_get_mode();
@ -269,8 +246,10 @@ void gui_usb_screen_run(bool early_usb, intptr_t seqnum)
push_current_activity(ACTIVITY_USBSCREEN); push_current_activity(ACTIVITY_USBSCREEN);
#ifdef USB_ENABLE_HID #ifdef USB_ENABLE_HID
usb_hid = global_settings.usb_hid;
usb_keypad_mode = global_settings.usb_keypad_mode; usb_keypad_mode = global_settings.usb_keypad_mode;
title = &usb_screen_vps_ar[SCREEN_MAIN].title;
#else
title = NULL;
#endif #endif
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
@ -296,33 +275,13 @@ void gui_usb_screen_run(bool early_usb, intptr_t seqnum)
/* The font system leaves the .fnt fd's open, so we need for force close them all */ /* The font system leaves the .fnt fd's open, so we need for force close them all */
font_disable_all(); font_disable_all();
} }
usb_acknowledge(SYS_USB_CONNECTED_ACK, seqnum); usb_acknowledge(SYS_USB_CONNECTED_ACK, seqnum);
usb_screens_draw(usb_screen_vps_ar);
while (1) handle_usb_events(title);
{
usb_screens_draw(usb_screen_vps_ar);
#ifdef SIMULATOR
if (button_get_w_tmo(HZ/2))
break;
send_event(GUI_EVENT_ACTIONUPDATE, NULL);
#else
if (handle_usb_events())
break;
#endif /* SIMULATOR */
}
FOR_NB_SCREENS(i)
{
const struct viewport* vp = NULL;
#if defined(USB_ENABLE_HID) #if defined(USB_ENABLE_HID)
vp = usb_hid ? &usb_screen_vps_ar[i].title : NULL; if (global_settings.usb_hid)
#endif screens[SCREEN_MAIN].scroll_stop_viewport(title);
if (vp)
screens[i].scroll_stop_viewport(vp);
}
#ifdef USB_ENABLE_HID
if (global_settings.usb_keypad_mode != usb_keypad_mode) if (global_settings.usb_keypad_mode != usb_keypad_mode)
{ {
global_settings.usb_keypad_mode = usb_keypad_mode; global_settings.usb_keypad_mode = usb_keypad_mode;

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Björn Stenberg * Copyright (C) 2002 Björn Stenberg
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2008 by Jonathan Gordon * Copyright (C) 2008 by Jonathan Gordon
* *
@ -83,7 +82,7 @@ static void evt_toggle(bool enable, unsigned short id,
static void toggle_events(bool enable) static void toggle_events(bool enable)
{ {
evt_toggle(enable, GUI_EVENT_ACTIONUPDATE, viewportmanager_redraw); evt_toggle(enable, GUI_EVENT_ACTIONREDRAW, viewportmanager_redraw);
evt_toggle(enable, PLAYBACK_EVENT_TRACK_CHANGE, do_sbs_update_callback); evt_toggle(enable, PLAYBACK_EVENT_TRACK_CHANGE, do_sbs_update_callback);
evt_toggle(enable, PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, do_sbs_update_callback); evt_toggle(enable, PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, do_sbs_update_callback);
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
@ -113,14 +112,14 @@ static void toggle_theme(enum screen_type screen, bool force)
if (!sb_get_persistent_title(i)) if (!sb_get_persistent_title(i))
sb_set_title_text(NULL, Icon_NOICON, i); sb_set_title_text(NULL, Icon_NOICON, i);
} }
skinlist_set_cfg(screen, NULL);
toggle_events(enable_event); toggle_events(enable_event);
if (is_theme_enabled(screen)) if (is_theme_enabled(screen))
{ {
last_vp = screens[screen].set_viewport(NULL); last_vp = screens[screen].set_viewport(NULL);
bool first_boot = theme_stack_top[screen] == 0; bool first_boot = theme_stack_top[screen] == 0;
/* remove the left overs from the previous screen. /* Remove the left overs from the previous screen */
* could cause a tiny flicker. Redo your screen code if that happens */
#ifdef HAVE_BACKDROP_IMAGE #ifdef HAVE_BACKDROP_IMAGE
skin_backdrop_show(sb_get_backdrop(screen)); skin_backdrop_show(sb_get_backdrop(screen));
#endif #endif
@ -154,9 +153,7 @@ static void toggle_theme(enum screen_type screen, bool force)
} }
intptr_t force = first_boot?0:1; intptr_t force = first_boot?0:1;
skin_defer_rendering(true); send_event(GUI_EVENT_ACTIONREDRAW, (void*)force);
send_event(GUI_EVENT_ACTIONUPDATE, (void*)force);
skin_defer_rendering(false);
if (!first_boot) if (!first_boot)
sb_skin_force_next_update(); sb_skin_force_next_update();
} }
@ -166,7 +163,7 @@ static void toggle_theme(enum screen_type screen, bool force)
screens[screen].backdrop_show(NULL); screens[screen].backdrop_show(NULL);
#endif #endif
screens[screen].scroll_stop(); screens[screen].scroll_stop();
skinlist_set_cfg(screen, NULL); skin_is_dirty(screen); /* remove dirty flag */
} }
/* let list initialize viewport in case viewport dimensions is changed. */ /* let list initialize viewport in case viewport dimensions is changed. */
send_event(GUI_EVENT_THEME_CHANGED, NULL); send_event(GUI_EVENT_THEME_CHANGED, NULL);
@ -219,10 +216,16 @@ static void viewportmanager_redraw(unsigned short id, void* data)
{ {
(void)id; (void)id;
FOR_NB_SCREENS(i) FOR_NB_SCREENS(i)
{
if (is_theme_enabled(i)) if (is_theme_enabled(i))
sb_skin_update(i, NULL != data); sb_skin_update(i, NULL != data);
} }
static void viewportmanager_update(unsigned short id, void* data)
{
viewportmanager_redraw(id, data);
FOR_NB_SCREENS(i)
if (skin_is_dirty(i))
screens[i].update();
} }
void viewportmanager_init(void) void viewportmanager_init(void)
@ -233,6 +236,7 @@ void viewportmanager_init(void)
/* We always want the theme enabled by default... */ /* We always want the theme enabled by default... */
viewportmanager_theme_enable(i, true, NULL); viewportmanager_theme_enable(i, true, NULL);
} }
add_event(GUI_EVENT_ACTIONUPDATE, viewportmanager_update);
} }
void viewportmanager_theme_changed(const int which) void viewportmanager_theme_changed(const int which)

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2008 by Jonathan Gordon * Copyright (C) 2008 by Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Jerome Kuptz * Copyright (C) 2002 Jerome Kuptz
* *
@ -533,11 +532,7 @@ static void gwps_leave_wps(bool theme_enabled)
viewports drawn by the WPS. May need further thought... */ viewports drawn by the WPS. May need further thought... */
struct wps_data *sbs = skin_get_gwps(CUSTOM_STATUSBAR, i)->data; struct wps_data *sbs = skin_get_gwps(CUSTOM_STATUSBAR, i)->data;
if (gwps->data->use_extra_framebuffer && sbs->use_extra_framebuffer) if (gwps->data->use_extra_framebuffer && sbs->use_extra_framebuffer)
{
skin_defer_rendering(true);
skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_ALL); skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_ALL);
skin_defer_rendering(false);
}
#endif #endif
viewportmanager_theme_undo(i, skin_has_sbs(gwps)); viewportmanager_theme_undo(i, skin_has_sbs(gwps));
} }
@ -599,11 +594,7 @@ static void gwps_enter_wps(bool theme_enabled)
skin_backdrop_show(gwps->data->backdrop_id); skin_backdrop_show(gwps->data->backdrop_id);
#endif #endif
display->clear_display(); display->clear_display();
if (skin_has_sbs(gwps))
skin_defer_rendering(true);
skin_update(WPS, i, SKIN_REFRESH_ALL); skin_update(WPS, i, SKIN_REFRESH_ALL);
skin_defer_rendering(false);
} }
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
gwps = skin_get_gwps(WPS, SCREEN_MAIN); gwps = skin_get_gwps(WPS, SCREEN_MAIN);
@ -611,7 +602,7 @@ static void gwps_enter_wps(bool theme_enabled)
if (gwps->data->touchregions < 0) if (gwps->data->touchregions < 0)
touchscreen_set_mode(TOUCHSCREEN_BUTTON); touchscreen_set_mode(TOUCHSCREEN_BUTTON);
#endif #endif
/* force statusbar/skin update since we just cleared the whole screen */ /* Screen was cleared, so redraw SBS if enabled, and update screen */
send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
} }
@ -806,9 +797,10 @@ long gui_wps_show(void)
case ACTION_WPS_HOTKEY: case ACTION_WPS_HOTKEY:
{ {
hotkey = true; hotkey = true;
if (!global_settings.hotkey_wps) int act = HK_CTX_GET(0, global_settings.context_wps);
if (act == HOTKEY_OFF)
break; break;
if (get_hotkey(global_settings.hotkey_wps)->flags & HOTKEY_FLAG_NOSBS) if (get_hotkey(act)->flags & HOTKEY_FLAG_NOSBS)
{ {
/* leave WPS without re-enabling theme */ /* leave WPS without re-enabling theme */
theme_enabled = false; theme_enabled = false;
@ -844,7 +836,7 @@ long gui_wps_show(void)
{ {
restore_theme(); restore_theme();
theme_enabled = false; theme_enabled = false;
open_plugin_run(ID2P(LANG_OPEN_PLUGIN_SET_WPS_CONTEXT_PLUGIN)); open_plugin_run(ID2P(LANG_ONPLAY_MENU_TITLE));
} }
restore = true; restore = true;

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2002 Björn Stenberg * Copyright (C) 2002 Björn Stenberg
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2005 by Kevin Ferrare * Copyright (C) 2005 by Kevin Ferrare
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Jonathan Gordon * Copyright (C) 2010 Jonathan Gordon
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Thomas Martitz * Copyright (C) 2010 Thomas Martitz
* *

View file

@ -5,7 +5,6 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/ * \/ \/ \/ \/ \/
* $Id$
* *
* Copyright (C) 2010 Thomas Martitz * Copyright (C) 2010 Thomas Martitz
* *

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