Compare commits

...

59 commits

Author SHA1 Message Date
Solomon Peachy
481cc70fe0 libc: Add an implementation of strtol/strtoul and export it via plugins
These were lifted from the lua plugin.

sdl, doom, puzzles updated to use the exported version

todo: lua, maybe?
also: convert uses of atoi [back] to strtol

Change-Id: I5a1ebbe8d8c99349e594ab9bbbce474e7645b4e9
2025-12-06 09:04:36 -05:00
William Wilgus
32edbd430d plugins - Add PLUGIN_GOTO_ROOT - lua add PLUGIN_GOTO_ROOT and PLUGIN_ERROR
Change-Id: I018f68685877700571aa7687428cfdda436a0294
2025-12-05 12:03:58 -05:00
William Wilgus
7b7d9a384a scrobbler / log viewer allow cancel button long press to exit plugin
some devices will shutdown before the button repeat even occurs so unfortunately
it still might not work on some devices (sansa clip series)

Change-Id: I1c5eda6c5a97887f69e1fbd0ada39cce01db352b
2025-12-05 12:03:58 -05:00
Aidan MacDonald
9d7af45122 touchscreen: Allow progress bars to be used in the .sbs
Progress bars (for seeking in the current track) can now be
used on the .sbs skin.

Change-Id: I42377b16036ca4ca8017ecfa2bdab08bd0fa1e64
2025-12-05 12:02:53 +00:00
Aidan MacDonald
9b5b9d6a6d touchscreen: Allow volume bars to be used in the .sbs
Move the volume bar input handling to skin_touchsupport.c so
volume bars can be used in the .sbs as well as the .wps skin.

Change-Id: I018fa1c84f93b64d676b68e3bea63ddb9141e492
2025-12-05 12:02:53 +00:00
Aidan MacDonald
e3e0c7b73c skin engine: Fix some user-created touch regions being suppressed
Fix the heuristic used for detecting a touch-enabled theme.
The old method assumes that volume bar and progress bar tags
are always auto-created, but this might not be true. Instead,
mark regions that originate from a %T tag as user-created and
check for those.

Change-Id: Iec732d299a2b4e298bef8069a68ff94e3b642703
2025-12-05 12:02:53 +00:00
Aidan MacDonald
1816667937 touchscreen: Allow bar tag touchregions to be labeled
This is necessary if you want to detect touches on the bar region
using %Tl conditionals. Suppressing the auto-created region and then
creating one manually using %T doesn't give exactly the same results
because user-defined touch regions can't yet specify padding.

Change-Id: I2f4bde8eb56ba89645c72f3cc9d4b2355b934abd
2025-12-05 12:02:53 +00:00
Aidan MacDonald
b781beecf5 manual: document touch area labels for %T and %Tl tags
It's been possible to label touch areas since the v3.9 stable
release, but it was never documented in the manual, only the wiki.

Change-Id: I6b92ff1d19369c105dc3a90aa04f8763f18a4214
2025-12-05 12:02:50 +00:00
Solomon Peachy
afe128f4cc arm: Profile/variation detection improvements
* Detection of 64-bit Arm v8-a
 * Proper detection of integer division support
   * always on v7-m, v8-a, v9-a, v8-m.main
   * sometimes on v7-a, v7-r, v8-r
   * never on v8-m.base v6-m, v6 and older "classic"
   * tl;dr: Rely on toolchain preprocessor definition

For the most part these additional variations won't acutally work
for native target builds, but sane -A detection is needed for
"local" builds now. -R detection is left out as it's not likely
to matter.

Change-Id: I8f6a52edc4d14490fc00e2f487406eca701eef02
2025-12-04 20:43:30 -05:00
Solomon Peachy
6d39bf5e48 manual: Update %Tp documentation
It returns 't' only if a touchscreen is present and set to pointer mode

Change-Id: Ia72c0ea0ceea78fc53327a4c6d6cb25436ef572c
2025-12-04 20:33:57 -05:00
Aidan MacDonald
910a39af27 touchscreen: Evaluate %Tp tag only if pointing mode is enabled
Simply knowing that a touchscreen is present isn't that useful for
themes. Having %Tp evaluate as true when in pointing mode and false
in 3x3 mode is better. For example, themes can change their layout
or hide touch UI elements when in 3x3 mode, or show a status icon.

Although a similar effect can be achieved with the %St tag it's
simpler to use %Tp for this purpose -- it can report the current
mode, not just the user preference.

Change-Id: Ie343c105970dca11864fa44c6a091ed8e9e35b3d
2025-12-04 19:36:51 -05:00
Aidan MacDonald
02ad19c959 touchscreen: Fix seeking to end of track in WPS
Seeking to the very end of the track with the touchscreen caused
rapid skipping through the playlist because each touch event
generates a separate seek operation, kind of like rapidly pressing
a physical button. Fix this bug by executing the seek operation
only for the release event.

Change-Id: Ic1080065a68e7cc2ba98e2f27293c954f2ec8fb2
2025-12-04 19:36:19 -05:00
Aidan MacDonald
010d22ed29 touchscreen: Port skin engine to gesture API
Use the gesture API for improved reliability.

Change-Id: I44c4e124132605ecf4f1499f97defd7b4b2d78e8
2025-12-04 19:00:38 -05:00
Aidan MacDonald
0f99defe1f touchscreen: Port quickscreen to gesture API
Use the gesture API to improve reliability, and allow press and hold
to repeatedly increment or decrement a value like on button targets.

Change-Id: Ic01b7a0802c3dec9f1534f5dd11e006b28a875b6
2025-12-04 17:29:54 -05:00
Aidan MacDonald
94468f693f touchscreen: Port yes/no screen to gesture API
Use the gesture API in the yes/no screen to suppress bogus
touches and generally improve reliability.

Change-Id: I44adf95255f07d81188fd249dc00a91519ca7b99
2025-12-04 17:29:54 -05:00
Aidan MacDonald
67233114f7 touchscreen: Port list code to gesture API
Make use of the new gesture API to overhaul list touch support.
This should fix most of the annoyances with touch navigation in
menus and make the touchscreen easier to use.

Change-Id: Ied300947fcf755e2810e9348496ed86eaf620669
2025-12-04 16:22:26 -05:00
Aidan MacDonald
e2363b0e2c plugins: Add touch API to plugin API and revamp touchscreen test
Change-Id: Iefb658693b03e0cda43e2a9fc93086485e790b4e
2025-12-04 09:01:51 -05:00
Aidan MacDonald
8aae723853 touchscreen: Integrate gesture API with action system
Provide a default gesture object in the action system which will
be kept up to date with touch events automatically. This reduces
the boilerplate needed to handle touch input.

Change-Id: I76f51ac2c3e3a0da204707d62e91a175c5f8c76a
2025-12-04 08:14:28 -05:00
Aidan MacDonald
bb1e0b48a0 touchscreen: Add gesture velocity helper
Add a helper for computing the motion velocity during a touchscreen press.

Change-Id: I1ef7452ba9815897fd3ec01f8980c89aeef5418f
2025-12-04 08:14:28 -05:00
Aidan MacDonald
7aa823215b touchscreen: Add gesture recognition API
Add a basic gesture API which can detect taps, long presses,
and dragging gestures.

Change-Id: Id10bf8d46b9195330ce951f9f108c81e87a8dad4
2025-12-04 08:14:28 -05:00
Aidan MacDonald
0f4cc33d26 touchscreen: Increase report rate to 25fps
The touchscreen repeat interval effectively controls the report
rate of the touchscreen to the action code. Touch interactions
are smoother with a faster refresh rate, but the CPU needs to be
fast enough to keep up, or we risk queue overflows.

25fps is the minimum required to appear smooth, and probably all
targets will be able to handle the extra CPU load.

Change-Id: I96dcc80ea2ce8b915ff5682360c2e719b835388d
2025-12-04 07:10:17 -05:00
Aidan MacDonald
9e254acab3 touchscreen: Update action system touch event reporting
Add a cleaner API for reporting touch events and deprecate the old
action_get_touchscreen_press() API. The old API is now emulated by
using the new one internally.

Change-Id: I001378e66f9c81806f134f011420d671954fcde2
2025-12-04 07:10:17 -05:00
Solomon Peachy
fa164f89e0 tools: Detect A-profile ARM cores for hosted and sim builds
The only v7-a targets we have are built using the androidndk (with gcc
4.9) but it is possible to perform "self-hosted" builds for eg the
simulator or the sdlapp.

Where this gets messy is the considerable amount of inline arm
asm we have.

Native builds will need considerably more work to support
v7-a processors, but we have to start somewhere.

(Note that this contains parts of commit 508bfabe8, which had to
 be reverted due to breakage)

Change-Id: Ia1c8e10d21a976c68fdaae58e4d776854b63186c
2025-12-03 22:49:25 -05:00
Solomon Peachy
c26981a9c6 samsungypr0: Fix red in bbcf210c94 due to a merge error
Change-Id: I78b69e67a0f0cd786c79da78245d93838a9142b9
2025-12-03 22:39:33 -05:00
Solomon Peachy
bbcf210c94 Nuke maemo (nokian800/nokian900) and [open]pandora targets
They haven't seen any work since 2013, and likely hasn't compiled in at
least a couple of releases -- not that we ever "released" anything for
these targets.

Futhermore, upstream for both has been effectively dead for about as
long, and there's been no user reports of these being used since 2017
(and even then only in passing).

It isn't worth the effort to triage their current state, much less
uplift into something supportable, while the maintenance burden of
keeping these things in-tree can be demonstrated by the diffstat.

Change-Id: Id93bd450679d1b75e2c74295b3ae1548cd241b24
2025-12-03 20:42:02 -05:00
Aidan MacDonald
c47c075bd3 touchscreen: Fix event reporting in button driver
The way the button driver reported touch events was problematic
and made it impossible to detect if a touch started or if it was
a continuation of an existing touch.

Now, the first detected touch event gets BUTTON_TOUCHSCREEN and
all subsequent touch events while the screen is pressed will get
the BUTTON_REPEAT bit set. When the screen is released the final
event will have the BUTTON_REL bit set.

Change-Id: Ia456a22b2180031555a82231c2af32576bc5f2cb
2025-12-03 20:34:52 -05:00
Aidan MacDonald
9f613fd981 touchscreen: Default to putting the scrollbar on the right
For touch targets and right-handed use it makes most sense to
put the scrollbar on the right so your finger doesn't get in
the way of the touchscreen. Sorry left-handed people!

Change-Id: I35cfd8aa3bee6eb638572c9ca592942c53188a50
2025-12-03 20:34:52 -05:00
Solomon Peachy
9290a484e4 Revert "Disable Thumb code generation in codecs for ARM profile 65"
This reverts commit 508bfabe83.

Reason for revert: Completely breaks builds made using Android toolchains.  A different approach is necessary.

Change-Id: Ie8767f1f304c1313e8a539179bc33d1cc7032a3c
2025-12-03 20:31:30 -05:00
Vencislav Atanasov
508bfabe83 Disable Thumb code generation in codecs for ARM profile 65
It seems that there are a couple of codecs that use assembly optimizations. Some of their instruction sequences are not valid Thumb code. To be able to compile them successfully on TI OMAP4430, ARM mode is forced on the codecs.

Change-Id: I932186177b540985e37cb3a5333943572da1c60a
2025-12-04 00:03:40 +02:00
Solomon Peachy
11163721d6 audio: Fix up final red from a79bdaf462
Change-Id: I8de562516e54e2101746ea54d91461661439bcf5
2025-12-02 22:16:34 -05:00
Solomon Peachy
6bdd3de554 Move hosted codec header files back under firmware/export
This is a partial revert of a79bdaf46

It caused all sorts of build breakages for misc stuff like the dbtool,
which doesn't include any per-target build directories

Change-Id: I493a33c1859706679972e47c96196223415985d9
2025-12-02 20:35:18 -05:00
Solomon Peachy
c2952136c6 audio: Fix up more red from a79bdaf462
Change-Id: Ie6a68f2a14489bc84ddc57b73b37ddb94b7dc0ac
2025-12-02 20:35:18 -05:00
Solomon Peachy
fd6d6c48b4 audio: Fix up most of the red from a79bdaf462
The rest involves some wrangling.

Change-Id: I5459c255677cbacf8cc8b0c28492d27c58971cb1
2025-12-02 20:09:47 -05:00
Solomon Peachy
a79bdaf462 audio: Move hosted audio "codec" drivers into their respective target dirs
They are nearly entirely generic wrappers around ALSA controls, unique
per target, and are ripe for further consolidation.

Change-Id: I05e4a450e3e89e03616906601c4f8fa46200dff5
2025-12-02 18:59:50 -05:00
Solomon Peachy
d376e0afb7 configure: Fix numeric entries for ihifi 770/770c
Regression from d65bfff876

Change-Id: I0cf3536968368e7a96ada40ebaf6c0c772e6880b
2025-12-02 08:31:54 -05:00
Aidan MacDonald
806b71b2ed hosted: consolidate sysfs-based battery measurement code
Several hosted targets read their battery state from a fixed
sysfs path. Get rid of the duplicated code by handling this
common case in power-linux.c.

Some targets use non-standard units in sysfs instead of the
typical microvolts / microamps, so allow the scale factors
to be overridden by the target.

Change-Id: I31dc4ffc7a2d2c066d00a74070f9f9849c1663d0
2025-12-01 13:39:04 +00:00
Solomon Peachy
7ffdf50ba5 ibasso: Use generic hosted sysfs accessors
This keeps the enumerated list of sysfs parameters.

Change-Id: Ia63549809490eba02b3f75b3d2f95745636e01a9
2025-11-30 19:21:06 -05:00
Solomon Peachy
d65bfff876 configure: Rearrange and renumber target listing to clean it up a bit
I didn't change the number of anything that would be consider "popular"
but the longnames are all unchanged so it's only muscle memory that will
be affected.

Change-Id: Ic34a2e01801b14e81d4f7c84633bf10fdcbc43c9
2025-11-29 17:27:52 -05:00
Solomon Peachy
9a9b4d089e FS#13708: Corrections to Russian translation (Ivan Romaniuk-Mikhailovsky)
Change-Id: I7c40dba2654c50b9c5f5770e09f415d56b26d1cd
2025-11-29 16:10:43 -05:00
Solomon Peachy
23d0886f29 FS#13701: Updated Russian translation (Ivan Romaniuk-Mikhailovsky)
Change-Id: I1cc454dce50651d95b611178cc986b7fa626f55f
2025-11-29 10:40:21 -05:00
Solomon Peachy
9020360f66 hosted: Pull tinyalsa out of ibasso tree so other targets can use it
Change-Id: I85e31a0d0993d3494568abbc05ff9b114d493d75
2025-11-28 19:33:48 -05:00
Solomon Peachy
26d22a64c9 mkzenboot: Add support for 1.21.03 (US) firmware on the ZEN
The EU variant was already listed, but the US was not.

Change-Id: I8445a9e906ecd891f1ca571a4a3d7aa146e69698
2025-11-28 16:38:23 -05:00
Solomon Peachy
6314eae268 Fix build regression for Creative ZEN V
Introduced in 297af3a483

Change-Id: I9cf37e27ecdf84b6f0a8b6c8d15b1eae987cedbe
2025-11-28 07:38:40 -05:00
Solomon Peachy
a6538abd16 rk27xx: Use slower memory timings at startup
Our decade+old defaults are reported to trigger a failure on
one user's IHIFI770c and IHIFI960, but work on their HM-603.
Backing CAS latency off from 2 to 3 appears to be sufficient.

What's interesting is that on paper, CL=2 should be easily attainable
due to our max RAM clock of 100MHz, well within the worst-case timings
of the EM639165 SDRAM.

So as an experiment, this code can go back to CL=2 when we change the
CPU+RAM clock speeds.  IF this still proves problematic, it will be
removed.

Change-Id: I4a8cfa0563c076e7f25d9599a19b454f590861cd
2025-11-28 07:18:22 -05:00
Christian Soffke
3307b04eed usb: Shorten debounce interval for USB status by event
The introduction of a debounce interval for USB
status by event (see e75a3fb), often resulted in the
FiiO M3K crashing after disconnecting from USB.
Shortening the interval to 10ms appears to fix this,
or make a crash much less likely at the very least.

Change-Id: Ibf1f02779ab1704d9b1c86d39b21648a3e2c4e9d
2025-11-27 20:55:00 -05:00
Sebastian Leonhardt
297af3a483 Creative ZEN: fix RTC regression
Creative ZEN lost it's time when shutting down.
The bug was introduced with commit 7f282b9280 (g#2601),
followed by e3f6e9d9f6 (g#2616).

I guarded all persistent register writes with wait loops,
as described in the datasheet.

TODO:
test SONY_NWZE360 and SONY_NWZE370 targets

Change-Id: Ib38ab8691fd1c6e8d0771c1e2eca20dfeb6fc87f
2025-11-27 15:04:14 -05:00
Sebastian Leonhardt
69bc230e7d imx233: add HW_RTC_CTRL and HW_RTC_STAT registers to debug screen
Change-Id: Id52f86b26ee039781f44fde639fb8f184c7dc438
2025-11-27 12:36:28 +01:00
Solomon Peachy
c43919352d FS#13707: Updated Simplified Chinese Translation (王吉)
Change-Id: I07bbe6f1415eea14fc3405f4030311437a976943
2025-11-26 20:31:05 -05:00
William Wilgus
76ee238d48 FS#13704 - Rockpaint fonts memory troubles -- Disable font rendering in font selection
Displaying the fonts as you select them is nice but IMO pretty wasteful
I think a few static bitmaps would probably suffice
I however don't feel like addressing this so lets just disable it, for now?

Change-Id: I882cc0c4129e99d8b2f4ac135301dc3906340bb7
2025-11-26 01:24:13 -05:00
William Wilgus
4e4af2fe96 Bugfix FS#13696 - ID3 year with substring cause panic
The issue was the false case returning NULL for children elements
instead just ignore the false branch for everything but
SKIN_TOKEN_SUBLINE_TIMEOUT_HIDE

Change-Id: Ie0f4f51646faf116e563ab7e60d52d18759f4220
2025-11-25 17:00:50 -05:00
Solomon Peachy
936482abb5 bootloaders: Correct formatting of 'no parition found' table dump
Change-Id: I0eb48a0a40d317f9b47b181e0a31bef7ffde1e15
2025-11-24 21:17:09 -05:00
Solomon Peachy
7511d7e514 ipod6g: Correct inverted sector shift for CE-ATA operations.
(sector needs to be scaled UP, not DOWN)

Change-Id: I350c6c371b29c5e152d8d35852e55e3eda0d1090
2025-11-24 21:08:01 -05:00
Christian Soffke
f2be592215 plugins: Oscilloscope: Fix outdated mixer frequency
When Waveform mode was active, frequency changes during playback
(if set to "auto", or with USB audio active) weren't picked
up

Change-Id: Iebec7db951312b7dacff850e9554e1d06762ab3a
2025-11-24 21:26:42 +01:00
Christian Soffke
10808f5dfe plugins: Oscilloscope fiiom3k keymap: Add graphmode support
- Allows switching between peaks and waveform
- Adds some missing keys to manual entry

Change-Id: I0b4f2cee3c4da071bf3bf43487c6f445e0f7f61c
2025-11-24 19:35:05 +01:00
Christian Soffke
4095b13d52 plugins: Oscilloscope & VU Meter: Support USB audio
Also show current mixer frequency in title of VU meter,
and adjust the menu title from "VU Meter Menu" to just
"VU Meter"

Change-Id: I5bf8f55a3c9874618cac939fe32a611ac96f52ff
2025-11-24 19:35:05 +01:00
Solomon Peachy
0551c4a780 ipod6g: Scale CE-ATA READ/WRITE sector/counts correctly
Despite the fact that CE-ATA specifies a minimum logical sector size of
4096 bytes, the low-level tranfer command arguments are specified in
units of 512 bytes. So scale the sector count up and the LBA down.

On CE-ATA devies, the partition table and filesytem is formatted with 4K
logical sectors, so this will be safe.

Change-Id: I959f21f9c72a68ac28aa611d06f8517ca77f0a8c
2025-11-23 20:21:06 -05:00
Solomon Peachy
e3dc4bf2d3 FS#13701: Updated Russian translation (Ivan Romaniuk-Mikhailovsky)
Most changes are for consistent capitalization

Change-Id: I5ebc3656450ee8ddf07c5a7fed0c1463b9825b9b
2025-11-23 20:21:06 -05:00
Solomon Peachy
ad6cc2f099 ipod6g: Prevent booting into OF if it does not support LBA48 and drive needs it
Early 6th gen ipods (80GB and 160GB "fat") are limited to LBA28
which results in a hard upper limit of 128GiB on the storage size.
The later 120GB model also shares this limitation.  These are identified
by HwVr of 0x00130000 and 0x00130100, respectively.

The final revision of the iPod Classic series (160GB "thin") does not
have this limitation, and can be identified by a HwVr of 0x00130200 or
0x00130300.

This is strictly an issue with Apple's stock firmware, and not the
hardware, and Rockbox will happily utilize the full capabiltiies of any
installed storage device.  Unfortunately, if you boot into the stock
Apple firmware, said firmware will destructively trash the partition
table and filesystem.

Consequently, the Rockbox bootloader will now check if the installed
drive requires LBA48, making sure the flashed firmware also supports
LBA48.  If not, we will disallow booting into the OF (including disk mode)
altogether.  This check can be overridden by holding down LEFT, at which
point you get to keep all the pieces.

Note: While Apple never released firmware without these limitaitons on
the older models, there is a way to update to update these to the newer
firmware.  This requires altering the stored HwVr, so it is safe to use
the HwVr as a proxy for the installe firmware capabilities.

Change-Id: Icdd5754f2a3d38c6de67fc7565fabc7aa20f19b3
2025-11-23 13:41:32 -05:00
Solomon Peachy
eeb8a893f1 talk: Rework utf8-awareness in talk_spell()
* Eliminates warning on 16-bit unicode devices
 * More efficient
 * Still correct

Change-Id: I8d29f5560bc6f34b935e867d184a62a280b33596
2025-11-23 12:08:51 -05:00
145 changed files with 2337 additions and 3848 deletions

View file

@ -11,6 +11,9 @@ core_keymap.c
debug_menu.c
filetypes.c
fileop.c
#ifdef HAVE_TOUCHSCREEN
gesture.c
#endif
language.c
main.c
menu.c

View file

@ -101,8 +101,10 @@ typedef struct
#endif
#ifdef HAVE_TOUCHSCREEN
bool ts_short_press;
int ts_data;
int ts_data;
long ts_start_tick;
struct touchevent touchevent;
struct gesture gesture;
#endif
} action_last_t;
@ -123,8 +125,8 @@ static action_last_t action_last =
#endif
#ifdef HAVE_TOUCHSCREEN
.ts_data = 0,
.ts_short_press = false,
.ts_data = 0,
.ts_start_tick = 0,
#endif
#ifdef HAVE_BACKLIGHT
@ -414,12 +416,10 @@ static inline void update_screen_has_lock(action_last_t *last, action_cur_t *cur
}
/***********************************************
* get_action_touchscreen allows touchscreen
* presses to have short_press and repeat events
* handles touch event processing
*/
static inline bool get_action_touchscreen(action_last_t *last, action_cur_t *cur)
{
#if !defined(HAVE_TOUCHSCREEN)
(void) last;
(void) cur;
@ -427,26 +427,56 @@ static inline bool get_action_touchscreen(action_last_t *last, action_cur_t *cur
#else
if (has_flag(cur->button, BUTTON_TOUCHSCREEN))
{
last->repeated = false;
last->ts_short_press = false;
if (has_flag(last->button, BUTTON_TOUCHSCREEN))
intptr_t data = button_get_data();
long now = current_tick;
if (has_flag(last->button, BUTTON_TOUCHSCREEN) &&
!has_flag(last->button, BUTTON_REL))
{
if (has_flag(cur->button, BUTTON_REL) &&
!has_flag(last->button, BUTTON_REPEAT))
{
last->ts_short_press = true;
}
else if (has_flag(cur->button, BUTTON_REPEAT))
{
/* Only update the coordinates if this is not a release event.
* For release events, we reuse the previous event coordinates. */
if (!has_flag(cur->button, BUTTON_REL))
last->ts_data = data;
/* Historical baggage... may be unnecessary. */
if (has_flag(cur->button, BUTTON_REPEAT))
last->repeated = true;
}
}
else
{
/* Ignore isolated release events. No good can come of this. */
if (has_flag(cur->button, BUTTON_REL))
return false;
last->ts_data = data;
last->ts_start_tick = now;
}
last->button = cur->button;
last->tick = current_tick;
last->tick = now;
cur->action = ACTION_TOUCHSCREEN;
/* Update touchevent data */
if (has_flag(last->button, BUTTON_REL))
last->touchevent.type = TOUCHEVENT_RELEASE;
else if (has_flag(last->button, BUTTON_REPEAT))
last->touchevent.type = TOUCHEVENT_CONTACT;
else
last->touchevent.type = TOUCHEVENT_PRESS;
last->touchevent.x = (last->ts_data >> 16) & 0xffff;
last->touchevent.y = last->ts_data & 0xffff;
last->touchevent.tick = last->tick;
/* Update gesture state */
gesture_process(&last->gesture, &last->touchevent);
return true;
}
else
{
last->touchevent.type = TOUCHEVENT_NONE;
}
return false;
#endif
@ -1117,54 +1147,80 @@ static int get_action_worker(action_last_t *last, action_cur_t *cur)
*******************************************************************************
*/
#ifdef HAVE_TOUCHSCREEN
int action_get_touch_event(struct touchevent *ev)
{
if (ev)
*ev = action_last.touchevent;
return action_last.touchevent.type;
}
void action_gesture_reset(void)
{
gesture_reset(&action_last.gesture);
}
bool action_gesture_get_event_in_vp(struct gesture_event *gevt,
const struct viewport *vp)
{
return gesture_get_event_in_vp(&action_last.gesture, gevt, vp);
}
bool action_gesture_is_valid(void)
{
return gesture_is_valid(&action_last.gesture);
}
bool action_gesture_is_pressed(void)
{
return gesture_is_pressed(&action_last.gesture);
}
/* return BUTTON_NONE on error
* BUTTON_REPEAT if repeated press
* BUTTON_REPEAT|BUTTON_REL if release after repeated press
* BUTTON_REL if it's a short press = release after press
* BUTTON_TOUCHSCREEN if press
* DEPRECATED, do not use it anymore.
*/
int action_get_touchscreen_press(short *x, short *y)
{
/* historical default value */
const long long_press_time = 30 * HZ / 100;
int data;
int ret = BUTTON_TOUCHSCREEN;
if (!has_flag(action_last.button, BUTTON_TOUCHSCREEN))
int ret;
struct touchevent ev;
switch (action_get_touch_event(&ev))
{
return BUTTON_NONE;
case TOUCHEVENT_PRESS:
case TOUCHEVENT_CONTACT:
if (TIME_AFTER(ev.tick, action_last.ts_start_tick + long_press_time))
ret = BUTTON_REPEAT;
else
ret = BUTTON_TOUCHSCREEN;
break;
case TOUCHEVENT_RELEASE:
if (TIME_AFTER(ev.tick, action_last.ts_start_tick + long_press_time))
ret = BUTTON_REPEAT|BUTTON_REL;
else
ret = BUTTON_REL;
break;
default:
ret = BUTTON_NONE;
break;
}
data = button_get_data();
if (has_flag(action_last.button, BUTTON_REL))
{
*x = (action_last.ts_data&0xffff0000)>>16;
*y = (action_last.ts_data&0xffff);
}
else
{
*x = (data&0xffff0000)>>16;
*y = (data&0xffff);
}
action_last.ts_data = data;
if (action_last.repeated)
{
ret = BUTTON_REPEAT;
}
else if (action_last.ts_short_press)
{
ret = BUTTON_REL;
}
/* This is to return a BUTTON_REL after a BUTTON_REPEAT. */
else if (has_flag(action_last.button, BUTTON_REL))
{
ret = BUTTON_REPEAT|BUTTON_REL;
if (ret != BUTTON_NONE) {
*x = ev.x;
*y = ev.y;
}
return ret;
}
/* DEPRECATED, do not use it anymore. */
int action_get_touchscreen_press_in_vp(short *x1, short *y1, struct viewport *vp)
{
short x, y;

View file

@ -23,6 +23,7 @@
#include "stdbool.h"
#include "button.h"
#include "viewport.h"
#include "gesture.h"
#define TIMEOUT_BLOCK -1
#define TIMEOUT_NOBLOCK 0
@ -302,6 +303,8 @@ enum {
ACTION_TOUCH_REPMODE,
ACTION_TOUCH_MUTE,
ACTION_TOUCH_SCROLLBAR,
ACTION_TOUCH_SCROLLBAR_SET,
ACTION_TOUCH_SCROLLBAR_END,
ACTION_TOUCH_VOLUME,
ACTION_TOUCH_SOFTLOCK,
ACTION_TOUCH_SETTING,
@ -415,24 +418,23 @@ int get_action_statuscode(int *button);
intptr_t get_action_data(void);
#ifdef HAVE_TOUCHSCREEN
/* return BUTTON_NONE on error
* BUTTON_REPEAT if repeated press
* BUTTON_REPEAT|BUTTON_REL if release after repeated press
* BUTTON_REL if it's a short press = release after press
* BUTTON_TOUCHSCREEN if press
*/
int action_get_touchscreen_press(short *x, short *y);
/* Return a touch event and screen coordinates of the touch. */
int action_get_touch_event(struct touchevent *ev);
/*
* wrapper action_get_touchscreen_press()
* to filter the touchscreen coordinates through a viewport
*
* returns the action and x1, y1 relative to the viewport if
* the press was within the viewport,
* ACTION_UNKNOWN (and x1, y1 untouched) if the press was outside
* BUTTON_NONE else
*
**/
/* Action system gesture recognition */
void action_gesture_reset(void);
bool action_gesture_get_event_in_vp(struct gesture_event *gevt,
const struct viewport *vp);
bool action_gesture_is_valid(void);
bool action_gesture_is_pressed(void);
static inline bool action_gesture_get_event(struct gesture_event *gevt)
{
return action_gesture_get_event_in_vp(gevt, NULL);
}
/* DEPRECATED, do not use these anymore */
int action_get_touchscreen_press(short *x, short *y);
int action_get_touchscreen_press_in_vp(short *x1, short *y1, struct viewport *vp);
#endif

View file

@ -54,7 +54,7 @@
#define LOGF_ENABLE
#include "logf.h"
#if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
#if (CONFIG_PLATFORM & PLATFORM_SDL)
#define PREFIX(_x_) sim_ ## _x_
#else
#define PREFIX(_x_) _x_

View file

@ -746,6 +746,9 @@ int ft_enter(struct tree_context* c)
else
rc = GO_TO_FILEBROWSER;
break;
case PLUGIN_GOTO_ROOT:
rc = GO_TO_ROOT;
break;
/*
case PLUGIN_ERROR:
case PLUGIN_OK:

183
apps/gesture.c Normal file
View file

@ -0,0 +1,183 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2022 by Aidan MacDonald
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "gesture.h"
#include "button.h"
#include "viewport.h"
#include "system.h"
/* could be a setting */
#define TOUCH_LONG_PRESS_TIME (30 * HZ / 100)
void gesture_reset(struct gesture *g)
{
g->flags = 0;
}
void gesture_process(struct gesture *g, const struct touchevent *ev)
{
/* wait for the first press if we haven't seen it */
if (!gesture_is_pressed(g) && ev->type != TOUCHEVENT_PRESS)
return;
int dx, dy, dist_sqr;
switch (ev->type)
{
case TOUCHEVENT_PRESS:
g->flags |= GESTURE_F_PRESSED | GESTURE_F_VALID;
g->id = GESTURE_NONE;
g->ox = g->x = ev->x;
g->oy = g->y = ev->y;
g->start_tick = ev->tick;
g->last_tick = ev->tick;
break;
case TOUCHEVENT_CONTACT:
g->x = ev->x;
g->y = ev->y;
g->last_tick = ev->tick;
if (g->id == GESTURE_LONG_PRESS)
g->id = GESTURE_HOLD;
else if (g->id == GESTURE_DRAGSTART)
g->id = GESTURE_DRAG;
else if (g->id != GESTURE_DRAG)
{
dx = ev->x - g->ox;
dy = ev->y - g->oy;
dist_sqr = dx*dx + dy*dy;
/* if squared distance exceeds a threshold, report as a DRAG. */
const int thresh = touchscreen_get_scroll_threshold();
if (dist_sqr > thresh*thresh)
g->id = GESTURE_DRAGSTART;
/* report a LONG_PRESS if no motion occurs within a timeout */
if (g->id == GESTURE_NONE &&
TIME_AFTER(ev->tick, g->start_tick + TOUCH_LONG_PRESS_TIME))
g->id = GESTURE_LONG_PRESS;
}
break;
case TOUCHEVENT_RELEASE:
/* report a RELEASE event after a continuous HOLD or DRAG */
if (g->id == GESTURE_HOLD ||
g->id == GESTURE_DRAGSTART ||
g->id == GESTURE_DRAG)
g->id = GESTURE_RELEASE;
/* report a TAP event if we got a press & release without
* triggering any other gestures */
else if (g->id == GESTURE_NONE)
g->id = GESTURE_TAP;
g->flags &= ~GESTURE_F_PRESSED;
g->last_tick = ev->tick;
break;
}
}
bool gesture_get_event_in_vp(struct gesture *g, struct gesture_event *gevt,
const struct viewport *vp)
{
if (!gesture_is_valid(g))
return false;
gevt->id = g->id;
gevt->x = g->x;
gevt->y = g->y;
gevt->ox = g->ox;
gevt->oy = g->oy;
gevt->start_tick = g->start_tick;
gevt->last_tick = g->last_tick;
if (vp) {
gevt->x -= vp->x;
gevt->y -= vp->y;
gevt->ox -= vp->x;
gevt->oy -= vp->y;
}
return !vp || viewport_point_within_vp(vp, g->ox, g->oy);
}
/*
* gesture velocity helper
*/
void gesture_vel_reset(struct gesture_vel *gv)
{
gv->idx = 0;
gv->cnt = 0;
}
void gesture_vel_process(struct gesture_vel *gv, const struct touchevent *ev)
{
if (ev->type != TOUCHEVENT_PRESS &&
ev->type != TOUCHEVENT_CONTACT)
return;
gv->xsamp[gv->idx] = ev->x;
gv->ysamp[gv->idx] = ev->y;
gv->tsamp[gv->idx] = ev->tick;
gv->idx++;
gv->cnt++;
if (gv->idx >= ARRAYLEN(gv->xsamp))
gv->idx = 0;
}
bool gesture_vel_get(struct gesture_vel *gv, int *xvel, int *yvel)
{
if (gv->cnt <= 1) {
*xvel = 0;
*yvel = 0;
return false;
}
int dx = 0, dy = 0, dt = 0;
size_t n = MIN(gv->cnt, ARRAYLEN(gv->xsamp)) - 1;
size_t i = gv->cnt < ARRAYLEN(gv->xsamp) ? 0 : gv->idx;
size_t ip = i + 1;
while (n-- > 0) {
if (ip >= ARRAYLEN(gv->xsamp))
ip = 0;
dx += gv->xsamp[ip] - gv->xsamp[i];
dy += gv->ysamp[ip] - gv->ysamp[i];
dt += gv->tsamp[ip] - gv->tsamp[i];
i = ip;
ip++;
}
if (dt == 0) {
*xvel = 0;
*yvel = 0;
} else {
*xvel = dx * HZ / dt;
*yvel = dy * HZ / dt;
}
return gv->cnt >= ARRAYLEN(gv->xsamp);
}

137
apps/gesture.h Normal file
View file

@ -0,0 +1,137 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2022 Aidan MacDonald
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _GESTURE_H_
#define _GESTURE_H_
#include <stddef.h>
#include <stdbool.h>
struct viewport;
struct touchevent;
/** Events which can be detected by the gesture API.
*
* The gesture state machine, informally, looks like this:
*
* NONE --+--> TAP ------------------------------------+
* | |
* +--> LONG_PRESS -----------------------------+
* | | |
* | +---> HOLD ---+ |
* | | | |
* +-------------+---> DRAG ---+--> RELEASE ----+--> NONE
*
* State transitions occur from gesture_process() in response to touch events.
*
* - The NONE "event" is returned prior to any other gesture being detected.
* Although the graph above depicts a transition back to NONE at the end of
* an event chain, that transition in fact happens on the TOUCHEVENT_PRESS
* after the end of the last event.
*
* - TAP events are reported after getting a TOUCHEVENT_RELEASE event if no
* other gestures were detected between the press and release.
*
* - LONG_PRESS events are reported on a TOUCHEVENT_CONTACT event if the long
* press timeout has expired and the touch point hasn't moved too far from
* its initial position.
*
* - HOLD events are reported on TOUCHEVENT_CONTACT events after a LONG_PRESS,
* provided the touch point hasn't moved too far from its initial position.
*
* - DRAG events are reported on TOUCHEVENT_CONTACT events after the touch
* point first moves a certain distance from its initial position. The first
* time this happens, it is reported as DRAGSTART.
*
* - RELEASE events are reported on the TOUCHEVENT_RELEASE event following a
* HOLD or DRAG gesture.
*/
enum gesture_id
{
GESTURE_NONE = 0, /** No gesture */
GESTURE_TAP, /** Quick press & release */
GESTURE_LONG_PRESS, /** Start of a long press */
GESTURE_HOLD, /** Continuation of a long press */
GESTURE_DRAGSTART, /** Start of a DRAG event */
GESTURE_DRAG, /** Press and drag on the screen */
GESTURE_RELEASE, /** End of a HOLD or DRAG event */
};
enum gesture_flags
{
GESTURE_F_VALID = 0x01,
GESTURE_F_PRESSED = 0x02,
};
struct gesture
{
unsigned int flags;
int id;
short x, y;
short ox, oy;
long start_tick;
long last_tick;
};
struct gesture_event
{
int id;
short x, y;
short ox, oy;
long start_tick;
long last_tick;
};
void gesture_reset(struct gesture *g);
void gesture_process(struct gesture *g, const struct touchevent *ev);
bool gesture_get_event_in_vp(struct gesture *g, struct gesture_event *gevt,
const struct viewport *vp);
static inline bool gesture_get_event(struct gesture *g,
struct gesture_event *gevt)
{
return gesture_get_event_in_vp(g, gevt, NULL);
}
static inline bool gesture_is_valid(struct gesture *g)
{
return !!(g->flags & GESTURE_F_VALID);
}
static inline bool gesture_is_pressed(struct gesture *g)
{
return !!(g->flags & GESTURE_F_PRESSED);
}
/* Helper for computing velocity vectors */
struct gesture_vel
{
size_t idx;
size_t cnt;
short xsamp[4];
short ysamp[4];
long tsamp[4];
};
void gesture_vel_reset(struct gesture_vel *gv);
void gesture_vel_process(struct gesture_vel *gv, const struct touchevent *ev);
bool gesture_vel_get(struct gesture_vel *gv, int *xvel, int *yvel);
#endif /* _GESTURE_H_ */

View file

@ -46,13 +46,19 @@
#define ICON_PADDING 1
#define ICON_PADDING_S "1"
#ifdef HAVE_TOUCHSCREEN
/* used in gui_synclist->scroll_mode */
enum {
SCROLL_NONE = 0, /* no scrolling */
SCROLL_BAR, /* scroll by using the scrollbar */
SCROLL_SWIPE, /* scroll by wiping over the screen */
SCROLL_KINETIC, /* state after releasing swipe */
};
#endif
/* these are static to make scrolling work */
static struct viewport list_text[NB_SCREENS], title_text[NB_SCREENS];
#ifdef HAVE_TOUCHSCREEN
static bool hide_selection;
#endif
/* list-private helpers from the generic list.c (move to header?) */
int gui_list_get_item_offset(struct gui_synclist * gui_list, int item_width,
int text_pos, struct screen * display,
@ -363,7 +369,7 @@ void list_draw(struct screen *display, struct gui_synclist *list)
if(
#ifdef HAVE_TOUCHSCREEN
/* don't draw it during scrolling */
!hide_selection &&
list->scroll_mode == SCROLL_NONE &&
#endif
i >= list->selected_item
&& i < list->selected_item + list->selected_size)
@ -448,43 +454,51 @@ void list_draw(struct screen *display, struct gui_synclist *list)
#if defined(HAVE_TOUCHSCREEN)
/* This needs to be fixed if we ever get more than 1 touchscreen on a target. */
/* difference in pixels between draws, above it means enough to start scrolling */
#define SCROLL_BEGIN_THRESHOLD 3
static enum {
SCROLL_NONE, /* no scrolling */
SCROLL_BAR, /* scroll by using the scrollbar */
SCROLL_SWIPE, /* scroll by wiping over the screen */
SCROLL_KINETIC, /* state after releasing swipe */
} scroll_mode;
static int scrollbar_scroll(struct gui_synclist * gui_list, int y)
static void do_touch_scroll(struct gui_synclist *gui_list, int new_y_pos)
{
const int screen = screens[SCREEN_MAIN].screen_type;
if (new_y_pos < 0)
new_y_pos = 0;
int line_height = gui_list->line_height[SCREEN_MAIN];
int new_start = new_y_pos / line_height;
int nb_lines = list_get_nb_lines(gui_list, SCREEN_MAIN);
if (new_start > gui_list->nb_items - nb_lines)
{
new_start = gui_list->nb_items - nb_lines;
new_y_pos = new_start * line_height;
}
int new_item = new_start + nb_lines/2;
if (gui_list->selected_size > 1)
new_item -= new_item % gui_list->selected_size;
gui_list->selected_item = new_item;
gui_list->start_item[SCREEN_MAIN] = new_start;
gui_list->y_pos = new_y_pos;
}
/* Handle touch scrolling using the scrollbar. Pass the screen y-coordinate
* of the current touch position. */
static int scrollbar_scroll(struct gui_synclist *gui_list, int y)
{
const enum screen_type screen = SCREEN_MAIN;
const int nb_lines = list_get_nb_lines(gui_list, screen);
if (nb_lines < gui_list->nb_items)
{
const int line_height = gui_list->line_height[screen];
int bar_height = list_text[screen].height;
int bar_y = y - list_text[screen].y;
/* try to position the center of the scrollbar at the touch point */
int scrollbar_size = list_text[screen].height;
int actual_y = y - list_text[screen].y;
int new_y_pos = (actual_y * gui_list->nb_items * line_height) / scrollbar_size;
int new_start = (actual_y * gui_list->nb_items) / scrollbar_size;
if (bar_y < 0)
bar_y = 0;
else if(bar_y >= bar_height)
bar_y = bar_height - 1;
new_start -= nb_lines / 2;
int new_y_pos = (bar_y * gui_list->nb_items * line_height) / bar_height;
new_y_pos -= (nb_lines * line_height) / 2;
if(new_start < 0) {
new_start = 0;
new_y_pos = 0;
} else if(new_start > gui_list->nb_items - nb_lines) {
new_start = gui_list->nb_items - nb_lines;
new_y_pos = new_start * line_height;
}
gui_list->start_item[screen] = new_start;
gui_list->y_pos = new_y_pos;
do_touch_scroll(gui_list, new_y_pos);
return ACTION_REDRAW;
}
@ -492,6 +506,21 @@ static int scrollbar_scroll(struct gui_synclist * gui_list, int y)
return ACTION_NONE;
}
/* Handle swipe scrolling on a list. 'delta' is the distance to scroll
* relative to gui_list->scroll_base_y, which should be set up at the
* beginning of scrolling. */
static int swipe_scroll(struct gui_synclist *gui_list, int delta)
{
/* nothing to do if the list does not scroll */
const int nb_lines = list_get_nb_lines(gui_list, SCREEN_MAIN);
if (nb_lines >= gui_list->nb_items)
return ACTION_NONE;
do_touch_scroll(gui_list, gui_list->scroll_base_y - delta);
return ACTION_REDRAW;
}
/* kinetic scrolling, based on
*
* v = a*t + v0 and ds = v*dt
@ -513,7 +542,6 @@ static int scrollbar_scroll(struct gui_synclist * gui_list, int y)
* relatively accurate
*/
#define SIGN(a) ((a) < 0 ? -1 : 1)
/* these could possibly be configurable */
/* the lower the smoother */
@ -521,217 +549,92 @@ static int scrollbar_scroll(struct gui_synclist * gui_list, int y)
/* the higher the earler the list stops */
#define DECELERATION (1000*RELOAD_INTERVAL/HZ)
/* this array holds data to compute the initial velocity v0 */
static struct kinetic_info {
int difference;
long ticks;
} kinetic_data[4];
static size_t cur_idx;
struct kinetic_cb_data {
struct gui_synclist *list;
int velocity;
};
static struct cb_data {
struct gui_synclist *list; /* current list */
int velocity; /* in pixel/s */
} cb_data;
struct kinetic {
/* callback for performing the scroll animation */
struct kinetic_cb_data cb_data;
struct timeout tmo;
};
/* data member points to the above struct */
static struct timeout kinetic_tmo;
static struct kinetic kinetic;
static struct gesture_vel list_gvel;
static bool is_kinetic_over(void)
static void kinetic_stop_scrolling(struct kinetic *k, struct gui_synclist *list)
{
return !cb_data.velocity && (scroll_mode == SCROLL_KINETIC);
if (k->cb_data.list == list)
timeout_cancel(&k->tmo);
}
/*
* collect data about how fast the list is moved in order to compute
* the initial velocity from it later */
static void kinetic_stats_collect(const int difference)
/* helper for gui/list.c to cancel scrolling if a normal button event comes */
void _gui_synclist_stop_kinetic_scrolling(struct gui_synclist *list)
{
static long last_tick;
/* collect velocity statistics */
kinetic_data[cur_idx].difference = difference;
kinetic_data[cur_idx].ticks = current_tick - last_tick;
last_tick = current_tick;
cur_idx += 1;
if (cur_idx >= ARRAYLEN(kinetic_data))
cur_idx = 0; /* rewind the index */
}
/*
* resets the statistic */
static void kinetic_stats_reset(void)
{
memset(kinetic_data, 0, sizeof(kinetic_data));
cur_idx = 0;
}
/* cancels all currently active kinetic scrolling */
static void kinetic_force_stop(void)
{
timeout_cancel(&kinetic_tmo);
kinetic_stats_reset();
}
/* helper for gui/list.c to cancel scrolling if a normal button event comes
* through dpad or keyboard or whatever */
void _gui_synclist_stop_kinetic_scrolling(struct gui_synclist * gui_list)
{
const enum screen_type screen = screens[SCREEN_MAIN].screen_type;
gui_list->y_pos = gui_list->start_item[screen] * gui_list->line_height[screen];
if (scroll_mode == SCROLL_KINETIC)
kinetic_force_stop();
scroll_mode = SCROLL_NONE;
hide_selection = false;
}
/*
* returns false if scrolling should be stopped entirely
*
* otherwise it returns true even if it didn't actually scroll,
* but scrolling mode shouldn't be changed
**/
static int scroll_begin_threshold;
static int threshold_accumulation;
static bool swipe_scroll(struct gui_synclist * gui_list, int difference)
{
/* fixme */
const enum screen_type screen = screens[SCREEN_MAIN].screen_type;
const int nb_lines = list_get_nb_lines(gui_list, screen);
const int line_height = gui_list->line_height[screen];
if (UNLIKELY(scroll_begin_threshold == 0))
scroll_begin_threshold = touchscreen_get_scroll_threshold();
/* make selecting items easier */
threshold_accumulation += abs(difference);
if (threshold_accumulation < scroll_begin_threshold && scroll_mode == SCROLL_NONE)
return false;
threshold_accumulation = 0;
/* does the list even scroll? if no, return but still show
* the caller that we would scroll */
if (nb_lines >= gui_list->nb_items)
return true;
const int old_start = gui_list->start_item[screen];
int new_start_item = -1;
int line_diff = 0;
int max_y_pos = gui_list->nb_items * line_height - list_text[screen].height;
/* Track whether we hit the end of the list for sake of kinetic scroll */
bool hit_end = true;
/* Move the y position and clamp it (funny things happen otherwise...) */
gui_list->y_pos -= difference;
if(gui_list->y_pos < 0)
gui_list->y_pos = 0;
else if(gui_list->y_pos > max_y_pos)
gui_list->y_pos = max_y_pos;
else
hit_end = false;
/* Get the list y position. When pos_y differs by a line height or more,
* we need to scroll the list by adjusting the start item accordingly */
int cur_y = gui_list->start_item[screen] * line_height;
int diff_y = cur_y - gui_list->y_pos;
if (abs(diff_y) >= line_height)
if (list->scroll_mode == SCROLL_KINETIC)
{
line_diff = diff_y/line_height;
kinetic_stop_scrolling(&kinetic, list);
list->scroll_mode = SCROLL_NONE;
}
if(line_diff != 0)
{
int selection_offset = gui_list->selected_item - old_start;
new_start_item = old_start - line_diff;
/* check if new_start_item is bigger than list item count */
if(new_start_item > gui_list->nb_items - nb_lines)
new_start_item = gui_list->nb_items - nb_lines;
/* set new_start_item to 0 if it's negative */
if(new_start_item < 0)
new_start_item = 0;
gui_list->start_item[screen] = new_start_item;
/* keep selected item in sync */
gui_list->selected_item = new_start_item + selection_offset;
if(gui_list->selected_size > 1)
gui_list->selected_item -= (gui_list->selected_item % gui_list->selected_size);
}
if(hit_end)
return scroll_mode != SCROLL_KINETIC;
else
return true;
}
static int kinetic_callback(struct timeout *tmo)
{
/* cancel if screen was pressed */
if (scroll_mode != SCROLL_KINETIC)
struct kinetic_cb_data *data = (struct kinetic_cb_data*)tmo->data;
struct gui_synclist *list = data->list;
/* deal with cancellation */
if (list->scroll_mode != SCROLL_KINETIC)
return 0;
struct cb_data *data = (struct cb_data*)tmo->data;
/* ds = v*dt */
int pixel_diff = data->velocity * RELOAD_INTERVAL / HZ;
/* remember signedness to detect stopping */
int old_sign = SIGN(data->velocity);
/* advance the list */
if (!swipe_scroll(data->list, pixel_diff))
int action = swipe_scroll(list, pixel_diff);
if (action == ACTION_REDRAW)
{
/* nothing to scroll? */
data->velocity = 0;
}
else
{
/* decelerate by a fixed amount
* decrementing v0 over time by the deceleration is
* equivalent to computing v = a*t + v0 */
data->velocity -= SIGN(data->velocity)*DECELERATION;
if (SIGN(data->velocity) != old_sign)
data->velocity = 0;
/* force the list to redraw */
button_queue_post(BUTTON_REDRAW, 0);
}
/* let get_action() timeout, which loads to a
* gui_synclist_draw() call from the main thread */
button_queue_post(BUTTON_REDRAW, 0);
/* stop if the velocity hit or crossed zero */
if (!data->velocity)
/* apply deceleration */
int old_sign = SIGN(data->velocity);
data->velocity -= SIGN(data->velocity) * DECELERATION;
if (SIGN(data->velocity) != old_sign)
data->velocity = 0;
/* stop scrolling if we didn't move, it means we hit the end */
if (list->y_pos == list->scroll_base_y)
data->velocity = 0;
else
/* update base y since our scroll distance doesn't accumulate. */
list->scroll_base_y = list->y_pos;
if (data->velocity == 0)
{
kinetic_stats_reset();
list->scroll_mode = SCROLL_NONE;
return 0;
}
return RELOAD_INTERVAL; /* cancel or reload */
return RELOAD_INTERVAL;
}
/*
* computes the initial velocity v0 and sets up the timer */
static bool kinetic_setup_scroll(struct gui_synclist *list)
/* Computes the initial velocity v0 and sets up the timer */
static bool kinetic_start_scrolling(struct kinetic *k, struct gui_synclist *list)
{
/* compute initial velocity */
int i, _i, v0, len = ARRAYLEN(kinetic_data);
for(i = 0, _i = 0, v0 = 0; i < len; i++)
{ /* in pixel/s */
if (kinetic_data[i].ticks > 0)
{
v0 += kinetic_data[i].difference*HZ/kinetic_data[i].ticks;
_i++;
}
}
if (_i > 0)
v0 /= _i;
else
v0 = 0;
int xvel, yvel;
gesture_vel_get(&list_gvel, &xvel, &yvel);
if (yvel == 0)
return false;
if (v0 != 0)
{
cb_data.list = list;
cb_data.velocity = v0;
timeout_register(&kinetic_tmo, kinetic_callback, RELOAD_INTERVAL, (intptr_t)&cb_data);
return true;
}
return false;
k->cb_data.list = list;
k->cb_data.velocity = yvel;
list->scroll_mode = SCROLL_KINETIC;
list->scroll_base_y = list->y_pos;
timeout_register(&k->tmo, kinetic_callback, RELOAD_INTERVAL,
(intptr_t)&k->cb_data);
return true;
}
#define OUTSIDE 0
@ -746,18 +649,20 @@ static bool kinetic_setup_scroll(struct gui_synclist *list)
static int get_click_location(struct gui_synclist *list, int x, int y)
{
int screen = SCREEN_MAIN;
struct viewport *parent, *title, *text;
const enum screen_type screen = SCREEN_MAIN;
int retval = OUTSIDE;
parent = list->parent[screen];
struct viewport *parent = list->parent[screen];
struct viewport *text = &list_text[screen];
struct viewport *title = &title_text[screen];
if (viewport_point_within_vp(parent, x, y))
{
/* see if the title was clicked */
title = &title_text[screen];
if (viewport_point_within_vp(title, x, y))
retval = TITLE_TEXT;
/* check the icon too */
/* check the title icon */
if (list->title_icon != Icon_NOICON && list->show_icons)
{
int width = list_icon_width(screen);
@ -770,12 +675,12 @@ static int get_click_location(struct gui_synclist *list, int x, int y)
if (viewport_point_within_vp(&vp, x, y))
retval = TITLE_ICON;
}
/* check scrollbar. assume it's shown, if it isn't it will be handled
* later */
/* check scrollbar if shown */
if (retval == OUTSIDE)
{
bool on_scrollbar_clicked;
int adj_x = x - parent->x;
int adj_x = x - text->x;
switch (list->scrollbar)
{
case SCROLLBAR_OFF:
@ -787,12 +692,14 @@ static int get_click_location(struct gui_synclist *list, int x, int y)
on_scrollbar_clicked = adj_x <= SCROLLBAR_WIDTH;
break;
case SCROLLBAR_RIGHT:
on_scrollbar_clicked = adj_x > (title->x + title->width - SCROLLBAR_WIDTH);
on_scrollbar_clicked = adj_x > (text->x + text->width - SCROLLBAR_WIDTH);
break;
}
if (on_scrollbar_clicked)
retval = SCROLLBAR;
}
/* check the text area */
if (retval == OUTSIDE)
{
text = &list_text[screen];
@ -805,170 +712,126 @@ static int get_click_location(struct gui_synclist *list, int x, int y)
return retval;
}
unsigned gui_synclist_do_touchscreen(struct gui_synclist * list)
unsigned gui_synclist_do_touchscreen(struct gui_synclist *list)
{
enum screen_type screen;
struct viewport *parent;
short x, y;
int action, adj_x, adj_y, line, line_height, list_start_item;
bool recurse;
static bool initial_touch = true;
static int last_y;
screen = SCREEN_MAIN;
parent = list->parent[screen];
line_height = list->line_height[screen];
list_start_item = list->start_item[screen];
/* start with getting the action code and finding the click location */
action = action_get_touchscreen_press(&x, &y);
adj_x = x - parent->x;
adj_y = y - parent->y;
struct touchevent tevent;
struct gesture_event gevent;
action_get_touch_event(&tevent);
if (!action_gesture_get_event(&gevent))
return ACTION_NONE;
/* some defaults before running the state machine */
recurse = false;
hide_selection = false;
const enum screen_type screen = SCREEN_MAIN;
struct viewport *list_vp = list->parent[screen];
int adj_x = gevent.x - list_vp->x;
int adj_y = gevent.y - list_vp->y;
int line_height = list->line_height[screen];
int start_item = list->start_item[screen];
int start_y = start_item * line_height;
int action = ACTION_NONE;
int click_loc;
switch (scroll_mode)
switch (gevent.id)
{
case SCROLL_NONE:
case GESTURE_NONE:
if (!action_gesture_is_pressed())
break;
/* fallthrough */
case GESTURE_TAP:
case GESTURE_LONG_PRESS:
_gui_synclist_stop_kinetic_scrolling(list);
click_loc = get_click_location(list, gevent.x, gevent.y);
if (click_loc & LIST)
{
int click_loc;
if (initial_touch)
int line;
if(!skinlist_get_item(&screens[screen], list, adj_x, adj_y, &line))
{
/* on the first touch last_y has to be reset to avoid
* glitches with touches from long ago */
last_y = adj_y;
initial_touch = false;
line = (adj_y - (start_y - list->y_pos)) / line_height;
if (list_display_title(list, screen))
line -= 1;
}
line = 0; /* silence gcc 'used uninitialized' warning */
click_loc = get_click_location(list, x, y);
if (click_loc & LIST)
int new_item = start_item + line;
if (new_item < list->nb_items)
{
if(!skinlist_get_item(&screens[screen], list, adj_x, adj_y, &line))
{
/* selection needs to be corrected if items are only partially visible */
int cur_y = list->start_item[screen] * line_height;
line = (adj_y - (cur_y - list->y_pos)) / line_height;
if (list_display_title(list, screen))
line -= 1; /* adjust for the list title */
}
if (list_start_item+line >= list->nb_items)
return ACTION_NONE;
list->selected_item = list_start_item+line;
if(list->selected_size > 1)
list->selected_item -= (list->selected_item % list->selected_size);
if (list->selected_size > 1)
new_item -= new_item % list->selected_size;
list->selected_item = new_item;
gui_synclist_speak_item(list);
}
if (action == BUTTON_TOUCHSCREEN)
{
/* if not scrolling, the user is trying to select */
int diff = adj_y - last_y;
if ((click_loc & LIST) && swipe_scroll(list, diff))
scroll_mode = SCROLL_SWIPE;
else if (click_loc & SCROLLBAR)
scroll_mode = SCROLL_BAR;
}
else if (action == BUTTON_REPEAT)
{
if (click_loc & LIST)
{
/* held a single line for a while, bring up the context menu */
gui_synclist_select_item(list, list->selected_item);
/* don't sent context repeatedly */
action_wait_for_release();
initial_touch = true;
return ACTION_STD_CONTEXT;
}
}
else if (action & BUTTON_REL)
{
initial_touch = true;
if (click_loc & LIST)
{ /* release on list item enters it */
gui_synclist_select_item(list, list->selected_item);
return ACTION_STD_OK;
}
else if (click_loc & TITLE_TEXT)
{ /* clicking the title goes one level up (cancel) */
return ACTION_STD_CANCEL;
}
else if (click_loc & TITLE_ICON)
{ /* clicking the title icon goes back to the root */
return ACTION_STD_MENU;
}
}
break;
}
case SCROLL_SWIPE:
{
/* when swipe scrolling, we accept outside presses as well and
* grab the entire screen (i.e. click_loc does not matter) */
int diff = adj_y - last_y;
hide_selection = true;
kinetic_stats_collect(diff);
if (swipe_scroll(list, diff))
{
/* letting the pen go enters kinetic scrolling */
if ((action & BUTTON_REL))
{
if (kinetic_setup_scroll(list))
{
hide_selection = true;
scroll_mode = SCROLL_KINETIC;
}
else
scroll_mode = SCROLL_NONE;
}
}
else if (action & BUTTON_REL)
scroll_mode = SCROLL_NONE;
if (scroll_mode == SCROLL_NONE)
initial_touch = true;
break;
}
case SCROLL_KINETIC:
{
/* during kinetic scrolling we need to handle cancellation.
* This state is actually only entered upon end of it as this
* function is not called during the animation. */
if (!is_kinetic_over())
{ /* a) the user touched the screen (manual cancellation) */
kinetic_force_stop();
if (get_click_location(list, x, y) & SCROLLBAR)
scroll_mode = SCROLL_BAR;
if (gevent.id == GESTURE_TAP)
action = ACTION_STD_OK;
else if (gevent.id == GESTURE_LONG_PRESS)
action = ACTION_STD_CONTEXT;
else
scroll_mode = SCROLL_SWIPE;
action = ACTION_REDRAW;
}
else
{ /* b) kinetic scrolling stopped on its own */
/* need to re-run this with SCROLL_NONE since otherwise
* the next touch is not detected correctly */
scroll_mode = SCROLL_NONE;
recurse = true;
}
break;
}
case SCROLL_BAR:
else if ((click_loc & TITLE) && gevent.id == GESTURE_TAP)
{
hide_selection = true;
/* similarly to swipe scroll, using the scrollbar grabs
* focus so the click location is irrelevant */
scrollbar_scroll(list, y);
if (action & BUTTON_REL)
scroll_mode = SCROLL_NONE;
break;
if (click_loc & TITLE_TEXT)
action = ACTION_STD_CANCEL;
else if (click_loc & TITLE_ICON)
action = ACTION_STD_MENU;
}
else if (gevent.id != GESTURE_NONE && (click_loc & SCROLLBAR))
{
action = scrollbar_scroll(list, gevent.y);
/* allow long press to become a motion event */
if (gevent.id != GESTURE_TAP)
break;
}
if (action != ACTION_REDRAW)
gui_synclist_select_item(list, list->selected_item);
if (gevent.id != GESTURE_NONE)
action_gesture_reset();
break;
case GESTURE_DRAGSTART:
_gui_synclist_stop_kinetic_scrolling(list);
gesture_vel_reset(&list_gvel);
list->scroll_base_y = list->y_pos;
/* fallthrough */
case GESTURE_DRAG:
gesture_vel_process(&list_gvel, &tevent);
if (list->scroll_mode == SCROLL_NONE)
{
click_loc = get_click_location(list, gevent.ox, gevent.oy);
if (click_loc & SCROLLBAR)
list->scroll_mode = SCROLL_BAR;
else if (click_loc & LIST)
list->scroll_mode = SCROLL_SWIPE;
}
if (list->scroll_mode == SCROLL_BAR)
action = scrollbar_scroll(list, gevent.y);
else if (list->scroll_mode == SCROLL_SWIPE)
action = swipe_scroll(list, gevent.y - gevent.oy);
break;
case GESTURE_RELEASE:
if (list->scroll_mode != SCROLL_SWIPE ||
!kinetic_start_scrolling(&kinetic, list))
{
list->scroll_mode = SCROLL_NONE;
}
action_gesture_reset();
action = ACTION_REDRAW;
break;
default:
break;
}
/* register y position unless forcefully reset */
if (!initial_touch)
last_y = adj_y;
return recurse ? gui_synclist_do_touchscreen(list) : ACTION_REDRAW;
return action;
}
#endif

View file

@ -163,6 +163,8 @@ void gui_synclist_init(struct gui_synclist * gui_list,
gui_synclist_init_display_settings(gui_list);
#ifdef HAVE_TOUCHSCREEN
gui_list->y_pos = 0;
gui_list->scroll_base_y = 0;
gui_list->scroll_mode = 0;
#endif
FOR_NB_SCREENS(i)
{

View file

@ -23,6 +23,7 @@
#define _GUI_LIST_H_
#include "config.h"
#include "action.h"
#include "icon.h"
#include "screen_access.h"
#include "skin_engine/skin_engine.h"
@ -155,10 +156,6 @@ struct gui_synclist
int nb_items;
int selected_item;
#ifdef HAVE_TOUCHSCREEN
/* absolute Y coordinate, used for smooth scrolling */
int y_pos;
#endif
int start_item[NB_SCREENS]; /* the item that is displayed at the top of the screen */
/* the number of lines that are selected at the same time */
int selected_size;
@ -185,6 +182,12 @@ struct gui_synclist
struct list_selection_color *selection_color;
#endif
struct viewport *parent[NB_SCREENS];
#ifdef HAVE_TOUCHSCREEN
int y_pos; /* absolute Y coordinate, used for smooth scrolling */
int scroll_base_y; /* used for swipe scrolling */
int scroll_mode; /* see apps/gui/bitmap/list.c */
#endif
};

View file

@ -50,6 +50,11 @@
#define MARGIN 10
#define CENTER_ICONAREA_SIZE (MARGIN+8*2)
struct gui_quickscreen
{
const struct settings_list *items[QUICKSCREEN_ITEM_COUNT];
};
static bool redraw;
static void quickscreen_update_callback(unsigned short id,
@ -297,22 +302,30 @@ static bool gui_quickscreen_do_button(struct gui_quickscreen * qs, int button)
#ifdef HAVE_TOUCHSCREEN
static int quickscreen_touchscreen_button(void)
{
short x,y;
if (action_get_touchscreen_press(&x, &y) != BUTTON_REL)
struct gesture_event gevent;
if (!action_gesture_get_event(&gevent))
return ACTION_NONE;
switch (gevent.id) {
case GESTURE_TAP:
case GESTURE_HOLD:
break;
default:
return ACTION_NONE;
}
enum { left=1, right=2, top=4, bottom=8 };
int bits = 0;
if(x < LCD_WIDTH/3)
if(gevent.x < LCD_WIDTH/3)
bits |= left;
else if(x > 2*LCD_WIDTH/3)
else if(gevent.x > 2*LCD_WIDTH/3)
bits |= right;
if(y < LCD_HEIGHT/3)
if(gevent.y < LCD_HEIGHT/3)
bits |= top;
else if(y > 2*LCD_HEIGHT/3)
else if(gevent.y > 2*LCD_HEIGHT/3)
bits |= bottom;
switch(bits) {
@ -366,6 +379,10 @@ static int gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter
talk_qs_option(qs->items[QUICKSCREEN_LEFT], true);
if (qs->items[QUICKSCREEN_LEFT] != qs->items[QUICKSCREEN_RIGHT])
talk_qs_option(qs->items[QUICKSCREEN_RIGHT], true);
#ifdef HAVE_TOUCHSCREEN
action_gesture_reset();
#endif
while (true) {
if (redraw)
{

View file

@ -28,6 +28,8 @@
#include "screen_access.h"
struct settings_list;
enum quickscreen_item {
QUICKSCREEN_TOP = 0,
QUICKSCREEN_LEFT,
@ -43,11 +45,6 @@ enum quickscreen_return {
QUICKSCREEN_CHANGED = 0x4,
};
struct gui_quickscreen
{
const struct settings_list *items[QUICKSCREEN_ITEM_COUNT];
};
extern int quick_screen_quick(int button_enter);
int quickscreen_set_option(void *data);
bool is_setting_quickscreenable(const struct settings_list *setting);

View file

@ -119,6 +119,7 @@ static void gui_skin_reset(struct gui_skin *skin)
skin->data.tree = -1;
#ifdef HAVE_TOUCHSCREEN
skin->data.touchregions = -1;
gesture_reset(&skin->data.gesture);
#endif
#ifdef HAVE_SKIN_VARIABLES
skin->data.skinvars = -1;

View file

@ -982,6 +982,7 @@ static int parse_progressbar_tag(struct skin_element* element,
char *image_filename = NULL;
#ifdef HAVE_TOUCHSCREEN
bool suppress_touchregion = false;
char *touchregion_label = NULL;
#endif
if (element->params_count == 0 &&
@ -1156,6 +1157,17 @@ static int parse_progressbar_tag(struct skin_element* element,
#ifdef HAVE_TOUCHSCREEN
else if (pb_op == eNOTOUCH)
suppress_touchregion = true;
else if (!strcmp(text, "touchlabel"))
{
if (curr_param+1 < element->params_count)
{
curr_param++;
param++;
touchregion_label = SKINOFFSETTOPTR(skin_buffer, param->data.text);
}
else /* option needs the next param */
return -1;
}
#endif
else if (token->type == SKIN_TOKEN_SETTING && pb_op == eSETTING_OFFSET)
{
@ -1282,11 +1294,11 @@ static int parse_progressbar_tag(struct skin_element* element,
region->wvp = PTRTOSKINOFFSET(skin_buffer, curr_vp);
region->reverse_bar = false;
region->allow_while_locked = false;
region->user_region = false;
region->press_length = PRESS;
region->last_press = -1;
region->armed = false;
region->bar = PTRTOSKINOFFSET(skin_buffer, pb);
region->label = PTRTOSKINOFFSET(skin_buffer, NULL);
region->label = PTRTOSKINOFFSET(skin_buffer, touchregion_label);
item = new_skin_token_list_item(NULL, region);
if (!item)
@ -1781,13 +1793,14 @@ static int parse_touchregion(struct skin_element *element,
p++;
region->wvp = PTRTOSKINOFFSET(skin_buffer, curr_vp);
region->armed = false;
region->reverse_bar = false;
region->value = 0;
region->last_press = -1;
region->press_length = PRESS;
region->allow_while_locked = false;
region->user_region = true;
region->bar = PTRTOSKINOFFSET(skin_buffer, NULL);
action = get_param_text(element, p++);
/* figure out the action */
@ -2710,8 +2723,7 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
struct touchregion *r = NULL;
if (token)
r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (r && r->action != ACTION_TOUCH_SCROLLBAR &&
r->action != ACTION_TOUCH_VOLUME)
if (r && r->user_region)
{
user_touch_region_found = true;
break;

View file

@ -624,7 +624,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
{
struct skin_element *element=line;
struct wps_token *token;
struct wps_token *token = NULL;
int retval = DEFAULT_SUBLINE_TIME_MULTIPLIER*TIMEOUT_UNIT;
if (element->type == LINE)
{
@ -662,9 +662,12 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
struct conditional *conditional = SKINOFFSETTOPTR(skin_buffer, element->data);
int val = evaluate_conditional(gwps, 0, conditional, element->children_count);
int tmoval = get_subline_timeout(gwps, get_child(element->children, val));
if (tmoval >= 0)
return MAX(retval, tmoval); /* Bugfix %t()%?CONDITIONAL tmo ignored */
if (val >= 0 || (token && token->type == SKIN_TOKEN_SUBLINE_TIMEOUT_HIDE))
{/* only need tmoval in false case if SKIN_TOKEN_SUBLINE_TIMEOUT_HIDE */
int tmoval = get_subline_timeout(gwps, get_child(element->children, val));
if (tmoval >= 0)
return MAX(retval, tmoval); /* Bugfix %t()%?CONDITIONAL tmo ignored */
}
}
else if (type == COMMENT)
{

View file

@ -1457,10 +1457,10 @@ const char *get_token_value(struct gui_wps *gwps,
return NULL;
case SKIN_TOKEN_HAVE_TOUCH:
#ifdef HAVE_TOUCHSCREEN
return "t";
#else
return NULL;
if (touchscreen_get_mode() == TOUCHSCREEN_POINT)
return "t";
#endif
return NULL;
#ifdef HAVE_QUICKSCREEN
case SKIN_TOKEN_TOP_QUICKSETTING_NAME:

View file

@ -33,20 +33,12 @@
#include "splash.h"
#include "playlist.h"
#include "dsp_misc.h"
#include "playback.h"
/** Disarms all touchregions. */
void skin_disarm_touchregions(struct gui_wps *gwps)
{
struct wps_data *data = gwps->data;
char* skin_buffer = get_skin_buffer(data);
struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
while (regions)
{
struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
struct touchregion *region = SKINOFFSETTOPTR(skin_buffer, token->value.data);
region->armed = false;
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
}
gesture_reset(&gwps->data->gesture);
}
/* Get the touched action.
@ -56,272 +48,334 @@ void skin_disarm_touchregions(struct gui_wps *gwps)
int skin_get_touchaction(struct gui_wps *gwps, int* edge_offset)
{
struct wps_data *data = gwps->data;
int returncode = ACTION_NONE;
short x,y;
short vx, vy;
int type = action_get_touchscreen_press(&x, &y);
struct skin_viewport *wvp;
struct touchregion *r, *temp = NULL;
char* skin_buffer = get_skin_buffer(data);
bool repeated = (type == BUTTON_REPEAT);
bool released = (type == BUTTON_REL);
bool pressed = (type == BUTTON_TOUCHSCREEN);
struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
bool needs_repeat;
struct touchregion *region = NULL;
struct touchevent tevent;
struct gesture_event gevent;
while (regions)
action_get_touch_event(&tevent);
gesture_process(&data->gesture, &tevent);
struct skin_token_list *regions = SKINOFFSETTOPTR(skin_buffer, data->touchregions);
for (; regions && !region;
regions = SKINOFFSETTOPTR(skin_buffer, regions->next))
{
struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp);
struct touchregion *r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
struct skin_viewport *wvp = SKINOFFSETTOPTR(skin_buffer, r->wvp);
/* make sure this region's viewport is visible */
if (wvp->hidden_flags&VP_DRAW_HIDDEN)
{
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
if (wvp->hidden_flags & VP_DRAW_HIDDEN)
continue;
}
/* unless it's allow_while_locked, ignore the region if locked
* (this is a special skin engine lock, different from softlock) */
if (data->touchscreen_locked &&
(r->action != ACTION_TOUCH_SOFTLOCK && !r->allow_while_locked))
{
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
continue;
}
needs_repeat = r->press_length != PRESS;
/* check if it's inside this viewport */
if (viewport_point_within_vp(&(wvp->vp), x, y))
{ /* reposition the touch inside the viewport since touchregions
* are relative to a preceding viewport */
vx = x - wvp->vp.x;
vy = y - wvp->vp.y;
/* project touches in the padding region so they clamp to the
* edge of the region instead */
if(r->x - r->wpad <= vx && vx < r->x)
vx = r->x;
else if(r->x + r->width <= vx && vx < r->x + r->width + r->wpad)
vx = r->x + r->width - 1;
if(r->y - r->hpad <= vy && vy < r->y)
vy = r->y;
else if(r->y + r->height <= vy && vy < r->y + r->height + r->hpad)
vy = r->y + r->height - 1;
/* check for a gesture inside the region's parent viewport */
if (!gesture_get_event_in_vp(&data->gesture, &gevent, &wvp->vp))
continue;
/* now see if the point is inside this region */
if (vx >= r->x && vx < r->x+r->width &&
vy >= r->y && vy < r->y+r->height)
/* project touches inside the padding box to the region edge */
if (r->x - r->wpad <= gevent.ox && gevent.ox < r->x)
gevent.ox = r->x;
else if (r->x + r->width <= gevent.ox && gevent.ox < r->x + r->width + r->wpad)
gevent.ox = r->x + r->width - 1;
if (r->y - r->hpad <= gevent.y && gevent.y < r->y)
gevent.oy = r->y;
else if (r->y + r->height <= gevent.oy && gevent.oy < r->y + r->height + r->hpad)
gevent.oy = r->y + r->height - 1;
/* ignore anything outside of the region */
if (gevent.ox < r->x || gevent.ox >= r->x + r->width)
continue;
if (gevent.oy < r->y || gevent.oy >= r->y + r->height)
continue;
/* convert coordinates to region-relative and clamp */
gevent.x -= r->x;
gevent.y -= r->y;
switch (r->action)
{
case ACTION_TOUCH_SCROLLBAR:
case ACTION_TOUCH_VOLUME:
case ACTION_TOUCH_SETTING:
/* accept taps and drags, ignore the rest */
if (!(gevent.id == GESTURE_TAP ||
gevent.id == GESTURE_HOLD ||
gevent.id == GESTURE_DRAGSTART ||
gevent.id == GESTURE_DRAG ||
gevent.id == GESTURE_RELEASE))
break;
if (edge_offset)
{
/* reposition the touch within the area */
vx -= r->x;
vy -= r->y;
struct progressbar *bar = SKINOFFSETTOPTR(skin_buffer, r->bar);
bool reverse = r->reverse_bar || (bar && bar->invert_fill_direction);
int pos, lim;
switch(r->action)
{
case ACTION_TOUCH_SCROLLBAR:
case ACTION_TOUCH_VOLUME:
case ACTION_TOUCH_SETTING:
if (edge_offset)
{
struct progressbar *bar =
SKINOFFSETTOPTR(skin_buffer, r->bar);
if(r->width > r->height) {
if(r->width > 1)
*edge_offset = vx*1000/(r->width - 1);
else
*edge_offset = 0;
} else {
/* vertical bars are bottom-up by default */
if(r->height > 1)
*edge_offset = 1000 - vy*1000/(r->height - 1);
else
*edge_offset = 0;
}
if (r->reverse_bar || (bar && bar->invert_fill_direction))
*edge_offset = 1000 - *edge_offset;
}
temp = r;
returncode = r->action;
r->last_press = current_tick;
break;
default:
if (r->armed && ((repeated && needs_repeat) ||
(released && !needs_repeat)))
{
returncode = r->action;
temp = r;
}
if (pressed)
{
r->armed = true;
r->last_press = current_tick;
}
break;
if (r->width > r->height) {
/* left to right by default */
pos = MIN(MAX(0, gevent.x), r->width - 1);
lim = r->width;
} else {
/* bottom up by default, so we need to add a reversal */
pos = MIN(MAX(0, gevent.y), r->height - 1);
lim = r->height;
reverse = !reverse;
}
if (lim > 1)
*edge_offset = pos * 1000 / (lim - 1);
else
*edge_offset = 0;
if (reverse)
*edge_offset = 1000 - *edge_offset;
}
region = r;
break;
default:
if (r->press_length == PRESS)
{
if (gevent.id != GESTURE_TAP)
break;
}
else if (r->press_length == LONG_PRESS)
{
if (gevent.id != GESTURE_LONG_PRESS)
break;
}
else /* REPEAT */
{
/* for repeat regions we allow dragging inside the region */
if (gevent.id != GESTURE_HOLD &&
gevent.id != GESTURE_DRAGSTART &&
gevent.id != GESTURE_DRAG)
break;
if (gevent.x < 0 || gevent.x >= r->width ||
gevent.y < 0 || gevent.y >= r->height)
break;
}
/* gesture is OK */
region = r;
break;
}
regions = SKINOFFSETTOPTR(skin_buffer, regions->next);
}
/* On release, all regions are disarmed. */
if (released)
skin_disarm_touchregions(gwps);
if (temp && temp->press_length == LONG_PRESS)
temp->armed = false;
/* no region - pass the event upward */
if (!region)
return ACTION_TOUCHSCREEN;
if (returncode != ACTION_NONE)
int action = region->action;
region->last_press = tevent.tick;
if (global_settings.party_mode)
{
if (global_settings.party_mode)
switch (action)
{
switch (returncode)
{
case ACTION_WPS_PLAY:
case ACTION_WPS_SKIPPREV:
case ACTION_WPS_SKIPNEXT:
case ACTION_WPS_STOP:
returncode = ACTION_NONE;
break;
default:
break;
}
}
switch (returncode)
{
case ACTION_TOUCH_SOFTLOCK:
data->touchscreen_locked = !data->touchscreen_locked;
returncode = ACTION_NONE;
break;
case ACTION_WPS_PLAY:
if (!audio_status())
{
if ( global_status.resume_index != -1 )
{
if (playlist_resume() != -1)
{
playlist_start(global_status.resume_index,
global_status.resume_elapsed,
global_status.resume_offset);
}
}
else
{
splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
}
}
else
{
wps_do_playpause(false);
}
returncode = ACTION_REDRAW;
break;
case ACTION_WPS_SKIPPREV:
audio_prev();
returncode = ACTION_REDRAW;
break;
case ACTION_WPS_SKIPNEXT:
audio_next();
returncode = ACTION_REDRAW;
break;
case ACTION_WPS_STOP:
audio_stop();
returncode = ACTION_REDRAW;
break;
case ACTION_SETTINGS_INC:
case ACTION_SETTINGS_DEC:
{
const struct settings_list *setting =
temp->setting_data.setting;
option_select_next_val(setting,
returncode == ACTION_SETTINGS_DEC,
true);
returncode = ACTION_REDRAW;
}
case ACTION_WPS_PLAY:
case ACTION_WPS_SKIPPREV:
case ACTION_WPS_SKIPNEXT:
case ACTION_WPS_STOP:
action = ACTION_NONE;
break;
case ACTION_SETTINGS_SET:
{
struct touchsetting *data = &temp->setting_data;
const struct settings_list *s = data->setting;
void (*f)(int) = NULL;
switch (s->flags&F_T_MASK)
{
case F_T_CUSTOM:
s->custom_setting
->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text));
break;
case F_T_INT:
case F_T_UINT:
*(int*)s->setting = data->value.number;
if ((s->flags & F_T_SOUND) == F_T_SOUND)
sound_set(s->sound_setting->setting, data->value.number);
else if (s->flags&F_CHOICE_SETTING)
f = s->choice_setting->option_callback;
else if (s->flags&F_TABLE_SETTING)
f = s->table_setting->option_callback;
else
f = s->int_setting->option_callback;
if (f)
f(data->value.number);
break;
case F_T_BOOL:
*(bool*)s->setting = data->value.number ? true : false;
if (s->bool_setting->option_callback)
s->bool_setting
->option_callback(data->value.number ? true : false);
break;
}
returncode = ACTION_REDRAW;
}
break;
case ACTION_TOUCH_MUTE:
{
const int min_vol = sound_min(SOUND_VOLUME);
if (global_status.volume == min_vol)
global_status.volume = temp->value;
else
{
temp->value = global_status.volume;
global_status.volume = min_vol;
}
setvol();
returncode = ACTION_REDRAW;
}
break;
case ACTION_TOUCH_SHUFFLE: /* toggle shuffle mode */
{
global_settings.playlist_shuffle =
!global_settings.playlist_shuffle;
replaygain_update();
if (global_settings.playlist_shuffle)
playlist_randomise(NULL, current_tick, true);
else
playlist_sort(NULL, true);
returncode = ACTION_REDRAW;
}
break;
case ACTION_TOUCH_REPMODE: /* cycle the repeat mode setting */
{
const struct settings_list *rep_setting =
find_setting(&global_settings.repeat_mode);
option_select_next_val(rep_setting, false, true);
audio_flush_and_reload_tracks();
returncode = ACTION_REDRAW;
}
break;
case ACTION_TOUCH_SETTING:
{
struct progressbar *bar =
SKINOFFSETTOPTR(skin_buffer, temp->bar);
if (bar && edge_offset)
{
int val, count;
get_setting_info_for_bar(bar->setting, bar->setting_offset, &count, &val);
val = *edge_offset * count / 1000;
update_setting_value_from_touch(bar->setting, bar->setting_offset, val);
}
}
default:
break;
}
return returncode;
}
return ACTION_TOUCHSCREEN;
switch (action)
{
case ACTION_TOUCH_SCROLLBAR:
{
action = ACTION_TOUCHSCREEN;
struct wps_state* gwps = get_wps_state();
if (!gwps->id3)
break;
if (gevent.id == GESTURE_HOLD ||
gevent.id == GESTURE_DRAGSTART ||
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);
}
} break;
case ACTION_TOUCH_VOLUME:
{
const int min_vol = sound_min(SOUND_VOLUME);
const int max_vol = sound_max(SOUND_VOLUME);
const int step_vol = sound_steps(SOUND_VOLUME);
global_status.volume = from_normalized_volume(*edge_offset, min_vol, max_vol, 1000);
global_status.volume -= (global_status.volume % step_vol);
setvol();
action = ACTION_TOUCHSCREEN;
} break;
case ACTION_TOUCH_SOFTLOCK:
data->touchscreen_locked = !data->touchscreen_locked;
action = ACTION_NONE;
break;
case ACTION_WPS_PLAY:
if (!audio_status())
{
if ( global_status.resume_index != -1 )
{
if (playlist_resume() != -1)
{
playlist_start(global_status.resume_index,
global_status.resume_elapsed,
global_status.resume_offset);
}
}
else
{
splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
}
}
else
{
wps_do_playpause(false);
}
action = ACTION_REDRAW;
break;
case ACTION_WPS_SKIPPREV:
audio_prev();
action = ACTION_REDRAW;
break;
case ACTION_WPS_SKIPNEXT:
audio_next();
action = ACTION_REDRAW;
break;
case ACTION_WPS_STOP:
audio_stop();
action = ACTION_REDRAW;
break;
case ACTION_SETTINGS_INC:
case ACTION_SETTINGS_DEC:
{
const struct settings_list *setting = region->setting_data.setting;
bool decrement = (action == ACTION_SETTINGS_DEC);
option_select_next_val(setting, decrement, true);
action = ACTION_REDRAW;
} break;
case ACTION_SETTINGS_SET:
{
struct touchsetting *data = &region->setting_data;
const struct settings_list *s = data->setting;
void (*f)(int) = NULL;
switch (s->flags & F_T_MASK)
{
case F_T_CUSTOM:
s->custom_setting
->load_from_cfg(s->setting, SKINOFFSETTOPTR(skin_buffer, data->value.text));
break;
case F_T_INT:
case F_T_UINT:
*(int*)s->setting = data->value.number;
if ((s->flags & F_T_SOUND) == F_T_SOUND)
sound_set(s->sound_setting->setting, data->value.number);
else if (s->flags&F_CHOICE_SETTING)
f = s->choice_setting->option_callback;
else if (s->flags&F_TABLE_SETTING)
f = s->table_setting->option_callback;
else
f = s->int_setting->option_callback;
if (f)
f(data->value.number);
break;
case F_T_BOOL:
*(bool*)s->setting = data->value.number ? true : false;
if (s->bool_setting->option_callback)
s->bool_setting
->option_callback(data->value.number ? true : false);
break;
}
action = ACTION_REDRAW;
} break;
case ACTION_TOUCH_MUTE:
{
const int min_vol = sound_min(SOUND_VOLUME);
if (global_status.volume == min_vol)
global_status.volume = region->value;
else
{
region->value = global_status.volume;
global_status.volume = min_vol;
}
setvol();
action = ACTION_REDRAW;
} break;
case ACTION_TOUCH_SHUFFLE:
global_settings.playlist_shuffle = !global_settings.playlist_shuffle;
replaygain_update();
if (global_settings.playlist_shuffle)
playlist_randomise(NULL, current_tick, true);
else
playlist_sort(NULL, true);
action = ACTION_REDRAW;
break;
case ACTION_TOUCH_REPMODE:
{
const struct settings_list *rep_setting =
find_setting(&global_settings.repeat_mode);
option_select_next_val(rep_setting, false, true);
audio_flush_and_reload_tracks();
action = ACTION_REDRAW;
} break;
case ACTION_TOUCH_SETTING:
{
struct progressbar *bar = SKINOFFSETTOPTR(skin_buffer, region->bar);
if (bar && edge_offset)
{
int val, count;
get_setting_info_for_bar(bar->setting, 0, &count, &val);
val = *edge_offset * count / 1000;
update_setting_value_from_touch(bar->setting, 0, val);
}
action = ACTION_NONE;
} break;
}
return action;
}

View file

@ -27,6 +27,7 @@
#include "tag_table.h"
#include "skin_parser.h"
#include "gesture.h"
#ifndef __PCTOOL__
#include "core_alloc.h"
#endif
@ -218,8 +219,7 @@ struct touchregion {
int16_t hpad; /* padding to height */
bool reverse_bar; /* if true 0% is the left or top */
bool allow_while_locked;
bool armed; /* A region is armed on press. Only armed regions are triggered
on repeat or release. */
bool user_region; /* if true this is a user-defined region */
enum {
PRESS, /* quick press only */
LONG_PRESS, /* Long press without repeat */
@ -371,6 +371,7 @@ struct wps_data
#ifdef HAVE_TOUCHSCREEN
bool touchscreen_locked;
OFFSETTYPE(struct skin_token_list *) touchregions;
struct gesture gesture;
#endif
#ifdef HAVE_ALBUMART
OFFSETTYPE(struct skin_albumart *) albumart;

View file

@ -170,7 +170,6 @@ void wps_do_action(enum wps_do_action_type action, bool updatewps)
static int skintouch_to_wps(void)
{
int offset = 0;
struct wps_state *gstate = get_wps_state();
struct gui_wps *gwps = skin_get_gwps(WPS, SCREEN_MAIN);
int button = skin_get_touchaction(gwps, &offset);
switch (button)
@ -193,22 +192,6 @@ static int skintouch_to_wps(void)
case ACTION_STD_HOTKEY:
return ACTION_WPS_HOTKEY;
#endif
case ACTION_TOUCH_SCROLLBAR:
gstate->id3->elapsed = gstate->id3->length*offset/1000;
audio_pre_ff_rewind();
audio_ff_rewind(gstate->id3->elapsed);
return ACTION_TOUCHSCREEN;
case ACTION_TOUCH_VOLUME:
{
const int min_vol = sound_min(SOUND_VOLUME);
const int max_vol = sound_max(SOUND_VOLUME);
const int step_vol = sound_steps(SOUND_VOLUME);
global_status.volume = from_normalized_volume(offset, min_vol, max_vol, 1000);
global_status.volume -= (global_status.volume % step_vol);
setvol();
}
return ACTION_TOUCHSCREEN;
}
return button;
}

View file

@ -249,6 +249,7 @@ enum yesno_res gui_syncyesno_run_w_tmo(int ticks, enum yesno_res tmo_default_res
/* switch to point mode because that's more intuitive */
enum touchscreen_mode old_mode = touchscreen_get_mode();
touchscreen_set_mode(TOUCHSCREEN_POINT);
action_gesture_reset();
#endif
/* make sure to eat any extranous keypresses */
@ -277,22 +278,20 @@ enum yesno_res gui_syncyesno_run_w_tmo(int ticks, enum yesno_res tmo_default_res
{
#ifdef HAVE_TOUCHSCREEN
case ACTION_TOUCHSCREEN:
{
struct gesture_event gevent;
if (action_gesture_get_event_in_vp(&gevent, &yn[0].vp) &&
gevent.id == GESTURE_TAP)
{
int btn;
short int x, y;
btn = action_get_touchscreen_press_in_vp(&x, &y, &(yn[0].vp));
if (btn == BUTTON_REL)
if (gevent.y > yn[0].vp.height/2)
{
if (y > yn[0].vp.height/2)
{
if (x <= yn[0].vp.width/2)
result = YESNO_YES;
else
result = YESNO_NO;
}
if (gevent.x <= yn[0].vp.width/2)
result = YESNO_YES;
else
result = YESNO_NO;
}
}
break;
} break;
#endif
case ACTION_YESNO_ACCEPT:
result = YESNO_YES;

View file

@ -3890,13 +3890,13 @@
rtc: "OFF:取消"
aigoerosq,erosqnative,gigabeats,sansafuzeplus,xduoox3*: "BACK:取消"
gigabeatfx: "POWER:取消"
mrobe500: "电源:取消"
gogearsa9200: "LEFT:取消"
iaudiom5,iaudiox5: "RECORD:取消"
ipod*,mpiohd300,sansac200*: "MENU:取消"
iriverh10,iriverh10_5gb,sansae200*,sansafuze*: "PREV:取消"
iriverh100,iriverh120,iriverh300: "STOP:取消"
mrobe100: "DISPLAY:取消"
mrobe500: "电源:取消"
samsungyh*: "REW:取消"
vibe500: "CANCEL:取消"
</dest>
@ -16924,3 +16924,71 @@
*: "按专辑排序的所有乐曲"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC
desc: in settings_menu
user: core
<source>
*: none
usbdac: "USB-DAC"
</source>
<dest>
*: none
usbdac: "~USB-DAC"
</dest>
<voice>
*: none
usbdac: "U S B D A C 功能"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_USB_CHARGE_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Charge-Only Mode"
</source>
<dest>
*: none
usbdac: "仅在仅充电模式下启用"
</dest>
<voice>
*: none
usbdac: "仅在仅充电模式下启用"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_MASS_STORAGE_USB_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Mass-Storage Mode"
</source>
<dest>
*: none
usbdac: "仅在大容量存储模式下启用"
</dest>
<voice>
*: none
usbdac: "仅在大容量存储模式下启用"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC_ACTIVE
desc: for splash
user: core
<source>
*: none
usbdac: "USB-DAC Active"
</source>
<dest>
*: none
usbdac: "USB-DAC 工作中"
</dest>
<voice>
*: none
usbdac: "USB-DAC 工作中"
</voice>
</phrase>

View file

@ -32,6 +32,7 @@
# - Dmitry Prozorov
# - Fedor Pomazkov
# - Vladislav Voronichev
# - Ivan Romaniuk-Mikhailovsky
<phrase>
id: LANG_SET_BOOL_YES
desc: bool true representation
@ -138,10 +139,10 @@
*: "Failed"
</source>
<dest>
*: "Сбой"
*: "не удалось"
</dest>
<voice>
*: "Сбой"
*: "не удалось"
</voice>
</phrase>
<phrase>
@ -466,10 +467,10 @@
*: "File View"
</source>
<dest>
*: "Показ файлов"
*: "Отображение файлов"
</dest>
<voice>
*: "Показ файлов"
*: "Отображение файлов"
</voice>
</phrase>
<phrase>
@ -550,7 +551,7 @@
*: "Browse .cfg Files"
</source>
<dest>
*: "Выбор профиля настроек "
*: "Выбор профиля настроек"
</dest>
<voice>
*: "Выбор профиля настроек"
@ -1248,10 +1249,10 @@
*: "Show Files"
</source>
<dest>
*: "Показывать файлы"
*: "Отображаемые типы файлов"
</dest>
<voice>
*: "Показывать файлы"
*: "Отображаемые типы файлов"
</voice>
</phrase>
<phrase>
@ -3350,7 +3351,7 @@
</dest>
<voice>
*: none
charging: "Аккумулятор заряжен"
charging: "Аккумулятор заряжается"
</voice>
</phrase>
<phrase>
@ -3408,7 +3409,8 @@
</source>
<dest>
*: "Внутр:"
hibylinux,xduoox3: "микро Эс Ди:"
hibylinux: "~mSD:"
xduoox3: "~mSD1:"
</dest>
<voice>
*: "Внутр"
@ -3429,15 +3431,15 @@
</source>
<dest>
*: none
hibylinux: "ЮСБ:"
multivolume: "ХД1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "микро Эс Ди:"
xduoox3: "микро Эс Ди2:"
hibylinux: "~USB:"
multivolume: "~HD1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "~mSD:"
xduoox3: "~mSD2:"
</dest>
<voice>
*: none
hibylinux: "Ю С Б"
multivolume: "Х Д 1"
multivolume: "жёсткий диск 1"
sansac200*,sansaclipplus,sansae200*,sansafuze*: "микро Эс Ди"
xduoox3: "микро Эс Ди 2"
</voice>
@ -3583,9 +3585,8 @@
</source>
<dest>
*: none
rtc: "ВЫКЛ. = Отмена"
aigoerosq,erosqnative,gigabeats,sansafuzeplus,xduoox3*: "НАЗАД = Отмена"
gigabeatfx,mrobe500: "ВЫКЛ. = Отмена"
gigabeatfx,mrobe500,rtc: "ВЫКЛ. = Отмена"
gogearsa9200: "ЛЕВО = Отмена"
iaudiom5,iaudiox5: "ЗАПИСЬ = Отмена"
ipod*,mpiohd300,sansac200*: "МЕНЮ = Отмена"
@ -3649,7 +3650,7 @@
*: none
iaudiom5,iaudiox5,recording: "Диск заполнен. Нажмите ВЫКЛ. для продолжения."
iriverh100,iriverh120,iriverh300: "Диск заполнен. Нажмите СТОП для продолжения."
samsungyh*: "Диск заполнен. Нажмите LEFT для продолжения."
samsungyh*: "Диск заполнен. Нажмите ВЛЕВО для продолжения."
sansac200*,sansae200*,vibe500: "Диск заполнен. Нажмите ПРЕД. для продолжения."
</dest>
<voice>
@ -3752,11 +3753,11 @@
</source>
<dest>
*: none
alarm: "Проснуться через %d:%02d"
alarm: "Сработает через %d:%02d"
</dest>
<voice>
*: none
alarm: "Проснуться через"
alarm: "Сработает через"
</voice>
</phrase>
<phrase>
@ -3913,7 +3914,7 @@
*: "(VBR)"
</source>
<dest>
*: " (Переменный)"
*: "(Переменный)"
</dest>
<voice>
*: "Переменный"
@ -6105,7 +6106,7 @@
*: "Не могу открыть %s"
</dest>
<voice>
*: ""
*: "Не могу открыть плагин"
</voice>
</phrase>
<phrase>
@ -11473,11 +11474,11 @@
</source>
<dest>
*: none
quickscreen: "Использовать Ярлыки вместо Быстрого меню"
quickscreen: "Использовать ярлыки вместо быстрого меню"
</dest>
<voice>
*: none
quickscreen: "Использовать Ярлыки вместо Быстрого меню"
quickscreen: "Использовать ярлыки вместо быстрого меню"
</voice>
</phrase>
<phrase>
@ -11516,10 +11517,10 @@
*: "Select directories to scan"
</source>
<dest>
*: "Выберите папки для сканирования"
*: "Выбрать папки для сканирования"
</dest>
<voice>
*: "Выберите папки для сканирования"
*: "Выбрать папки для сканирования"
</voice>
</phrase>
<phrase>
@ -11597,11 +11598,11 @@
</source>
<dest>
*: none
es9018: "Обойти"
es9018: "Обход"
</dest>
<voice>
*: none
es9018: "Обойти"
es9018: "Обход"
</voice>
</phrase>
<phrase>
@ -12170,10 +12171,10 @@
*: "Move Item Down"
</source>
<dest>
*: "Переместить Вниз"
*: "Переместить вниз"
</dest>
<voice>
*: "Переместить Вниз"
*: "Переместить вниз"
</voice>
</phrase>
<phrase>
@ -12184,10 +12185,10 @@
*: "Load Default Configuration"
</source>
<dest>
*: "Загрузить Исходную Конфигурацию"
*: "Загрузить исходную конфигурацию"
</dest>
<voice>
*: "Загрузить Исходную Конфигурацию"
*: "Загрузить исходную конфигурацию"
</voice>
</phrase>
<phrase>
@ -12198,10 +12199,10 @@
*: "Save and Exit"
</source>
<dest>
*: "Сохранить и Выйти"
*: "Сохранить и выйти"
</dest>
<voice>
*: "Сохранить и Выйти"
*: "Сохранить и выйти"
</voice>
</phrase>
<phrase>
@ -12633,10 +12634,10 @@
*: "Worm Speed"
</source>
<dest>
*: "Скорость Червя"
*: "Скорость червя"
</dest>
<voice>
*: "Скорость Червя"
*: "Скорость червя"
</voice>
</phrase>
<phrase>
@ -12961,10 +12962,10 @@
*: "Toggle Slideshow Mode"
</source>
<dest>
*: "Режим слайд-шоу"
*: "Слайд-шоу"
</dest>
<voice>
*: "Режим слайд-шоу"
*: "Слайд-шоу"
</voice>
</phrase>
<phrase>
@ -13503,10 +13504,10 @@
*: "Display FPS"
</source>
<dest>
*: "Кадров в секунду"
*: "Показывать FPS"
</dest>
<voice>
*: "Кадров в секунду"
*: "Показывать FPS"
</voice>
</phrase>
<phrase>
@ -13545,10 +13546,10 @@
*: "Worm Growth Per Food"
</source>
<dest>
*: "Прирост Червя на порцию пищи"
*: "Прирост червя на порцию пищи"
</dest>
<voice>
*: "Прирост Червя на порцию пищи"
*: "Прирост червя на порцию пищи"
</voice>
</phrase>
<phrase>
@ -13588,11 +13589,11 @@
lowmem: none
</source>
<dest>
*: "Ограничение числа кадров в секунду"
*: "Ограничение FPS"
lowmem: none
</dest>
<voice>
*: "Ограничение числа кадров в секунду"
*: "Ограничение FPS"
lowmem: none
</voice>
</phrase>
@ -13894,10 +13895,10 @@
*: "No Rem. Control"
</source>
<dest>
*: "Управление Не с пульта"
*: "Управление не с пульта"
</dest>
<voice>
*: "Управление Не с пульта"
*: "Управление не с пульта"
</voice>
</phrase>
<phrase>
@ -14006,10 +14007,10 @@
*: "No games found !"
</source>
<dest>
*: "Партий не найдено"
*: "Партии не найдены"
</dest>
<voice>
*: "Партий не найдено"
*: "Партии не найдены"
</voice>
</phrase>
<phrase>
@ -14194,10 +14195,10 @@
*: "[Size]"
</source>
<dest>
*: "[Объём]"
*: "[Размер]"
</dest>
<voice>
*: "Объём"
*: "Размер"
</voice>
</phrase>
<phrase>
@ -14639,10 +14640,10 @@
*: "Open Plugin"
</source>
<dest>
*: "Открыть Плагин"
*: "Открыть плагин режима воспроизведения"
</dest>
<voice>
*: "Открыть Плагин"
*: "Открыть плагин режима воспроизведения"
</voice>
</phrase>
<phrase>
@ -14667,10 +14668,10 @@
*: "Set WPS Context Plugin"
</source>
<dest>
*: "Назначить Плагин Режима Воспроизведения"
*: "Назначить плагин режима воспроизведения"
</dest>
<voice>
*: "Назначить Плагин Режима Воспроизведения"
*: "Назначить плагин режима воспроизведения"
</voice>
</phrase>
<phrase>
@ -14981,11 +14982,11 @@
</source>
<dest>
*: none
es9218: "Линейный Быстрый"
es9218: "Линейный быстрый"
</dest>
<voice>
*: none
es9218: "Линейный Быстрый"
es9218: "Линейный быстрый"
</voice>
</phrase>
<phrase>
@ -14998,11 +14999,11 @@
</source>
<dest>
*: none
es9218: "Линейный Медленный"
es9218: "Линейный медленный"
</dest>
<voice>
*: none
es9218: "Линейный Медленный"
es9218: "Линейный медленный"
</voice>
</phrase>
<phrase>
@ -15015,11 +15016,11 @@
</source>
<dest>
*: none
es9218: "Минимальный Быстрый"
es9218: "Минимальный быстрый"
</dest>
<voice>
*: none
es9218: "Минимальный Быстрый"
es9218: "Минимальный быстрый"
</voice>
</phrase>
<phrase>
@ -15032,11 +15033,11 @@
</source>
<dest>
*: none
es9218: "Минимальный Медленный"
es9218: "Минимальный медленный"
</dest>
<voice>
*: none
es9218: "Минимальный Медленный"
es9218: "Минимальный медленный"
</voice>
</phrase>
<phrase>
@ -15083,11 +15084,11 @@
</source>
<dest>
*: none
es9218: "Гибридный Быстрый"
es9218: "Гибридный быстрый"
</dest>
<voice>
*: none
es9218: "Гибридный Быстрый"
es9218: "Гибридный быстрый"
</voice>
</phrase>
<phrase>
@ -15100,11 +15101,11 @@
</source>
<dest>
*: none
es9218: "Кирпичная Стена"
es9218: "Кирпичная стена"
</dest>
<voice>
*: none
es9218: "Кирпичная Стена"
es9218: "Кирпичная стена"
</voice>
</phrase>
<phrase>
@ -15373,10 +15374,10 @@
*: "Play"
</source>
<dest>
*: "Проиграть"
*: "Воспроизвести"
</dest>
<voice>
*: "Проиграть"
*: "Воспроизвести"
</voice>
</phrase>
<phrase>
@ -15387,10 +15388,10 @@
*: "Play Shuffled"
</source>
<dest>
*: "Проиграть в случайном порядке"
*: "Воспроизвести в случайном порядке"
</dest>
<voice>
*: "Проиграть в случайном порядке"
*: "Воспроизвести в случайном порядке"
</voice>
</phrase>
<phrase>
@ -15401,10 +15402,10 @@
*: "Keep Current Track When Replacing Playlist"
</source>
<dest>
*: "Сохранять текущий трек при замене списка проигрывания"
*: "Сохранять текущий трек при замене списка воспроизведения"
</dest>
<voice>
*: "Сохранять текущий трек при замене списка проигрывания"
*: "Сохранять текущий трек при замене списка воспроизведения"
</voice>
</phrase>
<phrase>
@ -15449,10 +15450,10 @@
*: "Set As..."
</source>
<dest>
*: "Установить как..."
*: "Выбрать как..."
</dest>
<voice>
*: "Установить как"
*: "Выбрать как"
</voice>
</phrase>
<phrase>
@ -15463,10 +15464,10 @@
*: "Playlist Directory"
</source>
<dest>
*: "Каталог списков проигрывания"
*: "Папку списков воспроизведения"
</dest>
<voice>
*: "Каталог списков проигрывания"
*: "Папку списков воспроизведения"
</voice>
</phrase>
<phrase>
@ -15564,10 +15565,10 @@
*: "Add Shuffled"
</source>
<dest>
*: "Добавить случайный трек"
*: "Добавить с перемешиванием"
</dest>
<voice>
*: "Добавить случайный трэк"
*: "Добавить с перемешиванием"
</voice>
</phrase>
<phrase>
@ -15715,11 +15716,11 @@
</source>
<dest>
*: none
filter_roll_off: "Короткий Острый"
filter_roll_off: "Короткий острый"
</dest>
<voice>
*: none
filter_roll_off: "Короткий Острый"
filter_roll_off: "Короткий острый"
</voice>
</phrase>
<phrase>
@ -15732,11 +15733,11 @@
</source>
<dest>
*: none
filter_roll_off: "Короткий Медленный"
filter_roll_off: "Короткий медленный"
</dest>
<voice>
*: none
filter_roll_off: "Короткий Медленный"
filter_roll_off: "Короткий медленный"
</voice>
</phrase>
<phrase>
@ -15809,10 +15810,10 @@
*: "Database Directory"
</source>
<dest>
*: "Каталог базы данных"
*: "Папка базы данных"
</dest>
<voice>
*: "Каталог базы данных"
*: "Папка базы данных"
</voice>
</phrase>
<phrase>
@ -15837,10 +15838,10 @@
*: "Quick (Ignore Directory Cache)"
</source>
<dest>
*: "Quick (игнорировать кэш каталогов)"
*: "Быстро (игнорировать кэш папок)"
</dest>
<voice>
*: "Quick (игнорировать кэш каталогов)"
*: "Быстро (игнорировать кэш папок)"
</voice>
</phrase>
<phrase>
@ -15851,10 +15852,10 @@
*: "What's Playing Screen"
</source>
<dest>
*: "Что происходит на экране воспроизведения"
*: "Экран воспроизведения"
</dest>
<voice>
*: "Что происходит на экране воспроизведения"
*: "Экран воспроизведения"
</voice>
</phrase>
<phrase>
@ -15893,10 +15894,10 @@
*: "Set Maze Size"
</source>
<dest>
*: "Установить размер Maze "
*: "Установить размер лабиринта"
</dest>
<voice>
*: "Установить размер Maze "
*: "Установить размер лабиринта"
</voice>
</phrase>
<phrase>
@ -15949,10 +15950,10 @@
*: "Remember Path"
</source>
<dest>
*: "Запомнить путь"
*: "Запоминать путь"
</dest>
<voice>
*: "Запомнить путь"
*: "Запоминать путь"
</voice>
</phrase>
<phrase>
@ -15963,10 +15964,10 @@
*: "Use Large Tiles"
</source>
<dest>
*: "Используйте большие Tiles"
*: "Увеличенный масштаб карты"
</dest>
<voice>
*: "Используйте большие Tiles"
*: "Увеличенный масштаб карты"
</voice>
</phrase>
<phrase>
@ -16005,10 +16006,10 @@
*: "Generating maze..."
</source>
<dest>
*: "Создать лабиринт"
*: "Создание лабиринта..."
</dest>
<voice>
*: "Создать лабиринт"
*: "Создание лабиринта"
</voice>
</phrase>
<phrase>
@ -16103,10 +16104,10 @@
*: "Legal Notices"
</source>
<dest>
*: "официальное уведомление"
*: "Юридическое уведомление"
</dest>
<voice>
*: "официальное уведомление"
*: "Юридическое уведомление"
</voice>
</phrase>
<phrase>
@ -16131,10 +16132,10 @@
*: "Mikmod Settings"
</source>
<dest>
*: "Mikmod Настройки"
*: "Настройки Mikmod"
</dest>
<voice>
*: "Mik mod Настройки"
*: "Настройки Mik mod"
</voice>
</phrase>
<phrase>
@ -16145,10 +16146,10 @@
*: "Mikmod Menu"
</source>
<dest>
*: "Mikmod Меню"
*: "Меню Mikmod"
</dest>
<voice>
*: "Mik mod Меню"
*: "Меню Mik mod"
</voice>
</phrase>
<phrase>
@ -16159,10 +16160,10 @@
*: "Chessbox Menu"
</source>
<dest>
*: "Шахматы меню"
*: "Меню Chessbox"
</dest>
<voice>
*: "Шахматы меню"
*: "Меню Chessbox"
</voice>
</phrase>
<phrase>
@ -16229,10 +16230,10 @@
*: "Remaining"
</source>
<dest>
*: "Оставшийся"
*: "Оставшееся"
</dest>
<voice>
*: "Оставшийся"
*: "Оставшееся"
</voice>
</phrase>
<phrase>
@ -16271,10 +16272,10 @@
*: "Reset EQ"
</source>
<dest>
*: "Сбросить Эквалайзер"
*: "Сбросить эквалайзер"
</dest>
<voice>
*: "Сбросить Эквалайзер"
*: "Сбросить эквалайзер"
</voice>
</phrase>
<phrase>
@ -16299,10 +16300,10 @@
*: "View Album Art"
</source>
<dest>
*: "Просмотреть Обложку Альбома"
*: "Просмотреть обложку"
</dest>
<voice>
*: "Просмотреть Обложку Альбома"
*: "Просмотреть обложку"
</voice>
</phrase>
<phrase>
@ -16677,10 +16678,10 @@
*: "Most played (Plays|Score)"
</source>
<dest>
*: "Наиболее воспроизведённые (Воспроизведения|Рейтинг)"
*: "Наиболее игравшие (Число проигрываний|Рейтинг)"
</dest>
<voice>
*: "Наиболее воспроизведённые по проигрываниям затем по рейтингу"
*: "Наиболее игравшие по проигрываниям затем по рейтингу"
</voice>
</phrase>
<phrase>
@ -16691,10 +16692,10 @@
*: "Recently played tracks"
</source>
<dest>
*: "Недавно воспроизведённые треки"
*: "Недавно игравшие треки"
</dest>
<voice>
*: "Недавно воспроизведённые трэки"
*: "Недавно игравшие трэки"
</voice>
</phrase>
<phrase>
@ -16705,10 +16706,10 @@
*: "Never played tracks"
</source>
<dest>
*: "Никогда не воспроизведённые треки"
*: "Никогда не игравшие треки"
</dest>
<voice>
*: "Никогда не воспроизведённые трэки"
*: "Никогда не игравшие трэки"
</voice>
</phrase>
<phrase>
@ -16916,3 +16917,85 @@
*: "Сортировать плейлисты"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC
desc: in settings_menu
user: core
<source>
*: none
usbdac: "USB-DAC"
</source>
<dest>
*: none
usbdac: "USB-ЦАП"
</dest>
<voice>
*: none
usbdac: "USB ЦАП"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_USB_CHARGE_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Charge-Only Mode"
</source>
<dest>
*: none
usbdac: "В режиме только зарядки"
</dest>
<voice>
*: none
usbdac: "В режиме только зарядки"
</voice>
</phrase>
<phrase>
id: LANG_WHILE_MASS_STORAGE_USB_ONLY
desc: in settings_menu
user: core
<source>
*: none
usbdac: "While In USB Mass-Storage Mode"
</source>
<dest>
*: none
usbdac: "В режиме устройства хранения информации"
</dest>
<voice>
*: none
usbdac: "В режиме устройства хранения информации"
</voice>
</phrase>
<phrase>
id: LANG_USB_DAC_ACTIVE
desc: for splash
user: core
<source>
*: none
usbdac: "USB-DAC Active"
</source>
<dest>
*: none
usbdac: "Активен USB-ЦАП"
</dest>
<voice>
*: none
usbdac: "Активен USB ЦАП"
</voice>
</phrase>
<phrase>
id: LANG_TAGNAVI_ALL_TRACKS_SORTED_BY_ALBUM
desc: "[By album]" entry in tag browser
user: core
<source>
*: "[By album]"
</source>
<dest>
*: "[По альбому]"
</dest>
<voice>
*: "Все трэки сортируются по альбому"
</voice>
</phrase>

View file

@ -141,7 +141,7 @@
#endif
#endif
#if (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA))
#if (CONFIG_PLATFORM & PLATFORM_SDL)
#ifdef SIMULATOR
#include "sim_tasks.h"
#endif
@ -151,7 +151,7 @@
#if defined(WIN32)
#undef main
#endif
#endif /* SDL|MAEMO|PAMDORA */
#endif /* SDL */
/*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
@ -660,8 +660,8 @@ static void init(void)
for (int i = 0 ; i < NUM_VOLUMES ; i++) {
disk_partinfo(i, &pinfo);
if (pinfo.type)
lcd_putsf(0, line++, "P%d T%02x S%08lx",
i, pinfo.type, pinfo.size);
lcd_putsf(0, line++, "P%d T%02x S%llx",
i, pinfo.type, (unsigned long long)pinfo.size);
}
lcd_update();

View file

@ -639,7 +639,7 @@ static void lo_unplug_change(bool inserted)
long default_event_handler_ex(long event, void (*callback)(void *), void *parameter)
{
#if CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO)
#if CONFIG_PLATFORM & (PLATFORM_ANDROID)
static bool resume = false;
#endif
@ -737,7 +737,7 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame
lo_unplug_change(false);
return SYS_LINEOUT_UNPLUGGED;
#endif
#if CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO)
#if CONFIG_PLATFORM & (PLATFORM_ANDROID)
/* stop playback if we receive a call */
case SYS_CALL_INCOMING:
resume = audio_status() == AUDIO_STATUS_PLAY;

View file

@ -892,6 +892,8 @@ static bool onplay_load_plugin(void *param)
onplay_result = ONPLAY_PLUGIN;
else if (ret == PLUGIN_GOTO_WPS)
onplay_result = ONPLAY_START_PLAY;
else if (ret == PLUGIN_GOTO_ROOT)
onplay_result = ONPLAY_MAINMENU;
return false;
}

View file

@ -62,6 +62,10 @@
#include "usbstack/usb_hid.h"
#endif
#ifdef USB_ENABLE_AUDIO
#include "usbstack/usb_audio.h"
#endif
#define WRAPPER(_x_) _x_ ## _wrapper
#if (CONFIG_PLATFORM & PLATFORM_HOSTED)
@ -567,6 +571,8 @@ static const struct plugin_api rockbox_api = {
_ctype_,
#endif
atoi,
strtol,
strtoul,
strchr,
strcat,
strlcat,
@ -845,6 +851,23 @@ static const struct plugin_api rockbox_api = {
add_playbacklog,
&device_battery_tables,
yesno_pop_confirm,
#ifdef USB_ENABLE_AUDIO
usb_audio_get_playing,
#endif
#ifdef HAVE_TOUCHSCREEN
action_get_touch_event,
action_gesture_reset,
action_gesture_get_event_in_vp,
action_gesture_get_event,
action_gesture_is_valid,
action_gesture_is_pressed,
gesture_reset,
gesture_process,
gesture_get_event_in_vp,
gesture_vel_reset,
gesture_vel_process,
gesture_vel_get,
#endif
};
static int plugin_buffer_handle;

View file

@ -74,6 +74,7 @@ int plugin_open(const char *plugin, const char *parameter);
#include "thread.h"
#include "button.h"
#include "action.h"
#include "gesture.h"
#include "load_code.h"
#include "usb.h"
#include "font.h"
@ -190,6 +191,7 @@ enum plugin_status {
PLUGIN_POWEROFF,
PLUGIN_GOTO_WPS,
PLUGIN_GOTO_PLUGIN,
PLUGIN_GOTO_ROOT,
PLUGIN_ERROR = -1,
};
@ -656,6 +658,8 @@ struct plugin_api {
const unsigned char *_rbctype_;
#endif
int (*atoi)(const char *str);
long int (*strtol)(const char *ptr, char **endptr, int base);
unsigned long int (*strtoul)(const char *ptr, char **endptr, int base);
char *(*strchr)(const char *s, int c);
char *(*strcat)(char *s1, const char *s2);
size_t (*strlcat)(char *dst, const char *src, size_t length);
@ -994,6 +998,27 @@ struct plugin_api {
void (*add_playbacklog)(struct mp3entry *id3);
struct battery_tables_t *device_battery_tables;
bool (*yesno_pop_confirm)(const char* text);
#ifdef USB_ENABLE_AUDIO
bool (*usb_audio_get_playing)(void);
#endif
#ifdef HAVE_TOUCHSCREEN
int (*action_get_touch_event)(struct touchevent *ev);
void (*action_gesture_reset)(void);
bool (*action_gesture_get_event_in_vp)(struct gesture_event *gevt,
const struct viewport *vp);
bool (*action_gesture_get_event)(struct gesture_event *gevt);
bool (*action_gesture_is_valid)(void);
bool (*action_gesture_is_pressed)(void);
void (*gesture_reset)(struct gesture *g);
void (*gesture_process)(struct gesture *g, const struct touchevent *ev);
bool (*gesture_get_event_in_vp)(struct gesture *g,
struct gesture_event *gevt,
const struct viewport *vp);
void (*gesture_vel_reset)(struct gesture_vel *gv);
void (*gesture_vel_process)(struct gesture_vel *gv,
const struct touchevent *ev);
bool (*gesture_vel_get)(struct gesture_vel *gv, int *xvel, int *yvel);
#endif
};
/* plugin header */

View file

@ -2882,7 +2882,7 @@ boolean deh_GetData(char *s, char *k, uint_64_t *l, char **strval, int fpout)
okrc = FALSE;
}
// we've incremented t
val = atoi(t);//strtol(t,NULL,0); // killough 8/9/98: allow hex or octal input
val = strtol(t,NULL,0); // killough 8/9/98: allow hex or octal input
}
// go put the results in the passed pointers

View file

@ -87,6 +87,7 @@ int my_close(int id);
#define srand(a) rb->srand((a))
#define rand() rb->rand()
#define atoi(a) rb->atoi((a))
#define strtol(a,b,c) rb->strtol((a),(b),(c))
#define strcat(a,b) rb->strcat((a),(b))
#define snprintf rb->snprintf

View file

@ -850,8 +850,8 @@ static void cleanup(void *parameter)
static void menu_action_printcell(int *action, int selected_item, bool* exit, struct gui_synclist *lists)
{
(void) exit;
struct printcell_data_t *pc_data = (struct printcell_data_t*) lists->data;
static int last_action = ACTION_NONE;
if (*action == ACTION_STD_OK)
{
if (selected_item < lists->nb_items)
@ -860,6 +860,11 @@ static void menu_action_printcell(int *action, int selected_item, bool* exit, st
*action = ACTION_NONE;
}
}
else if (*action == ACTION_STD_CANCEL && last_action == ACTION_STD_CANCEL)
{
/* allow user to hold cancel to quit */
*exit = true;
}
else if (*action == ACTION_STD_CANCEL)
{
pc_data->view_lastcol = printcell_increment_column(-1, true);
@ -874,6 +879,7 @@ static void menu_action_printcell(int *action, int selected_item, bool* exit, st
if (ctxret == QUIT_CONTEXT_MENU)
*exit = true;
}
last_action = *action;
}
int menu_action_cb(int *action, int selected_item, bool* exit, struct gui_synclist *lists)

View file

@ -50,7 +50,7 @@ if ($def_type eq "rb_defines") {
'^SYS_(TIMEOUT|POWEROFF|BATTERY_UPDATE)$',
'^SYS_USB_(DIS|)CONNECTED$',
'^HOME_DIR$',
'^PLUGIN(_OK|_USB_CONNECTED|_POWEROFF|_GOTO_WPS|_GOTO_PLUGIN)$',
'^PLUGIN(_OK|_USB_CONNECTED|_POWEROFF|_GOTO_WPS|_GOTO_PLUGIN|_GOTO_ROOT|_ERROR)$',
'^PLUGIN_DIR$',
'^PLUGIN(_APPS_|_GAMES_|_)DATA_DIR$',
'^ROCKBOX_DIR$',

View file

@ -51,6 +51,8 @@ my @ported_functions;
# you want to manually port them to Lua. The format is a standard Perl regular
# expression.
my @forbidden_functions = ('^atoi$',
'^strtol$',
'^strtoul$',
'^open$',
'^open_utf8$',
'^close$',

View file

@ -542,8 +542,11 @@
#elif CONFIG_KEYPAD == FIIO_M3K_PAD
#define OSCILLOSCOPE_QUIT BUTTON_POWER
#define OSCILLOSCOPE_DRAWMODE BUTTON_MENU
#define OSCILLOSCOPE_GRAPHMODE_PRE BUTTON_BACK
#define OSCILLOSCOPE_GRAPHMODE (BUTTON_BACK | BUTTON_REPEAT)
#define OSCILLOSCOPE_ADVMODE BUTTON_PLAY
#define OSCILLOSCOPE_ORIENTATION BUTTON_BACK
#define OSCILLOSCOPE_ORIENTATION_PRE BUTTON_BACK
#define OSCILLOSCOPE_ORIENTATION (BUTTON_BACK | BUTTON_REL)
#define OSCILLOSCOPE_PAUSE BUTTON_SELECT
#define OSCILLOSCOPE_SPEED_UP BUTTON_SCROLL_BACK
#define OSCILLOSCOPE_SPEED_DOWN BUTTON_SCROLL_FWD
@ -763,6 +766,8 @@ static bool one_frame_paused = false; /* Allow one frame to be drawn when paused
static long osc_delay; /* delay in 100ths of a tick */
static long osc_delay_error; /* delay fraction error accumulator */
static enum pcm_mixer_channel channel;
/* implementation */
@ -938,7 +943,7 @@ static int last_right;
static void get_peaks(int *left, int *right)
{
static struct pcm_peaks peaks;
rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK,
rb->mixer_channel_calculate_peaks(channel,
&peaks);
*left = peaks.left;
*right = peaks.right;
@ -1501,7 +1506,7 @@ static long anim_waveform_horizontal(void)
long cur_tick = *rb->current_tick;
if (rb->mixer_channel_status(PCM_MIXER_CHAN_PLAYBACK) != CHANNEL_PLAYING)
if (rb->mixer_channel_status(channel) != CHANNEL_PLAYING)
{
osd_lcd_update_prepare();
rb->lcd_hline(0, LCD_WIDTH-1, 1*LCD_HEIGHT/4);
@ -1695,7 +1700,7 @@ static long anim_waveform_vertical(void)
long cur_tick = *rb->current_tick;
if (rb->mixer_channel_status(PCM_MIXER_CHAN_PLAYBACK) != CHANNEL_PLAYING)
if (rb->mixer_channel_status(channel) != CHANNEL_PLAYING)
{
osd_lcd_update_prepare();
rb->lcd_vline(1*LCD_WIDTH/4, 0, LCD_HEIGHT-1);
@ -1838,7 +1843,7 @@ static long anim_waveform_vertical(void)
static void anim_waveform_exit(void)
{
/* Remove any buffer hook */
rb->mixer_channel_set_buffer_hook(PCM_MIXER_CHAN_PLAYBACK, NULL);
rb->mixer_channel_set_buffer_hook(channel, NULL);
#ifdef HAVE_SCHEDULER_BOOSTCTRL
/* Remove our boost */
rb->cancel_cpu_boost();
@ -1906,7 +1911,7 @@ static void graphmode_setup(void)
#ifdef OSCILLOSCOPE_GRAPHMODE
if (osc.graphmode == GRAPH_WAVEFORM)
{
rb->mixer_channel_set_buffer_hook(PCM_MIXER_CHAN_PLAYBACK,
rb->mixer_channel_set_buffer_hook(channel,
waveform_buffer_callback);
#ifdef HAVE_SCHEDULER_BOOSTCTRL
rb->trigger_cpu_boost(); /* Just looks better */
@ -1914,7 +1919,7 @@ static void graphmode_setup(void)
}
else
{
rb->mixer_channel_set_buffer_hook(PCM_MIXER_CHAN_PLAYBACK,
rb->mixer_channel_set_buffer_hook(channel,
NULL);
#ifdef HAVE_SCHEDULER_BOOSTCTRL
rb->cancel_cpu_boost();
@ -1995,16 +2000,27 @@ static void osc_setup(void)
osd_lcd_update();
#endif
#ifdef OSCILLOSCOPE_GRAPHMODE
mixer_sampr = rb->mixer_get_frequency();
#endif
/* Turn off backlight timeout */
backlight_ignore_timeout();
graphmode_setup();
}
#ifdef USB_ENABLE_AUDIO
void switch_channel(enum pcm_mixer_channel new_channel)
{
/* Remove any buffer hook */
rb->mixer_channel_set_buffer_hook(channel, NULL);
channel = new_channel;
#ifdef OSCILLOSCOPE_GRAPHMODE
if (osc.graphmode == GRAPH_WAVEFORM)
rb->mixer_channel_set_buffer_hook(channel, waveform_buffer_callback);
#endif
}
#endif /* USB_ENABLE_AUDIO */
enum plugin_status plugin_start(const void* parameter)
{
bool exit = false;
@ -2012,10 +2028,29 @@ enum plugin_status plugin_start(const void* parameter)
int lastbutton = BUTTON_NONE;
#endif
channel = PCM_MIXER_CHAN_PLAYBACK;
osc_setup();
while (!exit)
{
#ifdef OSCILLOSCOPE_GRAPHMODE
if (osc.graphmode == GRAPH_WAVEFORM)
mixer_sampr = rb->mixer_get_frequency();
#endif
#ifdef USB_ENABLE_AUDIO
if (rb->usb_audio_get_playing())
{
if (channel != PCM_MIXER_CHAN_USBAUDIO)
switch_channel(PCM_MIXER_CHAN_USBAUDIO);
}
else
{
if (channel != PCM_MIXER_CHAN_PLAYBACK)
switch_channel(PCM_MIXER_CHAN_PLAYBACK);
}
#endif /* USB_ENABLE_AUDIO */
long delay = oscilloscope_draw();
if (delay <= 0)

View file

@ -22,7 +22,6 @@ float floor_wrapper(float n);
float atan_wrapper(float x);
float atan2_wrapper(float y, float x);
float sqrt_wrapper(float x);
long strtol_wrapper(const char *nptr, char **endptr, int base);
int64_t strtoq_wrapper(const char *nptr, char **endptr, int base);
uint64_t strtouq_wrapper(const char *nptr, char **endptr, int base);
float pow_wrapper(float x, float y);
@ -66,7 +65,7 @@ double acos_wrapper(double x);
#define strcmp rb->strcmp
#define strcpy rb->strcpy
#define strlen rb->strlen
#define strtol strtol_wrapper
#define strtol rb->strtol
#define strtoq strtoq_wrapper
#define strtouq strtouq_wrapper
#define vsprintf vsprintf_wrapper

View file

@ -437,101 +437,6 @@ double acos_wrapper(double x)
*/
#define CONST const
long strtol_wrapper(CONST char *nptr, char **endptr, int base)
{
register CONST char *s;
register long acc, cutoff;
register int c;
register int neg, any, cutlim;
/*
* Skip white space and pick up leading +/- sign if any.
* If base is 0, allow 0x for hex and 0 for octal, else
* assume decimal; if base is already 16, allow 0x.
*/
s = nptr;
do {
c = (unsigned char) *s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else {
neg = 0;
if (c == '+')
c = *s++;
}
if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
/*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
* a value > 214748364, or equal but the next digit is > 7 (or 8),
* the number is too big, and we will return a range error.
*
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
cutoff = neg ? LONG_MIN : LONG_MAX;
cutlim = cutoff % base;
cutoff /= base;
if (neg) {
if (cutlim > 0) {
cutlim -= base;
cutoff += 1;
}
cutlim = -cutlim;
}
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0)
continue;
if (neg) {
if ((acc < cutoff || acc == cutoff) && c > cutlim) {
any = -1;
acc = LONG_MIN;
} else {
any = 1;
acc *= base;
acc -= c;
}
} else {
if ((acc > cutoff || acc == cutoff) && c > cutlim) {
any = -1;
acc = LONG_MAX;
} else {
any = 1;
acc *= base;
acc += c;
}
}
}
if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
int64_t strtoq_wrapper(CONST char *nptr, char **endptr, int base)
{
return strtol(nptr, endptr, base);

View file

@ -1134,6 +1134,7 @@ static bool browse( char *dst, int dst_size, const char *start )
* In other words, cache_first-1 must be cached before cache_first-2 is cached.
* - there is enough space to store all preview currently displayed.
*/
#if 0 /* Broken crashy caching implementation that renders the font in the list FS#13704 */
static bool browse_fonts( char *dst, int dst_size )
{
#define LINE_SPACE 2
@ -1312,7 +1313,7 @@ static bool browse_fonts( char *dst, int dst_size )
li = tree->filesindir-1;
if( reset_font )
{
// fixme rb->font_load(NULL, bbuf_s );
// fixme rb->font_load(bbuf_s );
reset_font = false;
}
if( lvi-fvi+1 < tree->filesindir )
@ -1386,6 +1387,35 @@ static bool browse_fonts( char *dst, int dst_size )
#undef PREVIEW_SIZE
#undef PREVIEW_NEXT
}
#else /* simple uncached non-rendered fallback */
static bool browse_fonts( char *dst, int dst_size )
{
/* taken from text_viewer */
char font[MAX_PATH], name[MAX_FILENAME+10];
rb->snprintf(name, sizeof(name), "%s.fnt", rb->global_settings->font_file);
struct browse_context browse = {
.dirfilter = SHOW_FONT,
.flags = BROWSE_SELECTONLY | BROWSE_NO_CONTEXT_MENU,
.title = rb->str(LANG_CUSTOM_FONT),
.icon = Icon_Menu_setting,
.root = FONT_DIR,
.selected = name,
.buf = font,
.bufsize = sizeof(font),
//.callback_show_item = &callback_show_font,
};
rb->rockbox_browse(&browse);
if (browse.flags & BROWSE_SELECTED)
{
rb->snprintf( dst, dst_size, "%s", font );
return true;
}
return false;
}
#endif
/***********************************************************************
* HSVRGB Color chooser

View file

@ -117,6 +117,7 @@
#define atexit rb_atexit
#define atof atof_wrapper
#define atoi rb->atoi
#define HAVE_ATOI 1
#define atol atoi
#define calloc tlsf_calloc
#define ceil ceil_wrapper
@ -174,7 +175,8 @@
#define strstr SDL_strstr
#define strtok strtok_wrapper
#define strtok_r rb->strtok_r
#define strtol SDL_strtol
#define HAVE_STRTOL 1
#define strtol rb->strtol
#define tan tan_wrapper
#define time(x) (*rb->current_tick/HZ)
#define unlink remove

View file

@ -50,109 +50,284 @@
# error "No keymap defined!"
#endif
static bool usb_exit = false;
static const struct button_mapping tstest_context[] = {
{ACTION_STD_OK, TOUCHSCREEN_TOGGLE, BUTTON_NONE},
{ACTION_STD_CANCEL, TOUCHSCREEN_QUIT, BUTTON_NONE},
LAST_ITEM_IN_LIST,
};
static const struct button_mapping *get_context_map(int context)
{
(void)context;
return tstest_context;
}
static void draw_tsbutton_rect(int x, int y)
{
int x0 = x*LCD_WIDTH/3;
int y0 = y*LCD_HEIGHT/3;
int x1 = (x+1)*LCD_WIDTH/3;
int y1 = (y+1)*LCD_HEIGHT/3;
rb->lcd_set_foreground(LCD_RGBPACK(0xc0, 0, 0));
rb->lcd_fillrect(x0, y0, x1 - x0, y1 - y0);
}
static void draw_crosshair(int x, int y, unsigned fg)
{
rb->lcd_set_foreground(fg);
rb->lcd_hline(x-7, x+7, y);
rb->lcd_vline(x, y-7, y+7);
}
static void tstest_button_mode(void)
{
rb->splashf(HZ, "Button mode test");
rb->touchscreen_set_mode(TOUCHSCREEN_BUTTON);
int button = BUTTON_NONE;
while (true)
{
rb->lcd_clear_display();
if ((button & BUTTON_TOPLEFT) && !(button & BUTTON_REL))
draw_tsbutton_rect(0, 0);
if ((button & BUTTON_TOPMIDDLE) && !(button & BUTTON_REL))
draw_tsbutton_rect(1, 0);
if ((button & BUTTON_TOPRIGHT) && !(button & BUTTON_REL))
draw_tsbutton_rect(2, 0);
if ((button & BUTTON_MIDLEFT) && !(button & BUTTON_REL))
draw_tsbutton_rect(0, 1);
if ((button & BUTTON_CENTER) && !(button & BUTTON_REL))
draw_tsbutton_rect(1, 1);
if ((button & BUTTON_MIDRIGHT) && !(button & BUTTON_REL))
draw_tsbutton_rect(2, 1);
if ((button & BUTTON_BOTTOMLEFT) && !(button & BUTTON_REL))
draw_tsbutton_rect(0, 2);
if ((button & BUTTON_BOTTOMMIDDLE) && !(button & BUTTON_REL))
draw_tsbutton_rect(1, 2);
if ((button & BUTTON_BOTTOMRIGHT) && !(button & BUTTON_REL))
draw_tsbutton_rect(2, 2);
rb->lcd_update();
if (button & TOUCHSCREEN_QUIT)
break;
if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
{
usb_exit = true;
break;
}
button = rb->button_get(true);
}
}
static void tstest_pointing_mode(void)
{
struct touchevent tevent;
rb->splashf(HZ, "Pointing mode test");
rb->touchscreen_set_mode(TOUCHSCREEN_POINT);
rb->lcd_clear_display();
rb->lcd_update();
while (true)
{
int action = rb->get_custom_action(CONTEXT_PLUGIN, TIMEOUT_BLOCK,
get_context_map);
if (action == ACTION_TOUCHSCREEN)
{
rb->lcd_clear_display();
rb->action_get_touch_event(&tevent);
draw_crosshair(tevent.x, tevent.y, LCD_RGBPACK(0, 0xc0, 0));
rb->lcd_update();
}
else if (action == ACTION_STD_CANCEL)
{
break;
}
else if (rb->default_event_handler(action) == SYS_USB_CONNECTED)
{
usb_exit = true;
break;
}
}
}
static void tstest_gesture(void)
{
static const char *const gesture_names[] = {
[GESTURE_NONE] = "none",
[GESTURE_TAP] = "tap",
[GESTURE_LONG_PRESS] = "long press",
[GESTURE_HOLD] = "hold",
[GESTURE_DRAGSTART] = "dragstart",
[GESTURE_DRAG] = "drag",
[GESTURE_RELEASE] = "release",
};
struct gesture_event gevt;
int gevent_array[10];
int gevent_count = 0;
rb->splashf(HZ, "Gesture test");
rb->touchscreen_set_mode(TOUCHSCREEN_POINT);
rb->lcd_clear_display();
rb->lcd_update();
while (true)
{
int action = rb->get_custom_action(CONTEXT_PLUGIN, TIMEOUT_BLOCK,
get_context_map);
if (action == ACTION_TOUCHSCREEN)
{
rb->lcd_clear_display();
if (rb->action_gesture_get_event_in_vp(&gevt, NULL))
{
if (gevt.id == GESTURE_NONE)
{
gevent_array[gevent_count] = GESTURE_NONE;
gevent_count = 1;
}
if (gevt.id != gevent_array[gevent_count-1])
{
if (gevent_count < (int)ARRAYLEN(gevent_array))
{
gevent_array[gevent_count] = gevt.id;
gevent_count++;
}
}
rb->lcd_set_foreground(LCD_RGBPACK(0xff, 0xff, 0xff));
for (int i = 0; i < gevent_count; ++i)
rb->lcd_puts(0, i, gesture_names[gevent_array[i]]);
draw_crosshair(gevt.x, gevt.y, LCD_RGBPACK(0, 0xc0, 0));
draw_crosshair(gevt.ox, gevt.oy, LCD_RGBPACK(0xc0, 0, 0));
}
rb->lcd_update();
}
else if (action == ACTION_STD_OK)
{
rb->splashf(HZ, "Gesture reset");
rb->action_gesture_reset();
rb->lcd_clear_display();
rb->lcd_update();
}
else if (action == ACTION_STD_CANCEL)
{
break;
}
else if (rb->default_event_handler(action) == SYS_USB_CONNECTED)
{
usb_exit = true;
break;
}
}
}
static void tstest_velocity(void)
{
struct touchevent tevent;
struct gesture_vel gv;
rb->splashf(HZ, "Velocity test");
rb->touchscreen_set_mode(TOUCHSCREEN_POINT);
rb->lcd_clear_display();
rb->lcd_update();
rb->gesture_vel_reset(&gv);
while (true)
{
int action = rb->get_custom_action(CONTEXT_PLUGIN, TIMEOUT_BLOCK,
get_context_map);
if (action == ACTION_TOUCHSCREEN)
{
rb->lcd_clear_display();
rb->action_get_touch_event(&tevent);
rb->gesture_vel_process(&gv, &tevent);
int xvel, yvel;
rb->gesture_vel_get(&gv, &xvel, &yvel);
rb->lcd_set_foreground(LCD_RGBPACK(0xff, 0xff, 0xff));
rb->lcd_putsf(0, 0, "xvel=%4d yvel=%4d", xvel, yvel);
draw_crosshair(tevent.x, tevent.y, LCD_RGBPACK(0, 0xc0, 0));
rb->lcd_update();
if (tevent.type == TOUCHEVENT_RELEASE)
rb->gesture_vel_reset(&gv);
}
else if (action == ACTION_STD_OK)
{
rb->splashf(HZ, "Velocity reset");
rb->gesture_vel_reset(&gv);
rb->lcd_clear_display();
rb->lcd_update();
}
else if (action == ACTION_STD_CANCEL)
{
break;
}
else if (rb->default_event_handler(action) == SYS_USB_CONNECTED)
{
usb_exit = true;
break;
}
}
}
/* plugin entry point */
enum plugin_status plugin_start(const void* parameter)
{
int button = 0;
enum touchscreen_mode mode = TOUCHSCREEN_BUTTON;
/* standard stuff */
(void)parameter;
rb->touchscreen_set_mode(mode);
/* wait until user closes plugin */
do
int sel;
MENUITEM_STRINGLIST(menu, "Touchscreen test",
NULL,
"Button mode test",
"Pointing mode test",
"Gesture test",
"Velocity test",
"Quit");
while (true)
{
short x = 0;
short y = 0;
bool draw_rect = false;
button = rb->button_get(true);
rb->touchscreen_set_mode(rb->global_settings->touch_mode);
switch (rb->do_menu(&menu, &sel, NULL, false))
{
case 0:
tstest_button_mode();
break;
if (button & BUTTON_TOPLEFT)
{
draw_rect = true;
x = 0; y = 0;
}
else if (button & BUTTON_TOPMIDDLE)
{
draw_rect = true;
x = LCD_WIDTH/3; y = 0;
}
else if (button & BUTTON_TOPRIGHT)
{
draw_rect = true;
x = 2*(LCD_WIDTH/3); y = 0;
}
else if (button & BUTTON_MIDLEFT)
{
draw_rect = true;
x = 0; y = LCD_HEIGHT/3;
}
else if (button & BUTTON_CENTER)
{
draw_rect = true;
x = LCD_WIDTH/3; y = LCD_HEIGHT/3;
}
else if (button & BUTTON_MIDRIGHT)
{
draw_rect = true;
x = 2*(LCD_WIDTH/3); y = LCD_HEIGHT/3;
}
else if (button & BUTTON_BOTTOMLEFT)
{
draw_rect = true;
x = 0; y = 2*(LCD_HEIGHT/3);
}
else if (button & BUTTON_BOTTOMMIDDLE)
{
draw_rect = true;
x = LCD_WIDTH/3; y = 2*(LCD_HEIGHT/3);
}
else if (button & BUTTON_BOTTOMRIGHT)
{
draw_rect = true;
x = 2*(LCD_WIDTH/3); y = 2*(LCD_HEIGHT/3);
case 1:
tstest_pointing_mode();
break;
case 2:
tstest_gesture();
break;
case 3:
tstest_velocity();
break;
default:
return PLUGIN_OK;
}
if (button & TOUCHSCREEN_TOGGLE && (button & BUTTON_REL))
{
mode = (mode == TOUCHSCREEN_POINT) ? TOUCHSCREEN_BUTTON : TOUCHSCREEN_POINT;
rb->touchscreen_set_mode(mode);
}
if (button & BUTTON_REL) draw_rect = false;
rb->lcd_clear_display();
if (draw_rect)
{
rb->lcd_set_foreground(LCD_RGBPACK(0xc0, 0, 0));
rb->lcd_fillrect(x, y, LCD_WIDTH/3, LCD_HEIGHT/3);
}
if (draw_rect || button & BUTTON_TOUCHSCREEN)
{
intptr_t button_data = rb->button_get_data();
x = button_data >> 16;
y = button_data & 0xffff;
rb->lcd_set_foreground(LCD_RGBPACK(0, 0, 0xc0));
rb->lcd_fillrect(x-7, y-7, 14, 14);
/* in stylus mode, show REL position in black */
if (mode == TOUCHSCREEN_POINT && (button & BUTTON_REL))
rb->lcd_set_foreground(LCD_BLACK);
else
rb->lcd_set_foreground(LCD_WHITE);
rb->lcd_hline(x-5, x+5, y);
rb->lcd_vline(x, y-5, y+5);
}
rb->lcd_update();
} while (button != TOUCHSCREEN_QUIT);
return PLUGIN_OK;
if (usb_exit)
return PLUGIN_USB_CONNECTED;
}
}

View file

@ -666,7 +666,7 @@ static bool vu_meter_menu(void)
bool menu_quit = false;
bool exit = false;
MENUITEM_STRINGLIST(menu,"VU Meter Menu",NULL,"Meter Type","Scale",
MENUITEM_STRINGLIST(menu,"VU Meter",NULL,"Meter Type","Scale",
"Minimeters","Decay Speed","Playback Control",
"Quit");
@ -811,14 +811,8 @@ static void draw_digital_minimeters(void) {
#endif
}
static void analog_meter(void) {
static struct pcm_peaks peaks;
rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK,
&peaks);
#define left_peak peaks.left
#define right_peak peaks.right
static void draw_analog_meter(uint32_t left_peak, uint32_t right_peak)
{
if(vumeter_settings.analog_use_db_scale) {
left_needle_top_x = analog_db_scale[left_peak * half_width / MAX_PEAK];
right_needle_top_x = analog_db_scale[right_peak * half_width / MAX_PEAK] + half_width;
@ -867,13 +861,8 @@ static void analog_meter(void) {
}
}
static void digital_meter(void) {
static struct pcm_peaks peaks;
rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK,
&peaks);
#define left_peak peaks.left
#define right_peak peaks.right
static void draw_digital_meter(uint32_t left_peak, uint32_t right_peak)
{
if(vumeter_settings.digital_use_db_scale) {
num_left_leds = digital_db_scale[left_peak * 44 / MAX_PEAK];
num_right_leds = digital_db_scale[right_peak * 44 / MAX_PEAK];
@ -933,13 +922,37 @@ static void digital_meter(void) {
rb->lcd_hline(0,LCD_WIDTH-1,half_height+3);
}
static void draw_title(void)
{
static unsigned int sampr;
static int x;
static char title[16];
if (sampr != rb->mixer_get_frequency())
{
sampr = rb->mixer_get_frequency();
if ((sampr % 1000) < 100)
rb->snprintf(title, sizeof title, "VU %d kHz",
sampr / 1000);
else
rb->snprintf(title, sizeof title, "VU %d.%u kHz",
sampr / 1000, (sampr % 1000) / 100);
rb->font_getstringsize(title, &x, NULL, FONT_SYSFIXED);
x = half_width - (x/2); /* centered */
}
rb->lcd_putsxy(x, 0, title);
}
static void vu_meter_cleanup(void)
{
/* Turn on backlight timeout (revert to settings) */
backlight_use_settings();
}
enum plugin_status plugin_start(const void* parameter) {
enum plugin_status plugin_start(const void* parameter)
{
static struct pcm_peaks peaks;
int button;
#if defined(VUMETER_HELP_PRE) || defined(VUMETER_MENU_PRE)
int lastbutton = BUTTON_NONE;
@ -964,12 +977,21 @@ enum plugin_status plugin_start(const void* parameter) {
{
rb->lcd_clear_display();
rb->lcd_putsxy(half_width-23, 0, "VU Meter");
draw_title();
if(vumeter_settings.meter_type==ANALOG)
analog_meter();
#ifdef USB_ENABLE_AUDIO
if (rb->usb_audio_get_playing())
rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_USBAUDIO,
&peaks);
else
digital_meter();
#endif
rb->mixer_channel_calculate_peaks(PCM_MIXER_CHAN_PLAYBACK,
&peaks);
if(vumeter_settings.meter_type == ANALOG)
draw_analog_meter(peaks.left, peaks.right);
else
draw_digital_meter(peaks.left, peaks.right);
rb->lcd_update();

View file

@ -115,7 +115,8 @@ int fms_do_button_loop(bool update_screen)
case ACTION_STD_MENU:
return ACTION_FM_MENU;
case ACTION_TOUCH_SCROLLBAR:
/* TODO */
/* TODO - skin_get_touchaction has this hardcoded to seek in
* current track, refactor it if this is ever implemented. */
break;
}
#endif

View file

@ -808,6 +808,10 @@ static int load_plugin_screen(char *key)
}
continue;
}
else if (ret == PLUGIN_GOTO_ROOT)
{
ret_val = GO_TO_ROOT;
}
else
{
ret_val = GO_TO_PREVIOUS;

View file

@ -480,6 +480,13 @@ static const char graphic_numeric[] = "graphic,numeric";
# define MAX_FILES_IN_DIR_STEP 50
#endif
#ifdef HAVE_TOUCHSCREEN
/* on touchscreen, it makes more sense to put the scrollbar on the right */
# define SCROLLBAR_DEFAULT SCROLLBAR_RIGHT
#else
# define SCROLLBAR_DEFAULT SCROLLBAR_LEFT
#endif
#ifndef __PCTOOL__
#if LCD_DEPTH > 1
@ -1190,7 +1197,7 @@ const struct settings_list settings[] = {
ID2P(LANG_STATUSBAR_BOTTOM)),
#endif
CHOICE_SETTING(F_THEMESETTING|F_TEMPVAR, scrollbar,
LANG_SCROLL_BAR, SCROLLBAR_LEFT, "scrollbar","off,left,right",
LANG_SCROLL_BAR, SCROLLBAR_DEFAULT, "scrollbar","off,left,right",
NULL, 3, ID2P(LANG_OFF), ID2P(LANG_LEFT), ID2P(LANG_RIGHT)),
INT_SETTING(F_THEMESETTING, scrollbar_width, LANG_SCROLLBAR_WIDTH, 6,
"scrollbar width",UNIT_INT, 3, MAX(LCD_WIDTH/10,25), 1,

View file

@ -764,24 +764,15 @@ static int _talk_spell(const char* spell, size_t len, bool enqueue)
do_enqueue(enqueue); /* cut off all the pending stuff */
const char *last = spell;
size_t len0 = len - 1;
/* Tokenize into UTF8 codepoints */
while ((spell = utf8decode(spell, &c)), c != '\0')
{
int count;
if (c <= 0x7f)
count = 1;
else if (c <= 0x7ff)
count = 2;
else if (c <= 0xffff)
count = 3;
else
count = 4;
len0 -= count;
len0 -= (spell - last);
if (len0 >= len) /* ie we underflow and wrap */
break;
last = spell;
/* NOTE: This is COMPLETLY BROKEN for NON-ENGLISH */

View file

@ -121,8 +121,8 @@ void error(int errortype, int error, bool shutdown)
struct partinfo pinfo;
disk_partinfo(i, &pinfo);
if (pinfo.type)
printf("P%d T%02x S%08lx",
i, pinfo.type, pinfo.size);
printf("P%d T%02x S%llx",
i, pinfo.type, (unsigned long long)pinfo.size);
}
#endif
break;

View file

@ -64,6 +64,7 @@
#define ERR_RB 0
#define ERR_OF 1
#define ERR_STORAGE 2
#define ERR_LBA28 3
/* Safety measure - maximum allowed firmware image size.
The largest known current (October 2009) firmware is about 6.2MB so
@ -166,6 +167,10 @@ void fatal_error(int err)
printf("Hold MENU+SELECT to reboot");
printf("and enter Rockbox firmware");
break;
case ERR_LBA28:
printf("Hold MENU+SELECT to reboot");
printf("and LEFT if you are REALLY sure");
break;
}
#if (CONFIG_STORAGE & STORAGE_ATA)
@ -883,11 +888,35 @@ void main(void)
/* We wait until HDD spins up to check for hold button */
if (button_hold()) {
printf("Executing OF...");
bool lba48 = false;
struct SysCfg syscfg;
const ssize_t result = syscfg_read(&syscfg);
if (result != -1) {
const size_t syscfg_num_entries = MIN(syscfg.header.num_entries, SYSCFG_MAX_ENTRIES);
for (size_t i = 0; i < syscfg_num_entries; i++) {
const struct SysCfgEntry* entry = &syscfg.entries[i];
const uint32_t* data32 = (uint32_t *)entry->data;
if (entry->tag == SYSCFG_TAG_HWVR) {
lba48 = (data32[1] >= 0x130200);
break;
}
}
int btn = button_read_device();
struct storage_info sinfo;
storage_get_info(0, &sinfo);
if (sinfo.num_sectors < (1 << 28) || lba48 || btn & BUTTON_LEFT) {
printf("Executing OF...");
#if (CONFIG_STORAGE & STORAGE_ATA)
ata_sleepnow();
ata_sleepnow();
#endif
rc = kernel_launch_onb();
rc = kernel_launch_onb();
} else {
printf("OF does not support LBA48");
fatal_error(ERR_LBA28);
}
}
}
}
@ -925,8 +954,8 @@ void main(void)
for (int i = 0 ; i < NUM_VOLUMES ; i++) {
disk_partinfo(i, &pinfo);
if (pinfo.type)
printf("P%d T%02x S%08lx",
i, pinfo.type, pinfo.size);
printf("P%d T%02x S%llx",
i, pinfo.type, (unsigned long long)pinfo.size);
}
fatal_error(ERR_RB);
}

View file

@ -377,8 +377,8 @@ void* main(void)
for (int i = 0 ; i < NUM_VOLUMES ; i++) {
disk_partinfo(i, &pinfo);
if (pinfo.type)
printf("P%d T%02x S%08lx",
i, pinfo.type, pinfo.size);
printf("P%d T%02x S%lllx",
i, pinfo.type, (unsigned long long)pinfo.size);
}
printf("No partition found");

View file

@ -567,8 +567,8 @@ void main(void)
for (int i = 0 ; i < NUM_VOLUMES ; i++) {
disk_partinfo(i, &pinfo);
if (pinfo.type)
printf("P%d T%02x S%08lx",
i, pinfo.type, pinfo.size);
printf("P%d T%02x S%llx",
i, pinfo.type, (unsigned long long)pinfo.size);
}
while(button_get(true) != SYS_USB_CONNECTED) {};
}

View file

@ -627,8 +627,8 @@ void main(void)
for (int i = 0 ; i < NUM_VOLUMES ; i++) {
disk_partinfo(i, &pinfo);
if (pinfo.type)
printf("P%d T%02x S%08lx",
i, pinfo.type, pinfo.size);
printf("P%d T%02x S%llx",
i, pinfo.type, (unsigned long long)pinfo.size);
}
while(button_get(true) != SYS_USB_CONNECTED) {};
}

View file

@ -1,7 +0,0 @@
rockbox 3.13.x for Maemo
--------------------------
Rockbox for maemo technial preview release.
Known issues:
- Application exit is only possible with CTRL+BACKSPACE

113
debian/changelog vendored
View file

@ -1,113 +0,0 @@
rockbox (2013-03-10maemo1) unstable; urgency=low
* Update to rockbox 3.13 code base (v3.13-final)
-- Thomas Jarosch <tomj@simonv.com> Sun, 10 Mar 2013 19:00:00 +0100
rockbox (2012-12-26maemo1) unstable; urgency=low
* Update to rockbox 3.12 code base (v3.12-final)
-- Thomas Jarosch <tomj@simonv.com> Wed, 26 Dec 2012 19:00:00 +0100
rockbox (2011-12-10maemo1) unstable; urgency=low
* Update to rockbox 3.10 code base (r31165)
* Patch: Added software mixer performance fix on N900
* Patch: Added pcm locking code on N900
* Patch: Assembler optimized software mixing (FS #12421)
-- Thomas Jarosch <tomj@simonv.com> Sat, 10 Dec 2011 19:00:00 +0100
rockbox (2011-06-28maemo1) unstable; urgency=low
* Update to rockbox 3.9 code base
-- Thomas Jarosch <tomj@simonv.com> Tue, 28 Jun 2011 19:00:00 +0100
rockbox (2011-04-16maemo1) unstable; urgency=low
* Fix premature idle shutdown after last track finished playing
* Update to latest rockbox SVN code
-- Thomas Jarosch <tomj@simonv.com> Fri, 16 Apr 2011 19:15:00 +0100
rockbox (2011-03-18maemo0) unstable; urgency=low
* Implemented RTC support (timestamps in last.FM scrobbler log)
* Working sleep timer
* Working idle poweroff
* Support for antialised fonts (not in use yet)
* Update to latest rockbox SVN code
-- Thomas Jarosch <tomj@simonv.com> Fri, 18 Mar 2011 22:00:00 +0100
rockbox (2011-02-27maemo0) unstable; urgency=low
* Fix/enable assembler optimizations on public build
* Change play/pause button so that it shows
the click action and not the current state
-- Thomas Jarosch <tomj@simonv.com> Sun, 27 Feb 2011 19:00:00 +0100
rockbox (2011-02-25maemo0) unstable; urgency=low
* Embedded album art support
* Fixed bookmark handling
* Prevent stuck up/down buttons on N900 with shared cursor keys
* Fixed Last.FM scrobbler log file
* New threading code uses less CPU
* Fix rare hang on shutdown
* Small fixes to the metadata parser
* Update to rockbox SVN code
-- Thomas Jarosch <tomj@simonv.com> Fri, 25 Feb 2011 18:10:00 +0100
rockbox (2011-01-26maemo0) unstable; urgency=low
* Bluetooth headset support
* Ignore preinstalled sounds in /usr/share/sounds
-- Thomas Jarosch <tomj@simonv.com> Wed, 26 Jan 2011 22:50:00 +0100
rockbox (2011-01-12maemo0) unstable; urgency=low
* Always show prev/next track button
* Bind enter key to rockbock's center button (all platforms)
* Bind more keys on n8xx (maemo4)
* Update to latest rockbox SVN code
-- Thomas Jarosch <tomj@simonv.com> Wed, 12 Jan 2011 19:42:00 +0100
rockbox (2011-01-04maemo0) unstable; urgency=low
* Update to latest rockbox SVN code (regenerates the database)
* Test automatic garage build
* Fix x86 build targets
-- Thomas Jarosch <tomj@simonv.com> Tue, 04 Jan 2011 00:20:00 +0100
rockbox (2011-01-02maemo0) unstable; urgency=low
* New version number to indicate this build is work in progress
-- Thomas Jarosch <tomj@simonv.com> Sun, 02 Jan 2011 00:05:00 +0100
rockbox (3.7.2maemo2) unstable; urgency=low
* Fix duplicate database entries
* Initial rockbox plugin support:
- Small tools in the context menu
- mikmod (.mod, .s3m, .xm etc) support
- Credits screen
-- Thomas Jarosch <tomj@simonv.com> Sat, 01 Jan 2011 19:01:00 +0100
rockbox (3.7.2maemo1) unstable; urgency=low
* Initial release for Nokia N900
-- Thomas Jarosch <tomj@simonv.com> Thu, 30 Dec 2010 16:18:05 +0100

1
debian/compat vendored
View file

@ -1 +0,0 @@
5

82
debian/control vendored
View file

@ -1,82 +0,0 @@
Source: rockbox
Section: user/multimedia
Priority: extra
Maintainer: Thomas Jarosch <tomj@simonv.com>
Build-Depends: debhelper (>= 5), pkg-config, maemo-version-dev,
libosso-dev, libglib2.0-dev, libhal-dev, osso-af-settings,
libsdl1.2-dev, libxml2-dev,
libgstreamer0.10-dev | maemo-version-dev (<= 5),
libgstreamer-plugins-base0.10-dev | maemo-version-dev (<= 5),
libgstreamer-plugins-base0.10-dev | maemo-version-dev (<= 5),
libplayback-1-dev | maemo-version-dev (<= 5)
# Note: This is the -debian- standards version, not rockbox
Standards-Version: 3.7.2
Package: rockbox
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Rockbox open source high quality audio player
XB-Maemo-Display-Name: Rockbox audio player
XB-Maemo-Upgrade-Description: Update to rockbox 3.13 code base
XSBC-Bugtracker: http://www.rockbox.org/tracker/
XB-Maemo-Icon-26:
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c
6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0
SU1FB9oKHhIPE5mDh+sAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJ
TVBXgQ4XAAAH/ElEQVRo3s2aeZBU1RXGf/e+13v3rD0Dw4DiBA3FHpICVJZQ
MiJLKKJsUikiREoxKROIKYiKSkUSQ0QhAUPASkJRRmPCEoOFKDjUIBBCWFSs
IGCIEGFg9n2mu9+9+eP1DN0wg3T3zMCt+qq7Xt/13Hu+77zTV2AXCTgBL+AB
HNFngpujaEABYaARaACaAW1GJ+kFcr53L4NmjGRUupdswEDfJNMXgMaqbqDs
jWI++MNuPgJKgXoTcAE5zzzI5EX3s9gXJGi4cYqbx/r2Fmi01UxoeD9m9czh
lz97g+1AxADSZo7i68/P4ecZt9JTujGFgcCAK1FWC8f/C0dOQmMYwgqcbjAd
INqo35EQBkK6MN1ppA3JY8DpCxz69zkumoB7biFj/Ll0w2jfApU1sOAXsLUI
LAWmCX16wrhh8OB4uGtwF22FAf5cuj18L2M27+OoBJyZPoKmEwc66i5toLQS
Dh4HpwOenQ8bn4Xu2bBuM9z/E3jhjxCJtN++I2G6cGb5yQGcEpBaYyARWkB7
uC0fRn4NmkJw+AR88xvwzhpYuRDCEVi2Hla9DiGr/T46CgiE1hiAlIDQLa5+
jVamIXjxh4KZhfDeQVj0EpRVCRZMFyz/PigNq/4Exz6lS1YQJUgh45j2S0pe
EFY/AbPvgy1FMPc5TWkFzJsimD4OviiF13Z0kSrECNhlrr2OkpMpWLlQML0Q
io/Awpc05dWab422f9+2h86Xj5i5mvaCREKDpvvht0sEPYKadX8FraFwuP3b
uYtQ1wB+b2dvgq1uZuuWaJGQ6fweeGoe1DdqXt0Gew5HWU6CyyE6dxu0rWyt
O0CS4wV8gmWPCM58oXjngP2sVzdbI7rqGElbpkX0SeLIShese0rSp9dlR0+2
r0RgzznWiVMoPXMFORn296Ofwt+Luy4KjHHi1GK3ihr7s7EZHv+Vold3g0G3
C4ToXCaVrT6gU0N5td3hxLsFF8ph2XpFWVXq/baHOB+wl5P8eVRKUFFtM9DT
D0sWPCDZsU+zYqPqPD/QbelAkke3ss4OJbICkB4QLJkrOPG55tevKwbeDrPG
G5iyM3SghYWiXt3iC4miudnu1OkAKQTZ6ZIn55n0yIGlaxXFhzUqhf6vgr7s
syaJxhLXcCjTFAghQAiG9Yel800eXR5h2XqL5jAcO6n56KTG44LRQyXfHitJ
84uURjVbdEDr5NWzhWmcpv1da4GUgjmTJW8VK97eq5i6KIJhQMALlgWv7VCs
fVOw6gkHIwbKxNhKc7UOpMII6VErVtdpQmHR+vzUWc25kstW+UpPwbonnaz9
qYMJd0s+Pq35ztMh9h1TibNQfDQqomZMDk6HIM1na0FJuc1xDU3w45fDHD+t
GdhHEPBCVa0mzQ/T7jF5caGD4QMk50vhud+FaWhKgAlb59oaSoDSImloLbgt
37b8zv0KpQW7Dyn+eVwxaqjkby+7WfyQg4pq2LDVoqoWbskzmDrWwGHCqXOa
D0+R4JjEsxA6NV7uX2BnBN58z6KmDsqrYGhfyZrFLnKzJI/NcDBrvMnO/RZb
iiwEgr69DQJeCIehqjaBHYhhIRmrA6lg+EB7AWdLNBu3R5g61sHvl7npnS/R
gMMhWDLPSb8CydJXQpw6q1pPgtNhB4WJjXnFApSWKWHEIJNA9CXmlb+EOV8K
WWlGXJ1e3Qwem+nEsuDxFSH2HlXU1kOfXpJ+BUZC48UvoANEJjdbcudgW1bO
X9Ks3BSispb4ekIwYaSTyaMd7PvQYs2fQwQzBc886sblkgmLWXw4nWKmIN0v
mDLGgddtJ7427w7zyPONfHxSoSy7jlJw6nPFZ/9TKGWnY1b8yMOw/mYSmQni
hUxpYed/U3hFmjbOyd4jFluLQoTCsHN/hHcP1JEXFOQFJTX1mrMlioBXcMet
krMXFEdPWEwc6WzJ7SQsZB32PkDUUVcs9NK3wGBbUYgT/7FDiLIqjcOh6dvb
YFqhi7sGm3y1t8GS1Q28uqWZSaNdDLnDSCqYM2ODuY4oPq9gwQwP0wvd1NQr
auo0Po/A7xUEfIKAV2AYtvbMnuBiz7/CLN/QyKblAVzOBHYgbgHaZqHUjlCM
vAvIzYLcrLatqqLjjBzq4p5hIXbuD/HugTCTRrmSi4VSDaeThRCCRXN8SAnb
ikLU1JNwOC1jo9Ebgd75Jt+d4uH9gyE+O6cSahu3gFSFLFloLZl1nw+/T7Bh
SwNKXW+7K44QNxDZGZIRg1y8XdzMmfPW9eWFrg4lbhw8boMhfZ1YSrNlV9P1
RaOxLNSyLR3FQsmUAX2cpPkkuw428YPZaRhSXJOFlJadowOJlotlFoc+aSY7
w8DrkZRXKUrKNT1y5HXrgG6Nr2/A/8JLVldy6HgTsycGEEDEgpo6TV7wSwxq
G1ybgNJCWMqSGtn1/w2HI7bVLlVYVFRbdM8xyUwzW49Im8VCI4QFKAmE6hpF
ZTgkIzeCRuc/kInXLdm6ux6PR7JgZiZZGY5rtgmHZKS2UVQCIRNo2v6P8Af9
Cjwz01z0QHbtDgwf5GXTC/mUlEbonmNyS54jLuvQhvWpq+TSWwfCe4EmA9Cf
nGmoDWb6GwuCjv6GIVwgpdZSaCXpbKAl6X6T/Fwn6X4TdDt1LamtJhGpqxCl
W/c2/WbdtpJdQGWLMviA4EOTcoaNHey+0+MSGVrfXJc9hMBqbNZV7x9t3L9x
R9khoAyoFzF5RVf01oo7evXmZrxuEwKaYq/b/B/B2k8FFRXfJAAAAABJRU5E
rkJggg==
Package: rockbox-doc
Architecture: all
Description: Documentation for rockbox
Package: rockbox-dbg
Section: devel
Architecture: any
Depends: rockbox (= ${Source-Version})
Description: Debug symbols for rockbox

30
debian/copyright vendored
View file

@ -1,30 +0,0 @@
This package was debianized by Thomas Jarosch <tomj@simonv.com> on
Thu, 30 Dec 2010 16:18:05 -0500.
It was downloaded from www.rockbox.org / svn://svn.rockbox.org/rockbox/trunk
Upstream Author: The rockbox team - see docs/CREDITS for all the names
Copyright: 2001-2013 - The rockbox team
License:
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this package; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'.
The Debian packaging is (C) 2010, Thomas Jarosch <tomj@simonv.com> and
is licensed under the GPL, see above.

View file

@ -1,9 +0,0 @@
[Desktop Entry]
Encoding=UTF-8
Version=3.7.1
Type=Application
Name=Rockbox
Exec=/opt/rockbox/bin/rockbox
Icon=rockbox
X-HildonDesk-ShowInToolbar=true
X-Osso-Type=application/x-executable

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

80
debian/rules vendored
View file

@ -1,80 +0,0 @@
#!/usr/bin/make -f
# We deduce the target based on the available version of the Maemo SDK
ifeq (1,$(shell pkg-config --atleast-version=5 maemo-version && echo 1))
TARGET=nokian900
else
TARGET=nokian8xx
endif
CONFIGURE_OPTIONS := --target=$(TARGET) --ram=8 --rbdir=/.rockbox --type=N
DESKTOP_DIR := `pkg-config --variable=desktopentrydir osso-af-settings`
export DH_VERBOSE=1
builddir:
test -d builddir || mkdir -p builddir
builddir/Makefile: builddir
cd builddir && test -f Makefile || ../tools/configure $(CONFIGURE_OPTIONS)
build: build-stamp
build-stamp: builddir/Makefile
dh_testdir
cd builddir && $(MAKE)
touch $@
clean:
dh_testdir
dh_testroot
rm -f build-stamp
rm -rf builddir
dh_clean
install: build
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
cd builddir && $(MAKE) PREFIX=$(CURDIR)/debian/rockbox/opt/rockbox fullinstall
# Remove broken plugins (keymap missing)
# Note: Credits and f.e. mikmod are included and working
rm -f $(CURDIR)/debian/rockbox/opt/rockbox/lib/rockbox/rocks/apps/*
rm -f $(CURDIR)/debian/rockbox/opt/rockbox/lib/rockbox/rocks/demos/*
rm -f $(CURDIR)/debian/rockbox/opt/rockbox/lib/rockbox/rocks/games/*
# Install icon and .desktop file
mkdir -p $(CURDIR)/debian/rockbox/usr/share/icons/hicolor/64x64/apps
cp -f debian/maemo/rockbox.png $(CURDIR)/debian/rockbox/usr/share/icons/hicolor/64x64/apps
mkdir -p $(CURDIR)/debian/rockbox$(DESKTOP_DIR)
cp -f debian/maemo/rockbox.desktop $(CURDIR)/debian/rockbox$(DESKTOP_DIR)
# Ignore built in sounds
mkdir -p $(CURDIR)/debian/rockbox/usr/share/sounds
touch $(CURDIR)/debian/rockbox/usr/share/sounds/database.ignore
# Build architecture-independent files here.
binary-indep:
# We have nothing to do by default.
# Build architecture-dependent files here.
binary-arch: build install
dh_testdir
dh_testroot
dh_installdocs
dh_installexamples
dh_installman
dh_link
dh_strip --dbg-package=rockbox-dbg
dh_compress
dh_fixperms
dh_installdeb
dh_shlibdeps
dh_gencontrol
dh_md5sums
dh_builddeb
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install configure

View file

@ -747,6 +747,7 @@ Cameron John Peck
Chu Khánh Hanh
Hoàng Manh Phú
Gyúróczki Norbert
Ivan Romaniuk-Mikhailovsky
The libmad team
The wavpack team

View file

@ -133,12 +133,18 @@ target/hosted/sonynwz/audio-nwz.c
target/hosted/sonynwz/debug-nwz.c
target/hosted/sonynwz/nvp-nwz.c
target/hosted/sonynwz/nwz-db.c
#if !defined(BOOTLOADER)
target/hosted/sonynwz/nwzlinux-codec.c
#endif
#endif
#if ((defined(HIBY_LINUX) || defined(FIIO_M3K_LINUX) || defined(SAMSUNG_YPR0) || defined(SAMSUNG_YPR1) || defined(SONY_NWZ_LINUX)) && !defined(SIMULATOR))
target/hosted/pcm-alsa.c
target/hosted/alsa-controls.c
#endif
#if ((defined(HIBY_LINUX) || defined(FIIO_M3K_LINUX)) && !defined(SIMULATOR))
drivers/lcd-memframe.c
target/hosted/alsa-controls.c
target/hosted/pcm-alsa.c
target/hosted/backtrace-glibc.c
target/hosted/filesystem-unix.c
target/hosted/kernel-unix.c
@ -153,22 +159,28 @@ target/hosted/power-linux.c
#if defined(AGPTEK_ROCKER) && !defined(SIMULATOR)
target/hosted/agptek/button-agptek.c
target/hosted/agptek/debug-agptek.c
target/hosted/agptek/power-agptek.c
target/hosted/agptek/powermgmt-agptek.c
#if !defined(BOOTLOADER)
target/hosted/agptek/rocker_codec.c
#endif
#endif
#if defined(SURFANS_F28) && !defined(SIMULATOR)
target/hosted/surfans/button-f28.c
target/hosted/surfans/debug-f28.c
target/hosted/surfans/power-f28.c
target/hosted/surfans/powermgmt-f28.c
#if !defined(BOOTLOADER)
target/hosted/surfans/surfanslinux_codec.c
#endif
#endif
#if (defined(XDUOO_X3II) || defined(XDUOO_X20)) && !defined(SIMULATOR)
target/hosted/xduoo/button-xduoo.c
target/hosted/xduoo/debug-xduoo.c
target/hosted/xduoo/power-xduoo.c
target/hosted/xduoo/powermgmt-xduoo.c
#if !defined(BOOTLOADER)
target/hosted/xduoo/xduoolinux_codec.c
#endif
#endif
#if defined(HIBY_LINUX) && !defined(SIMULATOR)
@ -176,21 +188,26 @@ target/hosted/usb-hiby.c
target/hosted/button-devinput.c
#endif
#if (defined(FIIO_M3K_LINUX)) && !defined(SIMULATOR)
#if defined(FIIO_M3K_LINUX) && !defined(SIMULATOR)
target/hosted/fiio/buttonlight-fiio.c
target/hosted/fiio/button-fiio.c
target/hosted/fiio/debug-fiio.c
target/hosted/fiio/power-fiio.c
target/hosted/fiio/powermgmt-fiio.c
target/hosted/fiio/system-fiio.c
target/hosted/fiio/usb-fiio.c
#if !defined(BOOTLOADER)
target/hosted/fiio/fiiolinux_codec.c
#endif
#endif
#if (defined(EROS_Q)) && !defined(SIMULATOR)
#if defined(EROS_Q) && !defined(SIMULATOR)
target/hosted/aigo/button-erosq.c
target/hosted/aigo/debug-erosq.c
target/hosted/aigo/power-erosq.c
target/hosted/aigo/powermgmt-erosq.c
#if !defined(BOOTLOADER)
target/hosted/aigo/erosqlinux_codec.c
#endif
#endif
#if defined(SAMSUNG_YPR0) && !defined(SIMULATOR)
@ -223,17 +240,11 @@ target/hosted/samsungypr/ypr1/pmu-ypr1.c
target/hosted/samsungypr/ypr1/wmcodec-ypr1.c
#endif
/* Maemo specific files */
#if (CONFIG_PLATFORM & PLATFORM_MAEMO)
target/hosted/maemo/maemo-thread.c
#endif
#if defined(RG_NANO) && !defined(SIMULATOR)
target/hosted/sysfs.c
target/hosted/power-linux.c
target/hosted/backlight-unix.c
target/hosted/anbernic/instant_play.c
target/hosted/anbernic/power-rgnano.c
target/hosted/anbernic/button-rgnano.c
target/hosted/anbernic/powermgmt-rgnano.c
#endif /* RG_NANO */
@ -289,6 +300,8 @@ common/inflate.c
/* Standard library */
#if (CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(HAVE_ROCKBOX_C_LIBRARY)
libc/atoi.c
libc/strtol.c
libc/strtoul.c
libc/errno.c
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
/* our ctype.[ch] comes from newlib and is incompitble with most desktop's ctype */
@ -554,40 +567,17 @@ drivers/audio/es9018.c
drivers/audio/es9218.c
#endif /* defined(HAVE_*) */
#else /* PLATFORM_HOSTED */
#if defined(SAMSUNG_YPR0) && defined(HAVE_AS3514)
#if defined(HAVE_SDL_AUDIO) || defined(SIMULATOR)
drivers/audio/sdl.c
target/hosted/sdl/pcm-sdl.c
#elif defined(SAMSUNG_YPR0) && defined(HAVE_AS3514)
drivers/audio/as3514.c
target/hosted/pcm-alsa.c
#elif defined(SAMSUNG_YPR1) && defined(HAVE_WM8978)
drivers/audio/wm8978.c
target/hosted/pcm-alsa.c
#elif defined(HAVE_NWZ_LINUX_CODEC)
drivers/audio/nwzlinux-codec.c
target/hosted/alsa-controls.c
target/hosted/pcm-alsa.c
#elif defined(HAVE_ROCKER_CODEC) && !defined(SIMULATOR)
drivers/audio/rocker_codec.c
#elif defined(HAVE_SURFANS_LINUX_CODEC) && !defined(SIMULATOR)
drivers/audio/surfanslinux_codec.c
#elif defined(HAVE_XDUOO_LINUX_CODEC) && !defined(SIMULATOR)
drivers/audio/xduoolinux_codec.c
#elif defined(HAVE_FIIO_LINUX_CODEC) && !defined(SIMULATOR)
drivers/audio/fiiolinux_codec.c
#elif defined(HAVE_EROSQ_LINUX_CODEC) && !defined(SIMULATOR)
drivers/audio/erosqlinux_codec.c
#elif defined(HAVE_SDL_AUDIO)
drivers/audio/sdl.c
#if (CONFIG_PLATFORM & PLATFORM_MAEMO5)
target/hosted/maemo/pcm-gstreamer.c
#else
target/hosted/sdl/pcm-sdl.c
#endif /* (CONFIG_PLATFORM & PLATFORM_MAEMO) */
#elif defined(CTRU)
drivers/audio/ctru.c
#endif
#endif /* (CONFIG_PLATFORM & PLATFORM_NATIVE) */
#endif /* !defined(BOOTLOADER) */
/* build erosqn codec in bootloader for detection */
@ -2039,10 +2029,10 @@ target/hosted/android/pcm-android.c
target/hosted/android/powermgmt-android.c
target/hosted/android/system-android.c
target/hosted/android/telephony-android.c
target/hosted/android/android-codec.c
#ifdef APPLICATION
target/hosted/android/app/button-application.c
#endif
drivers/audio/android.c
#endif
#if defined(DX50) || defined(DX90)
@ -2063,11 +2053,10 @@ target/hosted/ibasso/pcm-ibasso.c
target/hosted/ibasso/power-ibasso.c
target/hosted/ibasso/powermgmt-ibasso.c
target/hosted/ibasso/sysfs-ibasso.c
target/hosted/sysfs.c
target/hosted/ibasso/system-ibasso.c
target/hosted/ibasso/usb-ibasso.c
target/hosted/ibasso/vold-ibasso.c
target/hosted/ibasso/tinyalsa/mixer.c
target/hosted/ibasso/tinyalsa/pcm.c
#ifdef DX50
target/hosted/ibasso/dx50/audiohw-dx50.c
target/hosted/ibasso/dx50/button-dx50.c
@ -2078,6 +2067,11 @@ target/hosted/ibasso/dx90/button-dx90.c
#endif
#endif
#ifdef USE_TINYALSA
target/hosted/tinyalsa/mixer.c
target/hosted/tinyalsa/pcm.c
#endif
#if (CONFIG_PLATFORM & PLATFORM_CTRU)
asm/arm/lcd-as-memframe.S
target/hosted/ctru/backlight-ctru.c

View file

@ -75,8 +75,8 @@ static bool enable_sw_poweroff = true;
* real list acceleration kicks in (this smooths acceleration).
*
* Note that touchscreen pointing events are not subject to this
* acceleration and always use REPEAT_INTERVAL_TOUCH. (Do repeat
* events even do anything sane for touchscreens??)
* acceleration and always use REPEAT_INTERVAL_TOUCH. That value
* essentially determines the touchscreen polling rate.
*/
/* the speed repeat starts at, in centiseconds */
@ -84,7 +84,7 @@ static bool enable_sw_poweroff = true;
/* speed repeat finishes at, in centiseconds */
#define REPEAT_INTERVAL_FINISH (5*HZ/100)
/* repeat interval for touch events */
#define REPEAT_INTERVAL_TOUCH (5*HZ/100)
#define REPEAT_INTERVAL_TOUCH (4*HZ/100)
static int lastdata = 0;
static int button_read(int *data);
@ -324,21 +324,29 @@ static void button_tick(void)
}
else
{
if (count++ > REPEAT_START)
++count;
if (count > REPEAT_START
#ifdef HAVE_TOUCHSCREEN
/* For touch events we want to repost quickly since
* the coordinates can change */
|| ((btn & BUTTON_TOUCHSCREEN) &&
count > REPEAT_INTERVAL_TOUCH)
#endif
)
{
post = true;
repeat = true;
repeat_count = 0;
/* initial repeat */
count = REPEAT_INTERVAL_START;
}
#ifdef HAVE_TOUCHSCREEN
else if (lastdata != data && btn == lastbtn)
{ /* only coordinates changed, post anyway */
if (touchscreen_get_mode() == TOUCHSCREEN_POINT)
post = true;
}
if (btn & BUTTON_TOUCHSCREEN)
count = REPEAT_INTERVAL_TOUCH;
else
#endif
{
count = REPEAT_INTERVAL_START;
}
}
}
}
if ( post )

View file

@ -28,8 +28,8 @@
#define YEAR1980 315532800 /* 1980/1/1 00:00:00 in UTC */
#if defined(SANSA_FUZEPLUS) || defined(CREATIVE_ZENXFI3) || defined(SONY_NWZE360) || \
defined(SONY_NWZE370)
#if defined(SANSA_FUZEPLUS) || defined(SONY_NWZE360) || defined(SONY_NWZE370) || \
defined(CREATIVE_ZENXFI2) || defined(CREATIVE_ZENXFI3)
#define USE_PERSISTENT
#endif

View file

@ -18,19 +18,12 @@
* KIND, either express or implied.
*
****************************************************************************/
#ifndef HOSTED_CODEC_H
#define HOSTED_CODEC_H
#ifndef __ANDROID_CODEC_H
#define __ANDROID_CODEC_H
#if (defined(HAVE_SDL_AUDIO) \
&& !(CONFIG_PLATFORM & PLATFORM_MAEMO5)) \
|| (CONFIG_PLATFORM & PLATFORM_CTRU)
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -80, 0, 0)
#else
#define AUDIOHW_CAPS (MONO_VOL_CAP)
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -99, 0, 0)
#endif /* CONFIG_PLATFORM & PLATFORM_SDL */
#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
/* Bass and treble tone controls */
#ifdef AUDIOHW_HAVE_BASS
AUDIOHW_SETTING(BASS, "dB", 0, 1, -24, 24, 0)
@ -49,6 +42,5 @@ AUDIOHW_SETTING(BASS_CUTOFF, "", 0, 1, 1, 4, 1)
#if defined(AUDIOHW_HAVE_TREBLE_CUTOFF)
AUDIOHW_SETTING(TREBLE_CUTOFF, "", 0, 1, 1, 4, 1)
#endif
#endif /* CONFIG_PLATFORM & PLATFORM_ANDROID */
#endif /* HOSTED_CODEC_H */
#endif /* __ANDROID_CODEC_H */

View file

@ -223,9 +223,10 @@ struct sound_settings_info
#include "es9018.h"
#elif defined(HAVE_ES9218)
#include "es9218.h"
#elif ((CONFIG_PLATFORM & (PLATFORM_ANDROID | PLATFORM_MAEMO \
| PLATFORM_PANDORA | PLATFORM_SDL | PLATFORM_CTRU)) | defined(RG_NANO))
#include "hosted_codec.h"
#elif (CONFIG_PLATFORM & PLATFORM_ANDROID)
#include "android_codec.h"
#elif ((CONFIG_PLATFORM & (PLATFORM_SDL | PLATFORM_CTRU)) | defined(RG_NANO))
#include "sdl_codec.h"
#elif defined(DX50)
#include "codec-dx50.h"
#elif defined(DX90)

View file

@ -95,11 +95,7 @@
#define PLATFORM_HOSTED (1<<1)
#define PLATFORM_ANDROID (1<<2)
#define PLATFORM_SDL (1<<3)
#define PLATFORM_MAEMO4 (1<<4)
#define PLATFORM_MAEMO5 (1<<5)
#define PLATFORM_MAEMO (PLATFORM_MAEMO4|PLATFORM_MAEMO5)
#define PLATFORM_PANDORA (1<<6)
#define PLATFORM_CTRU (1<<7)
#define PLATFORM_CTRU (1<<4)
/* CONFIG_KEYPAD */
#define IRIVER_H100_PAD 4
@ -538,12 +534,6 @@ Lyre prototype 1 */
#include "config/sdlapp.h"
#elif defined(ANDROID)
#include "config/android.h"
#elif defined(NOKIAN8XX)
#include "config/nokian8xx.h"
#elif defined(NOKIAN900)
#include "config/nokian900.h"
#elif defined(PANDORA)
#include "config/pandora.h"
#elif defined(SAMSUNG_YPR0)
#include "config/samsungypr0.h"
#elif defined(CREATIVE_ZENXFI)
@ -721,17 +711,19 @@ Lyre prototype 1 */
/* define for all cpus from ARM family */
#if ARCH == ARCH_ARM
#define CPU_ARM
#define ARM_ARCH ARCH_VERSION /* ARMv{4,5,6,7} */
#define ARM_PROFILE ARCH_PROFILE /* Classic, Microcontroller */
#define ARM_ARCH ARCH_VERSION /* ARMv{4,5,6,7,8,9} */
#define ARM_PROFILE ARCH_PROFILE /* Classic, Microcontroller, Application [,Realtime] */
# if ARM_PROFILE == ARM_PROFILE_MICRO
# define CPU_ARM_MICRO
# if (ARM_ARCH >= 7)
# define ARM_HAVE_HW_DIV
# endif
# elif ARM_PROFILE == ARM_PROFILE_CLASSIC
# define CPU_ARM_CLASSIC
# elif ARM_PROFILE == ARM_PROFILE_APPLICATION
# define CPU_ARM_APPLICATION
# endif
# if (CONFIG_PLATFORM & PLATFORM_NATIVE)
#if defined(__ARM_FEATURE_IDIV)
# define ARM_HAVE_HW_DIV
#endif
# if (CONFIG_PLATFORM & PLATFORM_NATIVE) && !defined(ARM_HAVE_HW_DIV)
# define ARM_NEED_DIV0
# endif
#endif
@ -1110,7 +1102,7 @@ Lyre prototype 1 */
* Older versions of GCC emit assembly in divided syntax with no option
* to enable unified syntax.
*/
#if (__GNUC__ < 8) && defined(CPU_ARM_CLASSIC) || defined(CTRU)
#if (__GNUC__ < 8) && (defined(CPU_ARM_CLASSIC)||defined(CPU_ARM_APPLICATION))
#define BEGIN_ARM_ASM_SYNTAX_UNIFIED ".syntax unified\n"
#define END_ARM_ASM_SYNTAX_UNIFIED ".syntax divided\n"
#else
@ -1427,7 +1419,6 @@ Lyre prototype 1 */
#endif
#if defined(HAVE_SDL_AUDIO) \
&& !(CONFIG_PLATFORM & PLATFORM_MAEMO5) \
&& !defined(HAVE_SW_VOLUME_CONTROL)
/* SW volume is needed for accurate control and no double buffering should be
* required. If target uses SW volume, then its definitions are used instead

View file

@ -125,6 +125,14 @@
#define BATTERY_CAPACITY_MAX 1100 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 0 /* capacity increment */
/* Voltage reported in millivolts */
#define BATTERY_VOLTAGE_SCALE_MUL 1
#define BATTERY_VOLTAGE_SCALE_DIV 1
/* Capacity reported as a value 0-5, 20% increments */
#define BATTERY_LEVEL_SCALE_MUL 20
#define BATTERY_LEVEL_SCALE_DIV 1
/* ROLO */
#define BOOTFILE_EXT "m3k"
#define BOOTFILE "rockbox." BOOTFILE_EXT

View file

@ -1,91 +0,0 @@
/*
* This config file is for Rockbox as an application on the Nokia N8xx
*/
/* We don't run on hardware directly */
#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_MAEMO4)
/* For Rolo and boot loader */
#define MODEL_NUMBER 100
#define MODEL_NAME "Rockbox"
#define USB_NONE
#define HAVE_FPU
/* define this if you have a colour LCD */
#define HAVE_LCD_COLOR
/* define this if you want album art for this target */
#define HAVE_ALBUMART
/* define this to enable bitmap scaling */
#define HAVE_BMP_SCALING
/* define this to enable JPEG decoding */
#define HAVE_JPEG
/* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN
/* define this if you would like tagcache to build on this target */
#define HAVE_TAGCACHE
/* LCD dimensions */
#define LCD_WIDTH 800
#define LCD_HEIGHT 480
#define LCD_DEPTH 16
#define LCD_PIXELFORMAT RGB565
/* define this to indicate your device's keypad */
#define HAVE_TOUCHSCREEN
#define HAVE_BUTTON_DATA
/* define this if you have a real-time clock */
#define CONFIG_RTC RTC_HOSTED
/* The number of bytes reserved for loadable codecs */
#define CODEC_SIZE 0x100000
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x80000
#define AB_REPEAT_ENABLE
/* Work around debug macro expansion of strncmp in scratchbox */
#define _HAVE_STRING_ARCH_strncmp
#define HAVE_MULTIMEDIA_KEYS
#define HAVE_SCROLLWHEEL
#define CONFIG_KEYPAD SDL_PAD
/* Use SDL audio/pcm in a SDL app build */
#define HAVE_SDL
#define HAVE_SDL_AUDIO
#define HAVE_SW_TONE_CONTROLS
/* can provide both remaining percentage and time information */
#define CONFIG_BATTERY_MEASURE (PERCENTAGE_MEASURE|TIME_MEASURE)
#define NO_LOW_BATTERY_SHUTDOWN
/* Define this to the CPU frequency */
/*
#define CPU_FREQ 48000000
*/
#define CONFIG_LCD LCD_COWOND2
/* Define this if a programmable hotkey is mapped */
#define HAVE_HOTKEY
#define BOOTDIR "/.rockbox"
/* No special storage */
#define CONFIG_STORAGE STORAGE_HOSTFS
#define HAVE_STORAGE_FLUSH

View file

@ -1,88 +0,0 @@
/*
* This config file is for Rockbox as an application on the Nokia N900
*/
/* We don't run on hardware directly */
#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_MAEMO5)
/* For Rolo and boot loader */
#define MODEL_NUMBER 100
#define MODEL_NAME "Rockbox"
#define USB_NONE
#define HAVE_FPU
/* define this if you have a colour LCD */
#define HAVE_LCD_COLOR
/* define this if you want album art for this target */
#define HAVE_ALBUMART
/* define this to enable bitmap scaling */
#define HAVE_BMP_SCALING
/* define this to enable JPEG decoding */
#define HAVE_JPEG
/* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN
/* define this if you would like tagcache to build on this target */
#define HAVE_TAGCACHE
/* LCD dimensions */
#define LCD_WIDTH 800
#define LCD_HEIGHT 480
#define LCD_DEPTH 16
#define LCD_PIXELFORMAT RGB565
/* define this to indicate your device's keypad */
#define HAVE_TOUCHSCREEN
#define HAVE_BUTTON_DATA
/* define this if you have a real-time clock */
#define CONFIG_RTC RTC_HOSTED
/* The number of bytes reserved for loadable codecs */
#define CODEC_SIZE 0x100000
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x80000
#define AB_REPEAT_ENABLE
/* Work around debug macro expansion of strncmp in scratchbox */
#define _HAVE_STRING_ARCH_strncmp
#define HAVE_MULTIMEDIA_KEYS
#define HAVE_SCROLLWHEEL
#define CONFIG_KEYPAD SDL_PAD
/* Use SDL audio/pcm in a SDL app build */
#define HAVE_SDL
#define HAVE_SDL_AUDIO
#define HAVE_SW_TONE_CONTROLS
/* can provide both remaining percentage and time information */
#define CONFIG_BATTERY_MEASURE (PERCENTAGE_MEASURE|TIME_MEASURE)
#define NO_LOW_BATTERY_SHUTDOWN
/*
#define CPU_FREQ 48000000
*/
#define CONFIG_LCD LCD_COWOND2
/* Define this if a programmable hotkey is mapped */
#define HAVE_HOTKEY
#define BOOTDIR "/.rockbox"
/* No special storage */
#define CONFIG_STORAGE STORAGE_HOSTFS
#define HAVE_STORAGE_FLUSH

View file

@ -1,91 +0,0 @@
/*
* This config file is for Rockbox as an application on the Nokia N8xx
*/
/* We don't run on hardware directly */
#define CONFIG_PLATFORM (PLATFORM_HOSTED|PLATFORM_PANDORA)
/* For Rolo and boot loader */
#define MODEL_NUMBER 100
#define MODEL_NAME "Rockbox"
#define USB_NONE
/* define this if you have a colour LCD */
#define HAVE_LCD_COLOR
/* define this if you want album art for this target */
#define HAVE_ALBUMART
/* define this to enable bitmap scaling */
#define HAVE_BMP_SCALING
/* define this to enable JPEG decoding */
#define HAVE_JPEG
/* define this if you have access to the quickscreen */
#define HAVE_QUICKSCREEN
/* define this if you would like tagcache to build on this target */
#define HAVE_TAGCACHE
/* LCD dimensions */
#define LCD_WIDTH 800
#define LCD_HEIGHT 480
#define LCD_DEPTH 16
#define LCD_PIXELFORMAT RGB565
/* define this to indicate your device's keypad */
#define HAVE_TOUCHSCREEN
#define HAVE_BUTTON_DATA
/* define this if you have a real-time clock */
#define CONFIG_RTC RTC_HOSTED
/* The number of bytes reserved for loadable codecs */
#define CODEC_SIZE 0x100000
/* The number of bytes reserved for loadable plugins */
#define PLUGIN_BUFFER_SIZE 0x80000
#define AB_REPEAT_ENABLE
/* Work around debug macro expansion of strncmp in scratchbox */
#define _HAVE_STRING_ARCH_strncmp
#define HAVE_SCROLLWHEEL
#define CONFIG_KEYPAD SDL_PAD
/* Use SDL audio/pcm in a SDL app build */
#define HAVE_SDL
#define HAVE_SDL_AUDIO
#define HAVE_SW_TONE_CONTROLS
/* Define current usage levels. */
#define CURRENT_NORMAL 88 /* 18 hours from a 1600 mAh battery */
#define CURRENT_BACKLIGHT 30 /* TBD */
#define CURRENT_RECORD 0 /* no recording yet */
/* Define this to the CPU frequency */
/*
#define CPU_FREQ 48000000
*/
#define CONFIG_LCD LCD_COWOND2
/* Define this if a programmable hotkey is mapped */
#define HAVE_HOTKEY
#define BOOTDIR "/.rockbox"
/* No special storage */
#define CONFIG_STORAGE STORAGE_HOSTFS
#define HAVE_STORAGE_FLUSH

View file

@ -70,6 +70,10 @@
#define BATTERY_CAPACITY_MAX 1050 /* max. capacity selectable */
#define BATTERY_CAPACITY_INC 0 /* capacity increment */
/* Voltage reported in millivolts */
#define BATTERY_VOLTAGE_SCALE_MUL 1
#define BATTERY_VOLTAGE_SCALE_DIV 1
/* Define this for LCD backlight available */
#define BACKLIGHT_RG_NANO
#define HAVE_BACKLIGHT

View file

@ -34,9 +34,7 @@
/* These MIPS32r1 targets have a very high interrupt latency, which
unfortunately causes a lot of audio underruns under even moderate load */
#define MIX_FRAME_SAMPLES 2048
#elif (CONFIG_PLATFORM & PLATFORM_MAEMO5) || defined(DX50) || defined(DX90)
/* Maemo 5 needs 2048 samples for decent performance.
Otherwise the locking overhead inside gstreamer costs too much */
#elif defined(DX50) || defined(DX90)
/* iBasso Devices: Match Rockbox PCM buffer size to ALSA PCM buffer size
to minimize memory transfers. */
#define MIX_FRAME_SAMPLES 2048

View file

@ -5,8 +5,9 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2017 by Marcin Bukat
* Copyright (C) 2010 by Thomas Martitz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -17,11 +18,10 @@
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _POWER_AGPTEK_H_
#define _POWER_AGPTEK_H_
#ifndef _SDL_CODEC_H
#define _SDL_CODEC_H
#include <stdbool.h>
#include "config.h"
// This is pretty generic and probably needs adjusting
AUDIOHW_SETTING(VOLUME, "dB", 0, 1, -80, 0, 0)
unsigned int agptek_power_get_battery_voltage(void);
#endif /* _POWER_AGPTEK_H_ */
#endif /* _SDL_CODEC_H */

View file

@ -3,7 +3,6 @@
#define AUDIOHW_CAPS (FILTER_ROLL_OFF_CAP)
AUDIOHW_SETTING(VOLUME, "dB", 1, 5, -102*10, 0, -30*10)
#endif
//#define AUDIOHW_MUTE_ON_STOP
#define AUDIOHW_MUTE_ON_SRATE_CHANGE
@ -15,3 +14,5 @@ AUDIOHW_SETTING(FILTER_ROLL_OFF, "", 0, 1, 0, 4, 0)
void audiohw_mute(int mute);
void surfans_set_output(int ps);
int surfans_get_outputs(void);
#endif /* __SURFANSLINUX__CODEC__ */

View file

@ -42,6 +42,21 @@ enum touchscreen_mode
from button_get_data */
};
enum touchevent_type
{
TOUCHEVENT_NONE = 0,
TOUCHEVENT_PRESS,
TOUCHEVENT_CONTACT,
TOUCHEVENT_RELEASE,
};
struct touchevent
{
int type;
short x, y;
long tick;
};
extern struct touchscreen_parameter calibration_parameters;
extern const struct touchscreen_parameter default_calibration_parameters;
int touchscreen_calibrate(struct touchscreen_calibration *cal);

View file

@ -58,6 +58,8 @@ void exit(int status);
#endif
int atoi (const char *str);
unsigned long int strtoul(const char *ptr, char **endptr, int base);
long int strtol(const char *ptr, char **endptr, int base);
#ifdef __cplusplus
}

29
firmware/libc/strtol.c Normal file
View file

@ -0,0 +1,29 @@
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
#include <gcc_extensions.h>
#define ABS_LONG_MIN LONG_MAX
long int strtol(const char *nptr, char **endptr, int base)
{
int neg=0;
unsigned long int v;
const char*orig=nptr;
while(UNLIKELY(isspace(*nptr))) nptr++;
if (*nptr == '-' && isalnum(nptr[1])) { neg=-1; ++nptr; }
v=strtoul(nptr,endptr,base);
if (endptr && *endptr==nptr) *endptr=(char *)orig;
if (UNLIKELY(v>=ABS_LONG_MIN)) {
if (v==ABS_LONG_MIN && neg) {
errno=0;
return v;
}
errno=ERANGE;
return (neg?LONG_MIN:LONG_MAX);
}
return (neg?-v:v);
}

57
firmware/libc/strtoul.c Normal file
View file

@ -0,0 +1,57 @@
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <limits.h>
#include <gcc_extensions.h>
unsigned long int strtoul(const char *ptr, char **endptr, int base)
{
int neg = 0, overflow = 0;
unsigned long int v=0;
const char* orig;
const char* nptr=ptr;
while(UNLIKELY(isspace(*nptr))) ++nptr;
if (*nptr == '-') { neg=1; nptr++; }
else if (*nptr == '+') ++nptr;
orig=nptr;
if (base==16 && nptr[0]=='0') goto skip0x;
if (base) {
register unsigned int b=base-2;
if (UNLIKELY(b>34)) { errno=EINVAL; return 0; }
} else {
if (*nptr=='0') {
base=8;
skip0x:
if ((nptr[1]=='x'||nptr[1]=='X') && isxdigit(nptr[2])) {
nptr+=2;
base=16;
}
} else
base=10;
}
while(LIKELY(*nptr)) {
register unsigned char c=*nptr;
c=(c>='a'?c-'a'+10:c>='A'?c-'A'+10:c<='9'?c-'0':0xff);
if (UNLIKELY(c>=base)) break; /* out of base */
{
register unsigned long x=(v&0xff)*base+c;
register unsigned long w=(v>>8)*base+(x>>8);
if (w>(ULONG_MAX>>8)) overflow=1;
v=(w<<8)+(x&0xff);
}
++nptr;
}
if (UNLIKELY(nptr==orig)) { /* no conversion done */
nptr=ptr;
errno=EINVAL;
v=0;
}
if (endptr) *endptr=(char *)nptr;
if (overflow) {
errno=ERANGE;
return ULONG_MAX;
}
return (neg?-v:v);
}

View file

@ -542,7 +542,8 @@ bool dbg_hw_info_rtc(void)
lcd_putsf(0, line++, "alarm: %lu", info.alarm);
for(int i = 0; i < 6; i++)
lcd_putsf(0, line++, "persist%d: 0x%lx", i, info.persistent[i]);
lcd_putsf(0, line++, "rtc_ctrl: 0x%lx", info.rtc_ctrl);
lcd_putsf(0, line++, "rtc_stat: 0x%lx", info.rtc_stat);
lcd_update();
yield();
}

View file

@ -55,5 +55,7 @@ struct imx233_rtc_info_t imx233_rtc_get_info(void)
info.alarm_wake_en = BF_RD(RTC_PERSISTENT0, ALARM_WAKE_EN);
info.alarm_wake = BF_RD(RTC_PERSISTENT0, ALARM_WAKE);
info.alarm_irq = BF_RD(RTC_CTRL, ALARM_IRQ);
info.rtc_ctrl = HW_RTC_CTRL;
info.rtc_stat = HW_RTC_STAT;
return info;
}

View file

@ -34,6 +34,8 @@ struct imx233_rtc_info_t
uint32_t seconds;
uint32_t persistent[6];
uint32_t alarm;
uint32_t rtc_ctrl;
uint32_t rtc_stat;
bool alarm_en, alarm_wake_en, alarm_wake, alarm_irq;
};
@ -84,10 +86,23 @@ static inline void imx233_rtc_init(void)
BF_CLR(RTC_CTRL, SFTRST);
udelay(5); /* only need 3 GPMI clocks (1us) */
BF_CLR(RTC_CTRL, CLKGATE);
#if defined(SANSA_FUZEPLUS)
#ifdef BM_RTC_PERSISTENT0_DISABLE_XTALOK
while (BF_RD(RTC_STAT, NEW_REGS)!=0) {};
BF_SET(RTC_PERSISTENT0, XTAL24MHZ_PWRUP, DISABLE_XTALOK);
#endif
while (BF_RD(RTC_STAT, NEW_REGS)!=0) {};
BF_CLR(RTC_PERSISTENT0, CLOCKSOURCE);
#else
/* confirmed for CREATIVE_ZEN and CREATIVE_ZENXFI2 */
/* FIXME: test SONY_NWZE360 and SONY_NWZE370 targets */
#ifdef BM_RTC_PERSISTENT0_DISABLE_XTALOK
while (BF_RD(RTC_STAT, NEW_REGS)!=0) {};
BF_SET(RTC_PERSISTENT0, XTAL32KHZ_PWRUP, CLOCKSOURCE);
while (BF_RD(RTC_STAT, NEW_REGS)!=0) {};
BF_CLR(RTC_PERSISTENT0, XTAL24MHZ_PWRUP, DISABLE_XTALOK);
#endif
#endif
imx233_rtc_enable_watchdog(false);
}

View file

@ -90,10 +90,10 @@ static void UIRQ(void)
void irq_handler(void)
{
asm volatile("stmfd sp!, {r0-r5, ip, lr} \n" /* store context */
"ldr r4, =0x18080000 \n" /* INTC base */
"ldr r4, =0x18080000 \n" /* INTC base */
"ldr r5, [r4, #0x104] \n" /* INTC_ISR */
"and r5, r5, #0x1f \n" /* irq_no = INTC_ISR & 0x1f */
"ldr r3, =irqvector \n"
"ldr r3, =irqvector \n"
"ldr r3,[r3, r5, lsl #2] \n"
"blx r3 \n" /* irqvector[irq_no]() */
"mov r3, #1 \n"
@ -117,8 +117,14 @@ void system_init(void)
WDTCON &= ~(1<<3);
#ifndef BOOTLOADER
/* SDRAM tweaks */
MCSDR_MODE = (2<<4)|3; /* CAS=2, burst=8 */
/* SDRAM tweaks. Note this assumes 100MHz AHB+SDRAM clock. */
#if !(defined(HM60X) || defined(HM801))
MCSDR_MODE = (3<<4)|3; /* CAS=3, burst=8(2^3) -- Safe but slower */
#else
MCSDR_MODE = (2<<4)|3; /* CAS=2, burst=8(2^3) -- Ideal but causes startup issues on (some?) IHIFI devices */
#endif
MCSDR_T_REF = (125*100) >> 3; /* 125/8 = 15.625 autorefresh interval */
MCSDR_T_RFC = (64*100) / 1000; /* autorefresh period */
MCSDR_T_RP = 1; /* precharge period */
@ -232,9 +238,15 @@ void commit_discard_dcache_range (const void *base, unsigned int size)
}
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
#if !defined(BOOTLOADER) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
static inline void set_sdram_timing(int ahb_freq)
{
#if 1
if (ahb_freq > 100000000)
MCSDR_MODE = (3<<4)|3; /* CAS=3, burst=8(2^3) */
else
MCSDR_MODE = (2<<4)|3; /* CAS=2, burst=8(2^3) */
#endif
MCSDR_T_REF = (125*ahb_freq/1000000) >> 3;
MCSDR_T_RFC = (64*ahb_freq/1000000)/1000;
}
@ -244,6 +256,8 @@ void set_cpu_frequency(long frequency)
if (cpu_frequency == frequency)
return;
/* Temporarily use more conservative SDRAM settings
so we don't glitch when changing clocks */
set_sdram_timing(12000000);
if (frequency == CPUFREQ_MAX)

View file

@ -790,6 +790,17 @@ static void ata_power_down(void)
static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bool write)
{
if (ceata) {
/* Despite the fact that CE-ATA specifies a minimum logical
sector size of 4096 bytes, the actual transfer commands
must be specified in units of 512 bytes. So scale the
sector count up and the LBA down.
On CE-ATA devies, the partition table and filesytem is
formatted with 4K logical sectors, so this will be safe.
*/
cnt <<= (identify_info[106] - 9);
sector <<= (identify_info[106] - 9);
memset(ceata_taskfile, 0, 16);
ceata_taskfile[0x2] = cnt >> 8;
ceata_taskfile[0x3] = sector >> 24;
@ -802,7 +813,6 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT;
PASS_RC(ceata_wait_idle(), 2, 0);
PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
cnt <<= (identify_info[106] - 9); /* convert LOGICAL block size into 512B CE-ATA blocks */
PASS_RC(ceata_rw_multiple_block(write, buffer, cnt, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2);
return 0;
}

View file

@ -1,41 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2017 by Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "system.h"
#include "power-agptek.h"
#include "power.h"
#include "panic.h"
#include "sysfs.h"
const char * const sysfs_bat_voltage =
"/sys/class/power_supply/battery/voltage_now";
unsigned int agptek_power_get_battery_voltage(void)
{
int battery_voltage;
sysfs_get_int(sysfs_bat_voltage, &battery_voltage);
return battery_voltage/1000;
}

View file

@ -19,7 +19,6 @@
****************************************************************************/
#include "powermgmt.h"
#include "power.h"
#include "power-agptek.h"
unsigned short battery_level_disksafe = 3470;
@ -37,8 +36,3 @@ unsigned short percent_to_volt_charge[11] =
{
3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196
};
int _battery_voltage(void)
{
return agptek_power_get_battery_voltage();
}

View file

@ -1,64 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 Hairo R. Carela
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "system.h"
#include "power-rgnano.h"
#include "power.h"
#include "panic.h"
#include "sysfs.h"
const char * const sysfs_bat_voltage =
"/sys/class/power_supply/axp20x-battery/voltage_now";
const char * const sysfs_bat_current =
"/sys/class/power_supply/axp20x-battery/current_now";
const char * const sysfs_bat_level =
"/sys/class/power_supply/axp20x-battery/capacity";
unsigned int rgnano_power_get_battery_voltage(void)
{
int battery_voltage;
sysfs_get_int(sysfs_bat_voltage, &battery_voltage);
return battery_voltage;
}
unsigned int rgnano_power_get_battery_current(void)
{
int battery_current;
sysfs_get_int(sysfs_bat_current, &battery_current);
/* Current is in microamps */
return (battery_current / 1000);
}
unsigned int rgnano_power_get_battery_capacity(void)
{
int battery_level;
sysfs_get_int(sysfs_bat_level, &battery_level);
return battery_level;
}

View file

@ -1,29 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2025 Hairo R. Carela
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _POWER_RGNANO_H_
#define _POWER_RGNANO_H_
#include <stdbool.h>
#include "config.h"
unsigned int rgnano_power_get_battery_voltage(void);
unsigned int rgnano_power_get_battery_current(void);
unsigned int rgnano_power_get_battery_capacity(void);
#endif /* _POWER_RGNANO_H_ */

View file

@ -20,7 +20,6 @@
****************************************************************************/
#include "powermgmt.h"
#include "power.h"
#include "power-rgnano.h"
/* System handles powering off at 2% */
unsigned short battery_level_disksafe = 0;
@ -39,18 +38,3 @@ unsigned short percent_to_volt_charge[11] =
{
3512, 3729, 3795, 3831, 3865, 3906, 3953, 4010, 4072, 4150, 4186
};
int _battery_voltage(void)
{
return rgnano_power_get_battery_voltage();
}
int _battery_current(void)
{
return rgnano_power_get_battery_current();
}
int _battery_level(void)
{
return rgnano_power_get_battery_capacity();
}

View file

@ -22,10 +22,10 @@
#include "config.h"
#include "audiohw.h"
#include "pcm-android.h"
void audiohw_set_volume(int volume)
{
extern void pcm_set_mixer_volume(int);
pcm_set_mixer_volume(volume);
}
@ -36,6 +36,5 @@ void audiohw_set_balance(int balance)
void audiohw_close(void)
{
extern void pcm_shutdown(void);
pcm_shutdown();
}

View file

@ -0,0 +1,7 @@
#ifndef __PCM_ANDROID_H
#define __PCM_ANDROID_H
void pcm_set_mixer_volume(int volume);
void pcm_shutdown(void);
#endif /* __PCM_ANDROID_H */

View file

@ -1,54 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2017 by Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "system.h"
#include "power.h"
#include "panic.h"
#include "sysfs.h"
#include "usb.h"
#include "power-fiio.h"
const char * const sysfs_bat_voltage =
"/sys/class/power_supply/battery/voltage_now";
const char * const sysfs_bat_capacity =
"/sys/class/power_supply/battery/capacity";
unsigned int fiio_power_get_battery_voltage(void)
{
int battery_voltage;
sysfs_get_int(sysfs_bat_voltage, &battery_voltage);
return battery_voltage;
}
unsigned int fiio_power_get_battery_capacity(void)
{
int battery_capacity;
sysfs_get_int(sysfs_bat_capacity, &battery_capacity);
return battery_capacity * 20;
}

View file

@ -1,28 +0,0 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2017 by Marcin Bukat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _POWER_FIIO_H_
#define _POWER_FIIO_H_
#include <stdbool.h>
#include "config.h"
unsigned int fiio_power_get_battery_voltage(void);
unsigned int fiio_power_get_battery_capacity(void);
#endif /* _POWER_FIIO_H_ */

View file

@ -19,7 +19,6 @@
****************************************************************************/
#include "powermgmt.h"
#include "power.h"
#include "power-fiio.h"
unsigned short battery_level_disksafe = 3470;
@ -37,15 +36,3 @@ unsigned short percent_to_volt_charge[11] =
{
3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196
};
int _battery_voltage(void)
{
return fiio_power_get_battery_voltage();
}
#if 0
int _battery_level(void)
{
return fiio_power_get_battery_capacity();
}
#endif

View file

@ -26,7 +26,6 @@
#include "usb.h"
#include "sysfs.h"
#include "power.h"
#include "power-fiio.h"
#ifdef HAVE_MULTIDRIVE
void cleanup_rbhome(void);

View file

@ -55,7 +55,7 @@
#if defined(HAVE_MULTIDRIVE) || defined(HAVE_SPECIAL_DIRS)
#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
static const char rbhome[] = "/sdcard";
#elif (CONFIG_PLATFORM & (PLATFORM_SDL|PLATFORM_MAEMO|PLATFORM_PANDORA)) \
#elif (CONFIG_PLATFORM & PLATFORM_SDL) \
&& !defined(__PCTOOL__)
static const char *rbhome;
#elif defined(PIVOT_ROOT)

View file

@ -48,7 +48,7 @@ bool backlight_hw_init(void)
/sys/devices/platform/rk29_backlight/backlight/rk28_bl/bl_power
0: backlight on
*/
if(! sysfs_set_int(SYSFS_BACKLIGHT_POWER, 0))
if(! sysfs_set_int(sysfs_paths[SYSFS_BACKLIGHT_POWER], 0))
{
DEBUGF("ERROR %s: Can not enable backlight.", __func__);
panicf("ERROR %s: Can not enable backlight.", __func__);
@ -79,7 +79,7 @@ void backlight_hw_off(void)
/sys/devices/platform/rk29_backlight/backlight/rk28_bl/bl_power
1: backlight off
*/
if(! sysfs_set_int(SYSFS_BACKLIGHT_POWER, 1))
if(! sysfs_set_int(sysfs_paths[SYSFS_BACKLIGHT_POWER], 1))
{
DEBUGF("ERROR %s: Can not disable backlight.", __func__);
return;
@ -124,7 +124,7 @@ void backlight_hw_brightness(int brightness)
/sys/devices/platform/rk29_backlight/backlight/rk28_bl/max_brightness
0 ... 255
*/
if(! sysfs_set_int(SYSFS_BACKLIGHT_BRIGHTNESS, _current_brightness))
if(! sysfs_set_int(sysfs_paths[SYSFS_BACKLIGHT_BRIGHTNESS], _current_brightness))
{
DEBUGF("ERROR %s: Can not set brightness.", __func__);
return;

View file

@ -94,7 +94,7 @@ static bool _hold = false;
bool button_hold(void)
{
char hold_state;
if(! sysfs_get_char(SYSFS_HOLDKEY, &hold_state))
if(! sysfs_get_char(sysfs_paths[SYSFS_HOLDKEY], &hold_state))
{
DEBUGF("ERROR %s: Can not get hold switch state.", __func__);
hold_state = HOLD_SWITCH_BIT;

View file

@ -61,7 +61,7 @@ void audiohw_set_volume(int volume)
/dev/codec_volume
0 ... 255
*/
if(! sysfs_set_int(SYSFS_DX50_CODEC_VOLUME, volume_adjusted))
if(! sysfs_set_int(sysfs_paths[SYSFS_DX50_CODEC_VOLUME], volume_adjusted))
{
DEBUGF("ERROR %s: Can not set volume.", __func__);
}
@ -72,7 +72,7 @@ void audiohw_set_filter_roll_off(int val)
{
DEBUGF("DEBUG %s: val: %d", __func__, val);
if(! sysfs_set_char(SYSFS_ES9018_FILTER, (char) val))
if(! sysfs_set_char(sysfs_paths[SYSFS_ES9018_FILTER], (char) val))
{
DEBUGF("ERROR %s: Can not set roll off filter.", __func__);
}

View file

@ -56,7 +56,7 @@ void audiohw_set_volume(int volume)
/sys/class/codec/es9018_volume
0 ... 255
*/
if(! sysfs_set_int(SYSFS_DX90_ES9018_VOLUME, volume_adjusted))
if(! sysfs_set_int(sysfs_paths[SYSFS_DX90_ES9018_VOLUME], volume_adjusted))
{
DEBUGF("ERROR %s: Can not set volume.", __func__);
}

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