diff --git c/apps/action.c w/apps/action.c
index 2492a7d..67272c3 100644
--- c/apps/action.c
+++ w/apps/action.c
@@ -150,6 +150,41 @@ static inline int get_next_context(const struct button_mapping *items, int i)
items[i].action_code;
}
+static bool backlight_on_action(int action)
+{
+ /* no backlight on volume change and pause/play */
+ return (action != ACTION_WPS_VOLUP)
+ && (action != ACTION_WPS_VOLDOWN)
+ && (action != ACTION_WPS_PLAY)
+ && (action != ACTION_WPS_STOP)
+ && (action != ACTION_WPS_SEEKBACK)
+ && (action != ACTION_WPS_SEEKFWD)
+ && (action != ACTION_WPS_STOPSEEK)
+ && (action != ACTION_WPS_SKIPNEXT)
+ && (action != ACTION_WPS_SKIPPREV);
+}
+
+static bool backlight_on_keypress_oracle(int btn)
+{
+ /* check whether the button would fire an action */
+ /* If yes, check whether that action should turn on the backlight */
+ /* Keep this function fast! It's called from the button ticktask */
+ /* or the scrollwheel interrupt handler! */
+
+ const struct button_mapping *items = NULL;
+ int i = 0;
+
+ if (!global_settings.backlight_on_volume_change)
+ {
+ items = get_context_mapping(CONTEXT_WPS);
+ /* also check action for button release */
+ return backlight_on_action(do_button_check(items, btn, BUTTON_NONE, &i))
+ && backlight_on_action(do_button_check(items, btn | BUTTON_REL, btn, &i));
+ }
+ else
+ return true;
+}
+
#if defined(HAVE_GUI_BOOST) && defined(HAVE_ADJUSTABLE_CPU_FREQ)
/* Timeout for gui boost in seconds. */
@@ -209,6 +244,16 @@ static int get_action_worker(int context, int timeout,
send_event(GUI_EVENT_ACTIONUPDATE, NULL);
+ /* In CONTEXT_WPS or CONTEXT_FM we may want to keep the backlight off */
+ /* on certain actions. */
+ /* Thus, a callback function is used to check if it should turn on. */
+ /* See also button.c */
+ if ( (context & ~ALLOW_SOFTLOCK) == CONTEXT_WPS
+ || (context & ~ALLOW_SOFTLOCK) == CONTEXT_FM )
+ set_backlight_on_keypress_oracle(backlight_on_keypress_oracle);
+ else
+ set_backlight_on_keypress_oracle(NULL);
+
if (timeout == TIMEOUT_NOBLOCK)
button = button_get(false);
else if (timeout == TIMEOUT_BLOCK)
diff --git c/apps/lang/deutsch.lang w/apps/lang/deutsch.lang
index 55377c2..c749d75 100644
--- c/apps/lang/deutsch.lang
+++ w/apps/lang/deutsch.lang
@@ -2595,6 +2595,20 @@
+ id: LANG_BACKLIGHT_ON_VOLUME_CHANGE
+ desc: Backlight on volume change and on pause/play
+ user: core
+
+ *: "Backlight On Volume Change"
+
+
+ *: "Beleuchtung bei Änderung der Lautstärke"
+
+
+ *: "Beleuchtung bei Änderung der Lautstärke"
+
+
+
id: LANG_LCD_SLEEP_AFTER_BACKLIGHT_OFF
desc: In display settings, time to switch LCD chip into power saving state
user: core
diff --git c/apps/lang/english-us.lang w/apps/lang/english-us.lang
index a6549da..ad7ff2f 100644
--- c/apps/lang/english-us.lang
+++ w/apps/lang/english-us.lang
@@ -2591,6 +2591,20 @@
*: "First Buttonpress Enables Backlight Only"
+
+ id: LANG_BACKLIGHT_ON_VOLUME_CHANGE
+ desc: Backlight on volume change and on pause/play
+ user: core
+
+ *: "Backlight on Volume Change"
+
+
+ *: "Backlight on Volume Change"
+
+
+ *: "Backlight on Volume Change"
+
+
id: LANG_LCD_SLEEP_AFTER_BACKLIGHT_OFF
desc: In display settings, time to switch LCD chip into power saving state
diff --git c/apps/lang/english.lang w/apps/lang/english.lang
index 08cd743..04ff96e 100644
--- c/apps/lang/english.lang
+++ w/apps/lang/english.lang
@@ -2676,6 +2676,20 @@
*: "First Buttonpress Enables Backlight Only"
+
+ id: LANG_BACKLIGHT_ON_VOLUME_CHANGE
+ desc: Backlight on volume change and on pause/play
+ user: core
+
+ *: "Backlight on Volume Change"
+
+
+ *: "Backlight on Volume Change"
+
+
+ *: "Backlight on Volume Change"
+
+
id: LANG_LCD_SLEEP_AFTER_BACKLIGHT_OFF
desc: In display settings, time to switch LCD chip into power saving state
diff --git c/apps/menus/display_menu.c w/apps/menus/display_menu.c
index 3e1443d..b1063ea 100644
--- c/apps/menus/display_menu.c
+++ w/apps/menus/display_menu.c
@@ -103,6 +103,9 @@ MENUITEM_SETTING(backlight_fade_out, &global_settings.backlight_fade_out, NULL);
MENUITEM_SETTING(bl_filter_first_keypress,
&global_settings.bl_filter_first_keypress,
filterfirstkeypress_callback);
+MENUITEM_SETTING(backlight_on_volume_change,
+ &global_settings.backlight_on_volume_change,
+ NULL);
#ifdef HAVE_LCD_SLEEP_SETTING
MENUITEM_SETTING(lcd_sleep_after_backlight_off,
&global_settings.lcd_sleep_after_backlight_off, NULL);
@@ -140,6 +143,7 @@ MAKE_MENU(lcd_settings,ID2P(LANG_LCD_MENU),
,&backlight_fade_in, &backlight_fade_out
#endif
,&bl_filter_first_keypress
+ ,&backlight_on_volume_change
# ifdef HAVE_LCD_SLEEP_SETTING
,&lcd_sleep_after_backlight_off
# endif
diff --git c/apps/settings.h w/apps/settings.h
index 087ff0c..54e8a73 100644
--- c/apps/settings.h
+++ w/apps/settings.h
@@ -657,6 +657,8 @@ struct user_settings
then according to timeout_values[] */
bool caption_backlight; /* turn on backlight at end and start of track */
bool bl_filter_first_keypress; /* filter first keypress when dark? */
+ bool backlight_on_volume_change; /* turn on the backlight on volume change
+ and on pause/play? */
#if CONFIG_CHARGING
int backlight_timeout_plugged;
#endif
diff --git c/apps/settings_list.c w/apps/settings_list.c
index 53e79fa..18538a3 100644
--- c/apps/settings_list.c
+++ w/apps/settings_list.c
@@ -1010,6 +1010,9 @@ const struct settings_list settings[] = {
OFFON_SETTING(0, bl_filter_first_keypress,
LANG_BACKLIGHT_FILTER_FIRST_KEYPRESS, false,
"backlight filters first keypress", NULL),
+ OFFON_SETTING(0, backlight_on_volume_change,
+ LANG_BACKLIGHT_ON_VOLUME_CHANGE, true,
+ "backlight on volume change", NULL),
#ifdef HAVE_REMOTE_LCD
OFFON_SETTING(0, remote_bl_filter_first_keypress,
LANG_BACKLIGHT_FILTER_FIRST_KEYPRESS, false,
diff --git c/firmware/drivers/button.c w/firmware/drivers/button.c
index c165e8f..2b50dd2 100644
--- c/firmware/drivers/button.c
+++ w/firmware/drivers/button.c
@@ -41,6 +41,7 @@
#ifdef HAVE_REMOTE_LCD
#include "lcd-remote.h"
#endif
+//#include "debug.h"
struct event_queue button_queue SHAREDBSS_ATTR;
@@ -52,6 +53,7 @@ static bool flipped; /* buttons can be flipped to match the LCD flip */
#endif
#ifdef HAVE_BACKLIGHT
static bool filter_first_keypress;
+static backlight_on_keypress_oracle_func backlight_on_keypress_oracle = NULL;
#ifdef HAVE_REMOTE_LCD
static bool remote_filter_first_keypress;
#endif
@@ -138,6 +140,28 @@ static bool button_try_post(int button, int data)
return ret;
}
+void backlight_on_by_button(int btn)
+{
+ bool bl_on;
+ if (backlight_on_keypress_oracle != NULL)
+ {
+ bl_on = (*backlight_on_keypress_oracle)(btn);
+ //DEBUGF("BL oracle (%d) returned: %d\n", btn, bl_on);
+ }
+ else
+ {
+ bl_on = true;
+ //DEBUGF("BL callback is NULL -> bl ON\n");
+ }
+ if (bl_on)
+ {
+ backlight_on();
+#ifdef HAVE_BUTTON_LIGHT
+ buttonlight_on();
+#endif
+ }
+}
+
static void button_tick(void)
{
static int count = 0;
@@ -308,10 +332,13 @@ static void button_tick(void)
skip_remote_release = true;
}
else
-#endif
- if (!filter_first_keypress || is_backlight_on(false)
+#endif /* HAVE_REMOTE_LCD */
+ if (!filter_first_keypress
+ || is_backlight_on(false)
+ || ((backlight_on_keypress_oracle != NULL)
+ && !(*backlight_on_keypress_oracle)(btn))
#if BUTTON_REMOTE
- || (btn & BUTTON_REMOTE)
++ || (btn & BUTTON_REMOTE)
#endif
)
button_try_post(btn, data);
@@ -327,12 +354,7 @@ static void button_tick(void)
remote_backlight_on();
else
#endif
- {
- backlight_on();
-#ifdef HAVE_BUTTON_LIGHT
- buttonlight_on();
-#endif
- }
+ backlight_on_by_button(btn);
reset_poweroff_timer();
}
@@ -447,6 +469,7 @@ void button_init(void)
#endif
#ifdef HAVE_BACKLIGHT
filter_first_keypress = false;
+ set_backlight_on_keypress_oracle(NULL);
#ifdef HAVE_REMOTE_LCD
remote_filter_first_keypress = false;
#endif
@@ -560,6 +583,12 @@ void set_backlight_filter_keypress(bool value)
{
filter_first_keypress = value;
}
+
+void set_backlight_on_keypress_oracle(backlight_on_keypress_oracle_func new_value)
+{
+ backlight_on_keypress_oracle = new_value;
+}
+
#ifdef HAVE_REMOTE_LCD
void set_remote_backlight_filter_keypress(bool value)
{
diff --git c/firmware/export/button.h w/firmware/export/button.h
index 6276a03..351e91c 100644
--- c/firmware/export/button.h
+++ w/firmware/export/button.h
@@ -64,6 +64,22 @@ void button_set_flip(bool flip); /* turn 180 degrees */
#endif
#ifdef HAVE_BACKLIGHT
void set_backlight_filter_keypress(bool value);
+/* Callback function to tell whether the backlight should be turned on
+ * when a key is pressed. Called just after a key press.
+ *
+ * @param btn The button that was pressed
+ *
+ * Returns true iff the backlight should be turned on on key press.
+ */
+typedef bool (*backlight_on_keypress_oracle_func)(int btn);
+
+/* Sets the new 'oracle' to tell whether the backlight should be turned
+ * on when a key is pressed. Passing NULL as parameter will turn on the BL
+ * on every key press.
+ */
+void set_backlight_on_keypress_oracle(backlight_on_keypress_oracle_func func);
+void backlight_on_by_button(int btn);
+
#ifdef HAVE_REMOTE_LCD
void set_remote_backlight_filter_keypress(bool value);
#endif
diff --git c/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c w/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
index 8244c47..0f7d16c 100644
--- c/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
+++ w/firmware/target/arm/as3525/sansa-fuzev2/button-fuzev2.c
@@ -168,7 +168,7 @@ static void scrollwheel(unsigned int wheel_value)
(wheel_delta << 24) | wheel_velocity*360/WHEELCLICKS_PER_ROTATION);
/* message posted - reset delta and poke backlight on*/
wheel_delta = 1;
- backlight_on();
+ backlight_on_by_button(btn);
buttonlight_on();
}
else
diff --git c/firmware/target/arm/ipod/button-1g-3g.c w/firmware/target/arm/ipod/button-1g-3g.c
index 045a0f6..790ed24 100644
--- c/firmware/target/arm/ipod/button-1g-3g.c
+++ w/firmware/target/arm/ipod/button-1g-3g.c
@@ -95,13 +95,6 @@ static void handle_scroll_wheel(int new_scroll)
count = 0;
}
- /* poke backlight every 1/4s of activity */
- if (TIME_AFTER(current_tick, next_backlight_on)) {
- backlight_on();
- reset_poweroff_timer();
- next_backlight_on = current_tick + HZ/4;
- }
-
/* has wheel travelled far enough? */
if (++count < WHEEL_BASE_SENSITIVITY) {
return;
@@ -126,6 +119,13 @@ static void handle_scroll_wheel(int new_scroll)
/* have a keycode */
+ /* poke backlight every 1/4s of activity */
+ if (TIME_AFTER(current_tick, next_backlight_on)) {
+ backlight_on_by_button(wheel_keycode);
+ reset_poweroff_timer();
+ next_backlight_on = current_tick + HZ/4;
+ }
+
usec = USEC_TIMER;
v = usec - last_wheel_usec;
diff --git c/firmware/target/arm/ipod/button-clickwheel.c w/firmware/target/arm/ipod/button-clickwheel.c
index 13c765c..31fa813 100644
--- c/firmware/target/arm/ipod/button-clickwheel.c
+++ w/firmware/target/arm/ipod/button-clickwheel.c
@@ -132,8 +132,7 @@ static inline int ipod_4g_button_read(void)
new_wheel_value = (status >> 16) & 0x7f;
whl = new_wheel_value;
- /* switch on backlight (again), reset power-off timer */
- backlight_on();
+ /* reset power-off timer */
reset_poweroff_timer();
/* Check whether the scrollwheel was untouched by accident or by will. */
@@ -176,6 +175,9 @@ static inline int ipod_4g_button_read(void)
if (wheel_keycode != BUTTON_NONE)
{
+ /* switch on backlight (again) */
+ backlight_on_by_button(wheel_keycode);
+
long v = (usec - last_wheel_usec) & 0x7fffffff;
/* undo signedness */
diff --git c/firmware/target/arm/ipod/button-mini1g.c w/firmware/target/arm/ipod/button-mini1g.c
index d4a75c9..e860f7f 100644
--- c/firmware/target/arm/ipod/button-mini1g.c
+++ w/firmware/target/arm/ipod/button-mini1g.c
@@ -91,13 +91,6 @@ static void handle_scroll_wheel(int new_scroll)
return;
}
- /* poke backlight every 1/4s of activity */
- if (TIME_AFTER(current_tick, next_backlight_on)) {
- backlight_on();
- reset_poweroff_timer();
- next_backlight_on = current_tick + HZ/4;
- }
-
if (++count < WHEEL_BASE_SENSITIVITY)
return;
@@ -117,6 +110,11 @@ static void handle_scroll_wheel(int new_scroll)
}
/* have a keycode */
+
+ /* poke backlight every 1/4s of activity */
+ if (TIME_AFTER(current_tick, next_backlight_on)) {
+ backlight_on_by_button(wheel_keycode);
+ }
usec = USEC_TIMER;
v = usec - last_wheel_usec;
diff --git c/firmware/target/arm/sandisk/sansa-e200/button-e200.c w/firmware/target/arm/sandisk/sansa-e200/button-e200.c
index 1e952b3..cd79023 100644
--- c/firmware/target/arm/sandisk/sansa-e200/button-e200.c
+++ w/firmware/target/arm/sandisk/sansa-e200/button-e200.c
@@ -170,7 +170,7 @@ void clickwheel_int(void)
/* Poke backlight to turn it on or maintain it no more often
* than every 1/4 second */
next_backlight_on = current_tick + HZ/4;
- backlight_on();
+ backlight_on_by_button(keycode);
#ifdef HAVE_BUTTON_LIGHT
buttonlight_on();
#endif