blob: 48d9e0912e55027576faf918af25320f7f2b8de0 [file] [log] [blame]
Daniel Stenberg09fce702005-11-18 09:03:25 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Jerome Kuptz
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Daniel Stenberg09fce702005-11-18 09:03:25 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
Christi Scarboroughf8cc3212005-11-17 20:20:01 +000021#include <stdio.h>
22#include <string.h>
23#include <stdlib.h>
Jonathan Gordon5e5bfab2006-08-16 13:25:45 +000024#include "config.h"
Christi Scarboroughf8cc3212005-11-17 20:20:01 +000025
26#include "system.h"
27#include "file.h"
28#include "lcd.h"
29#include "font.h"
30#include "backlight.h"
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +000031#include "action.h"
Christi Scarboroughf8cc3212005-11-17 20:20:01 +000032#include "kernel.h"
Jonathan Gordon36a2e302007-04-18 13:03:01 +000033#include "filetypes.h"
Christi Scarboroughf8cc3212005-11-17 20:20:01 +000034#include "settings.h"
Jonathan Gordonb5442f82009-08-03 04:57:43 +000035#include "skin_engine/skin_engine.h"
Jonathan Gordon5e5fc642009-07-27 07:21:05 +000036#include "mp3_playback.h"
Christi Scarboroughf8cc3212005-11-17 20:20:01 +000037#include "audio.h"
38#include "usb.h"
39#include "status.h"
Frank Gevaerts2f8a0082008-11-01 16:14:28 +000040#include "storage.h"
Christi Scarboroughf8cc3212005-11-17 20:20:01 +000041#include "screens.h"
42#include "playlist.h"
43#ifdef HAVE_LCD_BITMAP
44#include "icons.h"
45#include "peakmeter.h"
46#endif
Christi Scarboroughf8cc3212005-11-17 20:20:01 +000047#include "lang.h"
48#include "bookmark.h"
49#include "misc.h"
50#include "sound.h"
51#include "onplay.h"
52#include "abrepeat.h"
53#include "playback.h"
Christi Scarboroughf8cc3212005-11-17 20:20:01 +000054#include "splash.h"
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +000055#include "cuesheet.h"
Jonathan Gordond9f7ac22006-11-08 02:23:01 +000056#include "ata_idle_notify.h"
Jonathan Gordon91cb68a2007-03-01 11:14:46 +000057#include "root_menu.h"
Nicolas Pennequin1cf2ec32007-04-25 22:08:00 +000058#include "backdrop.h"
Jonathan Gordonea664e02008-05-03 12:30:40 +000059#include "quickscreen.h"
Jonathan Gordon1da2f012008-10-05 13:01:54 +000060#include "pitchscreen.h"
Jonathan Gordon71898e52008-10-16 10:38:03 +000061#include "appevents.h"
Jonathan Gordonb86f2d02009-01-02 01:43:00 +000062#include "viewport.h"
Thomas Martitz74aba342009-03-12 18:50:24 +000063#include "pcmbuf.h"
Jonathan Gordonc1267dc2009-05-15 05:36:16 +000064#include "option_select.h"
65#include "dsp.h"
Thomas Martitz5c9fe522009-07-22 22:10:25 +000066#include "playlist_viewer.h"
Jonathan Gordonb5442f82009-08-03 04:57:43 +000067#include "wps.h"
Thomas Martitz1016ee42009-10-19 15:28:15 +000068#include "statusbar-skinned.h"
Nicolas Pennequin1cf2ec32007-04-25 22:08:00 +000069
Thomas Martitzaad712d2009-03-17 01:56:20 +000070#define RESTORE_WPS_INSTANTLY 0l
71#define RESTORE_WPS_NEXT_SECOND ((long)(HZ+current_tick))
Thomas Martitz218b3122009-08-03 22:39:27 +000072
73#define FF_REWIND_MAX_PERCENT 3 /* cap ff/rewind step size at max % of file */
74 /* 3% of 30min file == 54s step size */
75#define MIN_FF_REWIND_STEP 500
76
Nils Wallménius20338ca2006-12-13 11:52:21 +000077/* initial setup of wps_data */
78static void wps_state_init(void);
Jonathan Gordon843c7ef2009-04-06 00:39:43 +000079static void track_changed_callback(void *param);
80static void nextid3available_callback(void* param);
Thomas Martitzec7a0c52009-04-14 22:13:29 +000081
Thomas Martitze510de12009-08-20 14:29:03 +000082#define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
83#ifdef HAVE_REMOTE_LCD
84#define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
85#define DEFAULT_WPS(screen) ((screen) == SCREEN_MAIN ? \
86 WPS_DEFAULTCFG:RWPS_DEFAULTCFG)
87#else
88#define DEFAULT_WPS(screen) (WPS_DEFAULTCFG)
89#endif
90
Jonathan Gordon9928e342010-09-14 11:56:50 +000091char* wps_default_skin(enum screen_type screen)
Thomas Martitz3b75c862009-08-03 15:06:30 +000092{
Jonathan Gordon9928e342010-09-14 11:56:50 +000093 static char *skin_buf[NB_SCREENS] = {
Thomas Martitz218b3122009-08-03 22:39:27 +000094#ifdef HAVE_LCD_BITMAP
Jonathan Gordoneee54232010-01-29 07:52:13 +000095#if LCD_DEPTH > 1
Jonathan Gordon5b0521c2010-06-07 03:44:11 +000096 "%X(d)\n"
Jonathan Gordoneee54232010-01-29 07:52:13 +000097#endif
Thomas Martitz218b3122009-08-03 22:39:27 +000098 "%s%?it<%?in<%in. |>%it|%fn>\n"
Jonathan Gordon5b0521c2010-06-07 03:44:11 +000099 "%s%?ia<%ia|%?d(2)<%d(2)|%(root%)>>\n"
100 "%s%?id<%id|%?d(1)<%d(1)|%(root%)>> %?iy<%(%iy%)|>\n\n"
Thomas Martitz218b3122009-08-03 22:39:27 +0000101 "%al%pc/%pt%ar[%pp:%pe]\n"
Jonathan Gordon5b0521c2010-06-07 03:44:11 +0000102 "%fbkBit %?fv<avg|> %?iv<%(id3v%iv%)|%(no id3%)>\n"
Thomas Martitz218b3122009-08-03 22:39:27 +0000103 "%pb\n%pm\n",
104#else
Jonathan Gordon5b0521c2010-06-07 03:44:11 +0000105 "%s%pp/%pe: %?it<%it|%fn> - %?ia<%ia|%d(2)> - %?id<%id|%d(1)>\n"
Thomas Martitz218b3122009-08-03 22:39:27 +0000106 "%pc%?ps<*|/>%pt\n",
107#endif
108#ifdef HAVE_REMOTE_LCD
Jonathan Gordoneee54232010-01-29 07:52:13 +0000109#if LCD_REMOTE_DEPTH > 1
Jonathan Gordon5b0521c2010-06-07 03:44:11 +0000110 "%X(d)\n"
Jonathan Gordoneee54232010-01-29 07:52:13 +0000111#endif
Jonathan Gordon5b0521c2010-06-07 03:44:11 +0000112 "%s%?ia<%ia|%?d(2)<%d(2)|%(root%)>>\n"
Thomas Martitz218b3122009-08-03 22:39:27 +0000113 "%s%?it<%?in<%in. |>%it|%fn>\n"
114 "%al%pc/%pt%ar[%pp:%pe]\n"
Jonathan Gordon5b0521c2010-06-07 03:44:11 +0000115 "%fbkBit %?fv<avg|> %?iv<%(id3v%iv%)|%(no id3%)>\n"
Thomas Martitz218b3122009-08-03 22:39:27 +0000116 "%pb\n",
117#endif
118 };
Jonathan Gordon9928e342010-09-14 11:56:50 +0000119 return skin_buf[screen];
Thomas Martitz3b75c862009-08-03 15:06:30 +0000120}
121
Michael Sevakis5078d462011-08-23 01:37:59 +0000122static void update_non_static(void)
123{
124 int i;
125 FOR_NB_SCREENS(i)
126 skin_update(WPS, i, SKIN_REFRESH_NON_STATIC);
127}
128
Michael Hohmuth84301c12011-05-09 12:59:46 +0000129void pause_action(bool may_fade, bool updatewps)
130{
Michael Sevakis5078d462011-08-23 01:37:59 +0000131#if CONFIG_CODEC == SWCODEC
132 /* Do audio first, then update, unless skin were to use its local
133 status in which case, reverse it */
134 audio_pause();
135
136 if (updatewps)
137 update_non_static();
138#else
Michael Hohmuth84301c12011-05-09 12:59:46 +0000139 if (may_fade && global_settings.fade_on_stop)
140 fade(false, updatewps);
141 else
142 audio_pause();
Michael Sevakis5078d462011-08-23 01:37:59 +0000143#endif
Michael Hohmuth5aec3c22011-05-13 22:28:47 +0000144
145 if (global_settings.pause_rewind) {
146 long newpos;
147
148#if (CONFIG_CODEC == SWCODEC)
149 audio_pre_ff_rewind();
150#endif
151 newpos = audio_current_track()->elapsed
152 - global_settings.pause_rewind * 1000;
153 audio_ff_rewind(newpos > 0 ? newpos : 0);
154 }
Michael Sevakisa2b67032011-06-29 06:37:04 +0000155
Michael Sevakis5078d462011-08-23 01:37:59 +0000156 (void)may_fade;
Michael Hohmuth84301c12011-05-09 12:59:46 +0000157}
158
159void unpause_action(bool may_fade, bool updatewps)
160{
Michael Sevakis5078d462011-08-23 01:37:59 +0000161#if CONFIG_CODEC == SWCODEC
162 /* Do audio first, then update, unless skin were to use its local
163 status in which case, reverse it */
164 audio_resume();
165
166 if (updatewps)
167 update_non_static();
168#else
Michael Hohmuth84301c12011-05-09 12:59:46 +0000169 if (may_fade && global_settings.fade_on_stop)
170 fade(true, updatewps);
171 else
172 audio_resume();
Michael Sevakis5078d462011-08-23 01:37:59 +0000173#endif
174
175 (void)may_fade;
Michael Hohmuth84301c12011-05-09 12:59:46 +0000176}
177
Michael Sevakisa2b67032011-06-29 06:37:04 +0000178#if CONFIG_CODEC != SWCODEC
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000179void fade(bool fade_in, bool updatewps)
180{
181 int fp_global_vol = global_settings.volume << 8;
182 int fp_min_vol = sound_min(SOUND_VOLUME) << 8;
Björn Stenbergb8f29c72011-03-10 22:25:18 +0000183 int fp_step = (fp_global_vol - fp_min_vol) / 10;
Michael Sevakis5078d462011-08-23 01:37:59 +0000184
Jonathan Gordon9928e342010-09-14 11:56:50 +0000185 skin_get_global_state()->is_fading = !fade_in;
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000186 if (fade_in) {
187 /* fade in */
188 int fp_volume = fp_min_vol;
189
190 /* zero out the sound */
191 sound_set_volume(fp_min_vol >> 8);
192
193 sleep(HZ/10); /* let audio thread run */
194 audio_resume();
195
Michael Sevakis5078d462011-08-23 01:37:59 +0000196 if (updatewps)
197 update_non_static();
Björn Stenbergb8f29c72011-03-10 22:25:18 +0000198
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000199 while (fp_volume < fp_global_vol - fp_step) {
200 fp_volume += fp_step;
201 sound_set_volume(fp_volume >> 8);
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000202 sleep(1);
203 }
204 sound_set_volume(global_settings.volume);
205 }
206 else {
207 /* fade out */
208 int fp_volume = fp_global_vol;
209
Michael Sevakis5078d462011-08-23 01:37:59 +0000210 if (updatewps)
211 update_non_static();
Björn Stenbergb8f29c72011-03-10 22:25:18 +0000212
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000213 while (fp_volume > fp_min_vol + fp_step) {
214 fp_volume -= fp_step;
215 sound_set_volume(fp_volume >> 8);
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000216 sleep(1);
217 }
218 audio_pause();
Björn Stenbergb8f29c72011-03-10 22:25:18 +0000219
Jonathan Gordon9928e342010-09-14 11:56:50 +0000220 skin_get_global_state()->is_fading = false;
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000221#if CONFIG_CODEC != SWCODEC
222#ifndef SIMULATOR
223 /* let audio thread run and wait for the mas to run out of data */
224 while (!mp3_pause_done())
225#endif
226 sleep(HZ/10);
227#endif
228
229 /* reset volume to what it was before the fade */
230 sound_set_volume(global_settings.volume);
231 }
232}
Michael Sevakisa2b67032011-06-29 06:37:04 +0000233#endif /* SWCODEC */
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000234
Jonathan Gordon9928e342010-09-14 11:56:50 +0000235static bool update_onvol_change(enum screen_type screen)
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000236{
Jonathan Gordon9928e342010-09-14 11:56:50 +0000237 skin_update(WPS, screen, SKIN_REFRESH_NON_STATIC);
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000238
239#ifdef HAVE_LCD_CHARCELLS
240 splashf(0, "Vol: %3d dB",
241 sound_val2phys(SOUND_VOLUME, global_settings.volume));
242 return true;
243#endif
244 return false;
245}
246
Thomas Martitz3b75c862009-08-03 15:06:30 +0000247
Jonathan Gordona398c282010-06-21 06:04:19 +0000248#ifdef HAVE_TOUCHSCREEN
Bertrik Sikken76f4c022010-07-31 13:41:06 +0000249static int skintouch_to_wps(struct wps_data *data)
Jonathan Gordona398c282010-06-21 06:04:19 +0000250{
251 int offset = 0;
Jonathan Gordon4caa8322010-09-06 13:33:49 +0000252 struct touchregion *region;
253 int button = skin_get_touchaction(data, &offset, &region);
Jonathan Gordona398c282010-06-21 06:04:19 +0000254 switch (button)
255 {
256 case ACTION_STD_PREV:
257 return ACTION_WPS_SKIPPREV;
258 case ACTION_STD_PREVREPEAT:
259 return ACTION_WPS_SEEKBACK;
260 case ACTION_STD_NEXT:
261 return ACTION_WPS_SKIPNEXT;
262 case ACTION_STD_NEXTREPEAT:
263 return ACTION_WPS_SEEKFWD;
264 case ACTION_STD_MENU:
265 return ACTION_WPS_MENU;
266 case ACTION_STD_CONTEXT:
267 return ACTION_WPS_CONTEXT;
268 case ACTION_STD_QUICKSCREEN:
269 return ACTION_WPS_QUICKSCREEN;
Jonathan Gordonc2017722010-06-21 12:14:16 +0000270#ifdef HAVE_HOTKEY
271 case ACTION_STD_HOTKEY:
272 return ACTION_WPS_HOTKEY;
273#endif
Jonathan Gordon443b1342011-03-27 07:23:38 +0000274 case ACTION_TOUCH_SCROLLBAR:
Jonathan Gordon9928e342010-09-14 11:56:50 +0000275 skin_get_global_state()->id3->elapsed = skin_get_global_state()->id3->length*offset/100;
Jonathan Gordona398c282010-06-21 06:04:19 +0000276#if (CONFIG_CODEC == SWCODEC)
Michael Sevakisc537d592011-04-27 03:08:23 +0000277 audio_pre_ff_rewind();
Jonathan Gordona398c282010-06-21 06:04:19 +0000278#else
Michael Sevakisc537d592011-04-27 03:08:23 +0000279 if (!skin_get_global_state()->paused)
Jonathan Gordona398c282010-06-21 06:04:19 +0000280 audio_pause();
281#endif
Jonathan Gordon9928e342010-09-14 11:56:50 +0000282 audio_ff_rewind(skin_get_global_state()->id3->elapsed);
Jonathan Gordona398c282010-06-21 06:04:19 +0000283#if (CONFIG_CODEC != SWCODEC)
Jonathan Gordon9928e342010-09-14 11:56:50 +0000284 if (!skin_get_global_state()->paused)
Jonathan Gordona398c282010-06-21 06:04:19 +0000285 audio_resume();
286#endif
287 return ACTION_TOUCHSCREEN;
Jonathan Gordon443b1342011-03-27 07:23:38 +0000288 case ACTION_TOUCH_VOLUME:
Jonathan Gordona398c282010-06-21 06:04:19 +0000289 {
290 const int min_vol = sound_min(SOUND_VOLUME);
291 const int max_vol = sound_max(SOUND_VOLUME);
292 global_settings.volume = (offset * (max_vol - min_vol)) / 100;
293 global_settings.volume += min_vol;
294 setvol();
295 }
296 return ACTION_TOUCHSCREEN;
297 }
298 return button;
299}
Bertrik Sikken76f4c022010-07-31 13:41:06 +0000300#endif /* HAVE_TOUCHSCREEN */
Jonathan Gordona398c282010-06-21 06:04:19 +0000301
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000302bool ffwd_rew(int button)
303{
304 unsigned int step = 0; /* current ff/rewind step */
305 unsigned int max_step = 0; /* maximum ff/rewind step */
306 int ff_rewind_count = 0; /* current ff/rewind count (in ticks) */
307 int direction = -1; /* forward=1 or backward=-1 */
308 bool exit = false;
309 bool usb = false;
310 int i = 0;
311 const long ff_rw_accel = (global_settings.ff_rewind_accel + 3);
312
313 if (button == ACTION_NONE)
314 {
315 status_set_ffmode(0);
316 return usb;
317 }
318 while (!exit)
319 {
320 switch ( button )
321 {
322 case ACTION_WPS_SEEKFWD:
323 direction = 1;
324 case ACTION_WPS_SEEKBACK:
Jonathan Gordon9928e342010-09-14 11:56:50 +0000325 if (skin_get_global_state()->ff_rewind)
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000326 {
327 if (direction == 1)
328 {
329 /* fast forwarding, calc max step relative to end */
Jonathan Gordon9928e342010-09-14 11:56:50 +0000330 max_step = (skin_get_global_state()->id3->length -
331 (skin_get_global_state()->id3->elapsed +
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000332 ff_rewind_count)) *
333 FF_REWIND_MAX_PERCENT / 100;
334 }
335 else
336 {
337 /* rewinding, calc max step relative to start */
Jonathan Gordon9928e342010-09-14 11:56:50 +0000338 max_step = (skin_get_global_state()->id3->elapsed + ff_rewind_count) *
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000339 FF_REWIND_MAX_PERCENT / 100;
340 }
341
342 max_step = MAX(max_step, MIN_FF_REWIND_STEP);
343
344 if (step > max_step)
345 step = max_step;
346
347 ff_rewind_count += step * direction;
348
349 /* smooth seeking by multiplying step by: 1 + (2 ^ -accel) */
350 step += step >> ff_rw_accel;
351 }
352 else
353 {
354 if ( (audio_status() & AUDIO_STATUS_PLAY) &&
Jonathan Gordon9928e342010-09-14 11:56:50 +0000355 skin_get_global_state()->id3 && skin_get_global_state()->id3->length )
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000356 {
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000357#if (CONFIG_CODEC == SWCODEC)
Michael Sevakisc537d592011-04-27 03:08:23 +0000358 audio_pre_ff_rewind();
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000359#else
Michael Sevakisc537d592011-04-27 03:08:23 +0000360 if (!skin_get_global_state()->paused)
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000361 audio_pause();
362#endif
363#if CONFIG_KEYPAD == PLAYER_PAD
364 FOR_NB_SCREENS(i)
Jonathan Gordon9928e342010-09-14 11:56:50 +0000365 skin_get_gwps(WPS, i)->display->stop_scroll();
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000366#endif
367 if (direction > 0)
368 status_set_ffmode(STATUS_FASTFORWARD);
369 else
370 status_set_ffmode(STATUS_FASTBACKWARD);
371
Jonathan Gordon9928e342010-09-14 11:56:50 +0000372 skin_get_global_state()->ff_rewind = true;
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000373
374 step = 1000 * global_settings.ff_rewind_min_step;
375 }
376 else
377 break;
378 }
379
380 if (direction > 0) {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000381 if ((skin_get_global_state()->id3->elapsed + ff_rewind_count) >
382 skin_get_global_state()->id3->length)
383 ff_rewind_count = skin_get_global_state()->id3->length -
384 skin_get_global_state()->id3->elapsed;
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000385 }
386 else {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000387 if ((int)(skin_get_global_state()->id3->elapsed + ff_rewind_count) < 0)
388 ff_rewind_count = -skin_get_global_state()->id3->elapsed;
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000389 }
390
Jonathan Gordonb5442f82009-08-03 04:57:43 +0000391 /* set the wps state ff_rewind_count so the progess info
392 displays corectly */
Andree Buschmann4c385722011-01-25 21:40:55 +0000393 skin_get_global_state()->ff_rewind_count = ff_rewind_count;
394
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000395 FOR_NB_SCREENS(i)
Jonathan Gordonb5442f82009-08-03 04:57:43 +0000396 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000397 skin_update(WPS, i,
Jonathan Gordon2d31d772010-07-29 12:37:48 +0000398 SKIN_REFRESH_PLAYER_PROGRESS |
399 SKIN_REFRESH_DYNAMIC);
Jonathan Gordonb5442f82009-08-03 04:57:43 +0000400 }
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000401
402 break;
403
404 case ACTION_WPS_STOPSEEK:
Jonathan Gordon9928e342010-09-14 11:56:50 +0000405 skin_get_global_state()->id3->elapsed = skin_get_global_state()->id3->elapsed+ff_rewind_count;
406 audio_ff_rewind(skin_get_global_state()->id3->elapsed);
407 skin_get_global_state()->ff_rewind_count = 0;
408 skin_get_global_state()->ff_rewind = false;
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000409 status_set_ffmode(0);
410#if (CONFIG_CODEC != SWCODEC)
Jonathan Gordon9928e342010-09-14 11:56:50 +0000411 if (!skin_get_global_state()->paused)
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000412 audio_resume();
413#endif
414#ifdef HAVE_LCD_CHARCELLS
415 FOR_NB_SCREENS(i)
Jonathan Gordon9928e342010-09-14 11:56:50 +0000416 skin_update(WPS, i, SKIN_REFRESH_ALL);
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000417#endif
418 exit = true;
419 break;
420
421 default:
422 if(default_event_handler(button) == SYS_USB_CONNECTED) {
423 status_set_ffmode(0);
424 usb = true;
425 exit = true;
426 }
427 break;
428 }
429 if (!exit)
430 {
431 button = get_action(CONTEXT_WPS|ALLOW_SOFTLOCK,TIMEOUT_BLOCK);
432#ifdef HAVE_TOUCHSCREEN
433 if (button == ACTION_TOUCHSCREEN)
Jonathan Gordon9928e342010-09-14 11:56:50 +0000434 button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
Jonathan Gordoneada0902010-06-20 13:17:24 +0000435 if (button != ACTION_WPS_SEEKFWD &&
436 button != ACTION_WPS_SEEKBACK)
437 button = ACTION_WPS_STOPSEEK;
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000438#endif
Teruaki Kawashima5b2a5992009-08-29 16:25:04 +0000439 }
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000440 }
441 return usb;
442}
443
444
445void display_keylock_text(bool locked)
446{
447 int i;
448 FOR_NB_SCREENS(i)
Jonathan Gordon9928e342010-09-14 11:56:50 +0000449 skin_get_gwps(WPS, i)->display->stop_scroll();
Jonathan Gordon5e5fc642009-07-27 07:21:05 +0000450
451 splash(HZ, locked ? ID2P(LANG_KEYLOCK_ON) : ID2P(LANG_KEYLOCK_OFF));
452}
453
454
455
456
Thomas Martitzec7a0c52009-04-14 22:13:29 +0000457#if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD)
458static void gwps_caption_backlight(struct wps_state *state)
459{
460 if (state && state->id3)
461 {
462#ifdef HAVE_BACKLIGHT
463 if (global_settings.caption_backlight)
464 {
465 /* turn on backlight n seconds before track ends, and turn it off n
466 seconds into the new track. n == backlight_timeout, or 5s */
467 int n = global_settings.backlight_timeout * 1000;
468
469 if ( n < 1000 )
470 n = 5000; /* use 5s if backlight is always on or off */
471
472 if (((state->id3->elapsed < 1000) ||
473 ((state->id3->length - state->id3->elapsed) < (unsigned)n)) &&
474 (state->paused == false))
475 backlight_on();
476 }
477#endif
478#ifdef HAVE_REMOTE_LCD
479 if (global_settings.remote_caption_backlight)
480 {
481 /* turn on remote backlight n seconds before track ends, and turn it
482 off n seconds into the new track. n == remote_backlight_timeout,
483 or 5s */
484 int n = global_settings.remote_backlight_timeout * 1000;
485
486 if ( n < 1000 )
487 n = 5000; /* use 5s if backlight is always on or off */
488
489 if (((state->id3->elapsed < 1000) ||
490 ((state->id3->length - state->id3->elapsed) < (unsigned)n)) &&
491 (state->paused == false))
492 remote_backlight_on();
493 }
494#endif
495 }
496}
497#endif
498
499
Thomas Martitz23489be2009-04-04 20:33:38 +0000500static void change_dir(int direction)
501{
502 if (global_settings.prevent_skip)
503 return;
504
505 if (direction < 0)
506 audio_prev_dir();
507 else if (direction > 0)
508 audio_next_dir();
Jonathan Gordon0e445fc2009-07-03 05:08:33 +0000509 /* prevent the next dir to immediatly start being ffw'd */
510 action_wait_for_release();
Thomas Martitz23489be2009-04-04 20:33:38 +0000511}
512
513static void prev_track(unsigned long skip_thresh)
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000514{
Jonathan Gordon9928e342010-09-14 11:56:50 +0000515 struct wps_state *state = skin_get_global_state();
516 if (state->id3->elapsed < skip_thresh)
Thomas Martitz62f3e952009-03-27 13:53:29 +0000517 {
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000518 audio_prev();
Thomas Martitz62f3e952009-03-27 13:53:29 +0000519 return;
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000520 }
Thomas Martitz62f3e952009-03-27 13:53:29 +0000521 else
522 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000523 if (state->id3->cuesheet)
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000524 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000525 curr_cuesheet_skip(state->id3->cuesheet, -1, state->id3->elapsed);
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000526 return;
527 }
528
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000529#if (CONFIG_CODEC == SWCODEC)
Michael Sevakisc537d592011-04-27 03:08:23 +0000530 audio_pre_ff_rewind();
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000531#else
Michael Sevakisc537d592011-04-27 03:08:23 +0000532 if (!state->paused)
Mustapha Senhajiccad6d02011-01-18 00:37:17 +0000533 audio_pause();
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000534#endif
535
536 audio_ff_rewind(0);
537
538#if (CONFIG_CODEC != SWCODEC)
Jonathan Gordon9928e342010-09-14 11:56:50 +0000539 if (!state->paused)
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000540 audio_resume();
541#endif
542 }
543}
544
Bertrik Sikken7835a202008-05-08 20:37:26 +0000545static void next_track(void)
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000546{
Jonathan Gordon9928e342010-09-14 11:56:50 +0000547 struct wps_state *state = skin_get_global_state();
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000548 /* take care of if we're playing a cuesheet */
Jonathan Gordon9928e342010-09-14 11:56:50 +0000549 if (state->id3->cuesheet)
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000550 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000551 if (curr_cuesheet_skip(state->id3->cuesheet, 1, state->id3->elapsed))
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000552 {
553 /* if the result was false, then we really want
554 to skip to the next track */
555 return;
556 }
557 }
558
559 audio_next();
560}
Thomas Martitz74aba342009-03-12 18:50:24 +0000561
562static void play_hop(int direction)
563{
Jonathan Gordon9928e342010-09-14 11:56:50 +0000564 struct wps_state *state = skin_get_global_state();
Thomas Martitza7c888c2009-10-17 16:05:23 +0000565 long step = global_settings.skip_length*1000;
Jonathan Gordon9928e342010-09-14 11:56:50 +0000566 long elapsed = state->id3->elapsed;
567 long remaining = state->id3->length - elapsed;
Thomas Martitz74aba342009-03-12 18:50:24 +0000568
Thomas Martitza7c888c2009-10-17 16:05:23 +0000569 if (step < 0)
570 {
571 if (direction < 0)
572 {
573 prev_track(DEFAULT_SKIP_TRESH);
574 return;
575 }
576 else if (remaining < DEFAULT_SKIP_TRESH*2)
577 {
578 next_track();
579 return;
580 }
581 else
582 elapsed += (remaining - DEFAULT_SKIP_TRESH*2);
583 }
584 else if (!global_settings.prevent_skip &&
Alexander Levinbe7f5252009-04-05 19:29:21 +0000585 (!step ||
586 (direction > 0 && step >= remaining) ||
587 (direction < 0 && elapsed < DEFAULT_SKIP_TRESH)))
Thomas Martitz23489be2009-04-04 20:33:38 +0000588 { /* Do normal track skipping */
589 if (direction > 0)
Thomas Martitz8d598212009-03-27 13:57:56 +0000590 next_track();
Thomas Martitz23489be2009-04-04 20:33:38 +0000591 else if (direction < 0)
592 prev_track(DEFAULT_SKIP_TRESH);
593 return;
594 }
Thomas Martitza7c888c2009-10-17 16:05:23 +0000595 else if (direction == 1 && step >= remaining)
Thomas Martitz23489be2009-04-04 20:33:38 +0000596 {
Thomas Martitz74aba342009-03-12 18:50:24 +0000597#if CONFIG_CODEC == SWCODEC
Michael Sevakis5663e1c2011-07-08 22:31:15 +0000598 system_sound_play(SOUND_TRACK_NO_MORE);
Thomas Martitz74aba342009-03-12 18:50:24 +0000599#endif
600 return;
Thomas Martitz62f3e952009-03-27 13:53:29 +0000601 }
Thomas Martitz23489be2009-04-04 20:33:38 +0000602 else if ((direction == -1 && elapsed < step))
Thomas Martitz62f3e952009-03-27 13:53:29 +0000603 {
Thomas Martitz23489be2009-04-04 20:33:38 +0000604 elapsed = 0;
Thomas Martitz62f3e952009-03-27 13:53:29 +0000605 }
606 else
607 {
Thomas Martitz23489be2009-04-04 20:33:38 +0000608 elapsed += step * direction;
Thomas Martitz74aba342009-03-12 18:50:24 +0000609 }
Michael Sevakisc537d592011-04-27 03:08:23 +0000610 if(audio_status() & AUDIO_STATUS_PLAY)
Thomas Martitz62f3e952009-03-27 13:53:29 +0000611 {
Thomas Martitz74aba342009-03-12 18:50:24 +0000612#if (CONFIG_CODEC == SWCODEC)
613 audio_pre_ff_rewind();
614#else
Michael Sevakisc537d592011-04-27 03:08:23 +0000615 if (!state->paused)
616 audio_pause();
Thomas Martitz74aba342009-03-12 18:50:24 +0000617#endif
618 }
Michael Sevakisc537d592011-04-27 03:08:23 +0000619
620#if (CONFIG_CODEC == SWCODEC)
621 audio_ff_rewind(elapsed);
622#else
Jonathan Gordon9928e342010-09-14 11:56:50 +0000623 audio_ff_rewind(state->id3->elapsed = elapsed);
Jonathan Gordon9928e342010-09-14 11:56:50 +0000624 if (!state->paused)
Thomas Martitz74aba342009-03-12 18:50:24 +0000625 audio_resume();
626#endif
627}
628
Jonathan Gordon036fb052009-02-01 13:43:08 +0000629
Thomas Martitz7ce12e62009-04-09 08:30:05 +0000630#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
631/*
632 * If the user is unable to see the wps, because the display is deactivated,
Thomas Martitz2ad5e242009-07-10 16:27:24 +0000633 * we suppress updates until the wps is activated again (the lcd driver will
Thomas Martitz29cf2e12009-04-25 19:23:40 +0000634 * call this hook to issue an instant update)
Thomas Martitz7ce12e62009-04-09 08:30:05 +0000635 * */
Thomas Martitzd85c3ec2009-10-20 21:54:59 +0000636static void wps_lcd_activation_hook(void *param)
Thomas Martitz7ce12e62009-04-09 08:30:05 +0000637{
Thomas Martitzd85c3ec2009-10-20 21:54:59 +0000638 (void)param;
Jonathan Gordon9928e342010-09-14 11:56:50 +0000639 skin_request_full_update(WPS);
Thomas Martitz7ce12e62009-04-09 08:30:05 +0000640 /* force timeout in wps main loop, so that the update is instantly */
641 queue_post(&button_queue, BUTTON_NONE, 0);
642}
643#endif
Thomas Martitz68099092009-03-17 01:39:20 +0000644
Thomas Martitzaad712d2009-03-17 01:56:20 +0000645static void gwps_leave_wps(void)
646{
Jonathan Gordonb2eb44c2009-12-09 07:25:46 +0000647 int i;
Thomas Martitzaad712d2009-03-17 01:56:20 +0000648
Thomas Martitzce6b1162009-03-19 23:04:39 +0000649 FOR_NB_SCREENS(i)
Thomas Martitz4764ee02009-08-06 00:14:40 +0000650 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000651 skin_get_gwps(WPS, i)->display->stop_scroll();
Jonathan Gordon54ca7652010-02-08 09:47:08 +0000652#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
Jonathan Gordon9928e342010-09-14 11:56:50 +0000653 skin_backdrop_show(sb_get_backdrop(i));
Jonathan Gordon54ca7652010-02-08 09:47:08 +0000654#endif
Jonathan Gordon9928e342010-09-14 11:56:50 +0000655 viewportmanager_theme_undo(i, skin_has_sbs(i, skin_get_gwps(WPS, i)->data));
Jonathan Gordon9d1832c2009-12-21 05:19:12 +0000656
Thomas Martitz4764ee02009-08-06 00:14:40 +0000657 }
Thomas Martitzaad712d2009-03-17 01:56:20 +0000658
Thomas Martitz7ce12e62009-04-09 08:30:05 +0000659#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
660 /* Play safe and unregister the hook */
Thomas Martitzd85c3ec2009-10-20 21:54:59 +0000661 remove_event(LCD_EVENT_ACTIVATION, wps_lcd_activation_hook);
Thomas Martitz7ce12e62009-04-09 08:30:05 +0000662#endif
Thomas Martitz1016ee42009-10-19 15:28:15 +0000663 /* unhandle statusbar update delay */
664 sb_skin_set_update_delay(DEFAULT_UPDATE_DELAY);
Jonathan Gordonf0611f82010-08-04 12:00:18 +0000665#ifdef HAVE_TOUCHSCREEN
666 touchscreen_set_mode(global_settings.touch_mode);
667#endif
Thomas Martitzaad712d2009-03-17 01:56:20 +0000668}
669
Thomas Martitzbdf29612009-11-16 01:38:30 +0000670/*
671 * display the wps on entering or restoring */
672static void gwps_enter_wps(void)
673{
674 int i;
Jonathan Gordon9928e342010-09-14 11:56:50 +0000675 struct gui_wps *gwps;
676 struct screen *display;
Thomas Martitzbdf29612009-11-16 01:38:30 +0000677 FOR_NB_SCREENS(i)
678 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000679 gwps = skin_get_gwps(WPS, i);
680 display = gwps->display;
Jonathan Gordon7e6f1242010-02-08 09:38:03 +0000681 display->stop_scroll();
Jonathan Gordon9928e342010-09-14 11:56:50 +0000682 viewportmanager_theme_enable(i, skin_has_sbs(i, skin_get_gwps(WPS, i)->data), NULL);
Thomas Martitzbdf29612009-11-16 01:38:30 +0000683
Thomas Martitzbdf29612009-11-16 01:38:30 +0000684 /* Update the values in the first (default) viewport - in case the user
685 has modified the statusbar or colour settings */
686#if LCD_DEPTH > 1
687 if (display->depth > 1)
688 {
Jonathan Gordon343001b2011-03-07 12:45:45 +0000689 struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL,
690 SKIN_FIND_VP, gwps->data);
Jonathan Gordon489962d2010-08-10 14:15:03 +0000691 if (svp)
692 {
693 struct viewport *vp = &svp->vp;
694 vp->fg_pattern = display->get_foreground();
695 vp->bg_pattern = display->get_background();
696 }
Thomas Martitzbdf29612009-11-16 01:38:30 +0000697 }
Jonathan Gordon25653892010-01-27 06:47:56 +0000698#endif
Thomas Martitze8ae70a2010-01-26 21:29:08 +0000699 /* make the backdrop actually take effect */
Alex Parker3e4e67b2010-02-08 22:34:04 +0000700#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
Jonathan Gordon9928e342010-09-14 11:56:50 +0000701 skin_backdrop_show(gwps->data->backdrop_id);
Alex Parker3e4e67b2010-02-08 22:34:04 +0000702#endif
Thomas Martitze8ae70a2010-01-26 21:29:08 +0000703 display->clear_display();
Jonathan Gordon9928e342010-09-14 11:56:50 +0000704 skin_update(WPS, i, SKIN_REFRESH_ALL);
Jonathan Gordon31fb4f62010-02-24 06:19:25 +0000705
Thomas Martitzbdf29612009-11-16 01:38:30 +0000706 }
Jonathan Gordonf0611f82010-08-04 12:00:18 +0000707#ifdef HAVE_TOUCHSCREEN
Jonathan Gordon9928e342010-09-14 11:56:50 +0000708 gwps = skin_get_gwps(WPS, SCREEN_MAIN);
709 skin_disarm_touchregions(gwps->data);
710 if (!gwps->data->touchregions)
Jonathan Gordonf0611f82010-08-04 12:00:18 +0000711 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
712#endif
Thomas Martitze8ae70a2010-01-26 21:29:08 +0000713 /* force statusbar/skin update since we just cleared the whole screen */
714 send_event(GUI_EVENT_ACTIONUPDATE, (void*)1);
Thomas Martitzbdf29612009-11-16 01:38:30 +0000715}
716
Jonathan Gordon98881fd2011-03-22 09:31:45 +0000717void wps_do_playpause(bool updatewps)
718{
719 struct wps_state *state = skin_get_global_state();
720 if ( state->paused )
721 {
722 state->paused = false;
Michael Hohmuth84301c12011-05-09 12:59:46 +0000723 unpause_action(true, updatewps);
Jonathan Gordon98881fd2011-03-22 09:31:45 +0000724 }
725 else
726 {
727 state->paused = true;
Michael Hohmuth84301c12011-05-09 12:59:46 +0000728 pause_action(true, updatewps);
Jonathan Gordon98881fd2011-03-22 09:31:45 +0000729 settings_save();
730#if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
731 call_storage_idle_notifys(true); /* make sure resume info is saved */
732#endif
733 }
734}
735
736
Thomas Martitz68099092009-03-17 01:39:20 +0000737/* The WPS can be left in two ways:
738 * a) call a function, which draws over the wps. In this case, the wps
739 * will be still active (i.e. the below function didn't return)
740 * b) return with a value evaluated by root_menu.c, in this case the wps
741 * is really left, and root_menu will handle the next screen
742 *
743 * In either way, call gwps_leave_wps(), in order to restore the correct
744 * "main screen" backdrops and statusbars
745 */
Daniel Stenberg09fce702005-11-18 09:03:25 +0000746long gui_wps_show(void)
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000747{
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000748 long button = 0;
Thomas Martitz1d52b722009-04-08 17:11:50 +0000749 bool restore = true;
Thomas Martitzaad712d2009-03-17 01:56:20 +0000750 long restoretimer = RESTORE_WPS_INSTANTLY; /* timer to delay screen redraw temporarily */
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000751 bool exit = false;
Magnus Holmgrena50c2b12007-08-22 16:33:34 +0000752 bool bookmark = false;
Thomas Martitz1d52b722009-04-08 17:11:50 +0000753 bool update = false;
Thomas Martitz28aef1f2009-10-31 14:55:13 +0000754 bool vol_changed = false;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000755 int i;
Jonathan Gordon89ed8552006-08-22 07:57:40 +0000756 long last_left = 0, last_right = 0;
Jonathan Gordon9928e342010-09-14 11:56:50 +0000757 struct wps_state *state = skin_get_global_state();
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000758
759#ifdef HAVE_LCD_CHARCELLS
760 status_set_audio(true);
761 status_set_param(false);
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000762#endif
763
764#ifdef AB_REPEAT_ENABLE
765 ab_repeat_init();
766 ab_reset_markers();
767#endif
Thomas Martitz1d52b722009-04-08 17:11:50 +0000768 wps_state_init();
Jonathan Gordonb2eb44c2009-12-09 07:25:46 +0000769
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000770 while ( 1 )
771 {
772 bool audio_paused = (audio_status() & AUDIO_STATUS_PAUSE)?true:false;
Zakk Roberts87afd0b2006-03-21 07:59:23 +0000773
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000774 /* did someone else (i.e power thread) change audio pause mode? */
Jonathan Gordon9928e342010-09-14 11:56:50 +0000775 if (state->paused != audio_paused) {
776 state->paused = audio_paused;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000777
778 /* if another thread paused audio, we are probably in car mode,
779 about to shut down. lets save the settings. */
Jonathan Gordon9928e342010-09-14 11:56:50 +0000780 if (state->paused) {
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000781 settings_save();
Dave Chapman5009c9c2005-12-04 13:05:56 +0000782#if !defined(HAVE_RTC_RAM) && !defined(HAVE_SW_POWEROFF)
Frank Gevaerts2f8a0082008-11-01 16:14:28 +0000783 call_storage_idle_notifys(true);
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000784#endif
785 }
786 }
Jonathan Gordon9928e342010-09-14 11:56:50 +0000787 button = skin_wait_for_action(WPS, CONTEXT_WPS|ALLOW_SOFTLOCK,
Jonathan Gordon1bd072c2010-05-12 10:38:00 +0000788 restore ? 1 : HZ/5);
Jonathan Gordonc41bd042008-11-16 09:56:38 +0000789
Jens Arnoldae61b942009-03-29 17:58:24 +0000790 /* Exit if audio has stopped playing. This happens e.g. at end of
791 playlist or if using the sleep timer. */
792 if (!(audio_status() & AUDIO_STATUS_PLAY))
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000793 exit = true;
Jonathan Gordon0eb5dc62009-04-20 01:41:56 +0000794#ifdef HAVE_TOUCHSCREEN
795 if (button == ACTION_TOUCHSCREEN)
Jonathan Gordon9928e342010-09-14 11:56:50 +0000796 button = skintouch_to_wps(skin_get_gwps(WPS, SCREEN_MAIN)->data);
Jonathan Gordon0eb5dc62009-04-20 01:41:56 +0000797#endif
Marc Guay2bfcb952008-07-07 05:17:15 +0000798/* The iPods/X5/M5 use a single button for the A-B mode markers,
799 defined as ACTION_WPSAB_SINGLE in their config files. */
Jonathan Gordon7258b5e2006-12-22 05:19:56 +0000800#ifdef ACTION_WPSAB_SINGLE
801 if (!global_settings.party_mode && ab_repeat_mode_enabled())
802 {
803 static int wps_ab_state = 0;
804 if (button == ACTION_WPSAB_SINGLE)
805 {
806 switch (wps_ab_state)
807 {
808 case 0: /* set the A spot */
809 button = ACTION_WPS_ABSETA_PREVDIR;
810 break;
811 case 1: /* set the B spot */
812 button = ACTION_WPS_ABSETB_NEXTDIR;
813 break;
814 case 2:
Marcoen Hirschberg5d2b1e32007-04-13 15:42:25 +0000815 button = ACTION_WPS_ABRESET;
Jonathan Gordon7258b5e2006-12-22 05:19:56 +0000816 break;
817 }
818 wps_ab_state = (wps_ab_state+1) % 3;
819 }
820 }
821#endif
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000822 switch(button)
823 {
Jeffrey Goode847bd282010-05-09 02:07:42 +0000824#ifdef HAVE_HOTKEY
Jeffrey Gooded5e6bc72010-04-01 03:14:44 +0000825 case ACTION_WPS_HOTKEY:
Jeffrey Goode1ad76ff2010-05-09 02:02:51 +0000826 if (!global_settings.hotkey_wps)
827 break;
828 /* fall through */
Jeffrey Goode847bd282010-05-09 02:07:42 +0000829#endif
Jeffrey Goode1ad76ff2010-05-09 02:02:51 +0000830 case ACTION_WPS_CONTEXT:
Jonathan Gordon92961262009-01-02 01:29:13 +0000831 {
Jeffrey Gooded5e6bc72010-04-01 03:14:44 +0000832 bool hotkey = button == ACTION_WPS_HOTKEY;
Thomas Martitz68099092009-03-17 01:39:20 +0000833 gwps_leave_wps();
Jonathan Gordon9928e342010-09-14 11:56:50 +0000834 int retval = onplay(state->id3->path,
Jeffrey Gooded5e6bc72010-04-01 03:14:44 +0000835 FILE_ATTR_AUDIO, CONTEXT_WPS, hotkey);
Jonathan Gordona6f2b822007-11-04 12:40:18 +0000836 /* if music is stopped in the context menu we want to exit the wps */
Thomas Martitzc19e5362010-02-20 19:06:39 +0000837 if (retval == ONPLAY_MAINMENU
Jonathan Gordona6f2b822007-11-04 12:40:18 +0000838 || !audio_status())
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000839 return GO_TO_ROOT;
Thomas Martitzc19e5362010-02-20 19:06:39 +0000840 else if (retval == ONPLAY_PLAYLIST)
841 return GO_TO_PLAYLIST_VIEWER;
Jonathan Gordon10e24d22010-06-09 08:51:29 +0000842#ifdef HAVE_PICTUREFLOW_INTEGRATION
Jonathan Gordond871ff82010-06-09 04:25:41 +0000843 else if (retval == ONPLAY_PICTUREFLOW)
844 return GO_TO_PICTUREFLOW;
Jonathan Gordon881a5b92010-06-09 08:14:41 +0000845#endif
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000846 restore = true;
Jonathan Gordon92961262009-01-02 01:29:13 +0000847 }
848 break;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000849
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000850 case ACTION_WPS_BROWSE:
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000851#ifdef HAVE_LCD_CHARCELLS
Jonathan Gordonc41bd042008-11-16 09:56:38 +0000852 status_set_record(false);
853 status_set_audio(false);
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000854#endif
Thomas Martitzce6b1162009-03-19 23:04:39 +0000855 gwps_leave_wps();
Jonathan Gordonc41bd042008-11-16 09:56:38 +0000856 return GO_TO_PREVIOUS_BROWSER;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000857 break;
858
859 /* play/pause */
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000860 case ACTION_WPS_PLAY:
Björn Stenbergfc390af2006-03-19 08:40:31 +0000861 if (global_settings.party_mode)
862 break;
Jonathan Gordon98881fd2011-03-22 09:31:45 +0000863 wps_do_playpause(true);
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000864 break;
865
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000866 case ACTION_WPS_VOLUP:
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000867 global_settings.volume++;
Thomas Martitz28aef1f2009-10-31 14:55:13 +0000868 vol_changed = true;
869 break;
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000870 case ACTION_WPS_VOLDOWN:
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000871 global_settings.volume--;
Thomas Martitz28aef1f2009-10-31 14:55:13 +0000872 vol_changed = true;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000873 break;
Jonathan Gordon89ed8552006-08-22 07:57:40 +0000874 /* fast forward
Thomas Martitz62f3e952009-03-27 13:53:29 +0000875 OR next dir if this is straight after ACTION_WPS_SKIPNEXT */
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000876 case ACTION_WPS_SEEKFWD:
Jonathan Gordon89ed8552006-08-22 07:57:40 +0000877 if (global_settings.party_mode)
878 break;
Thomas Martitz23489be2009-04-04 20:33:38 +0000879 if (current_tick -last_right < HZ)
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000880 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000881 if (state->id3->cuesheet)
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000882 {
883 audio_next();
884 }
885 else
886 {
Thomas Martitz23489be2009-04-04 20:33:38 +0000887 change_dir(1);
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000888 }
889 }
Thomas Martitz62f3e952009-03-27 13:53:29 +0000890 else
891 ffwd_rew(ACTION_WPS_SEEKFWD);
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000892 last_right = last_left = 0;
Jonathan Gordon89ed8552006-08-22 07:57:40 +0000893 break;
894 /* fast rewind
Thomas Martitz62f3e952009-03-27 13:53:29 +0000895 OR prev dir if this is straight after ACTION_WPS_SKIPPREV,*/
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000896 case ACTION_WPS_SEEKBACK:
Björn Stenbergfc390af2006-03-19 08:40:31 +0000897 if (global_settings.party_mode)
898 break;
Thomas Martitz23489be2009-04-04 20:33:38 +0000899 if (current_tick -last_left < HZ)
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000900 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000901 if (state->id3->cuesheet)
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000902 {
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000903#if (CONFIG_CODEC == SWCODEC)
Michael Sevakisc537d592011-04-27 03:08:23 +0000904 audio_pre_ff_rewind();
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000905#else
Michael Sevakisc537d592011-04-27 03:08:23 +0000906 if (!state->paused)
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000907 audio_pause();
908#endif
909 audio_ff_rewind(0);
910 }
911 else
912 {
Thomas Martitz23489be2009-04-04 20:33:38 +0000913 change_dir(-1);
Nicolas Pennequin9f4bd872007-02-14 14:40:24 +0000914 }
915 }
Thomas Martitz62f3e952009-03-27 13:53:29 +0000916 else
917 ffwd_rew(ACTION_WPS_SEEKBACK);
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000918 last_left = last_right = 0;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000919 break;
920
921 /* prev / restart */
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000922 case ACTION_WPS_SKIPPREV:
Björn Stenbergfc390af2006-03-19 08:40:31 +0000923 if (global_settings.party_mode)
924 break;
Jonathan Gordon89ed8552006-08-22 07:57:40 +0000925 last_left = current_tick;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000926#ifdef AB_REPEAT_ENABLE
927 /* if we're in A/B repeat mode and the current position
928 is past the A marker, jump back to the A marker... */
Brandon Low8d5a6602006-01-21 23:43:57 +0000929 if ( ab_repeat_mode_enabled() )
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000930 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000931 if ( ab_after_A_marker(state->id3->elapsed) )
Brandon Low8d5a6602006-01-21 23:43:57 +0000932 {
933 ab_jump_to_A_marker();
934 break;
Brandon Low8d5a6602006-01-21 23:43:57 +0000935 }
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000936 }
Thomas Martitz23489be2009-04-04 20:33:38 +0000937 else
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000938 /* ...otherwise, do it normally */
939#endif
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000940 play_hop(-1);
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000941 break;
942
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000943 /* next
Thom Johansen4a7e0c72008-07-14 20:39:30 +0000944 OR if skip length set, hop by predetermined amount. */
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000945 case ACTION_WPS_SKIPNEXT:
Björn Stenbergfc390af2006-03-19 08:40:31 +0000946 if (global_settings.party_mode)
947 break;
Jonathan Gordon89ed8552006-08-22 07:57:40 +0000948 last_right = current_tick;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000949#ifdef AB_REPEAT_ENABLE
950 /* if we're in A/B repeat mode and the current position is
951 before the A marker, jump to the A marker... */
Brandon Low8d5a6602006-01-21 23:43:57 +0000952 if ( ab_repeat_mode_enabled() )
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000953 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000954 if ( ab_before_A_marker(state->id3->elapsed) )
Brandon Low8d5a6602006-01-21 23:43:57 +0000955 {
956 ab_jump_to_A_marker();
957 break;
Brandon Low8d5a6602006-01-21 23:43:57 +0000958 }
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000959 }
Thomas Martitz23489be2009-04-04 20:33:38 +0000960 else
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000961 /* ...otherwise, do it normally */
962#endif
Stéphane Doyonab0f7e12008-05-04 13:47:58 +0000963 play_hop(1);
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000964 break;
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000965 /* next / prev directories */
Jonathan Gordon5e5bfab2006-08-16 13:25:45 +0000966 /* and set A-B markers if in a-b mode */
967 case ACTION_WPS_ABSETB_NEXTDIR:
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000968 if (global_settings.party_mode)
969 break;
Jonathan Gordon5e5bfab2006-08-16 13:25:45 +0000970#if defined(AB_REPEAT_ENABLE)
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000971 if (ab_repeat_mode_enabled())
972 {
Jonathan Gordon9928e342010-09-14 11:56:50 +0000973 ab_set_B_marker(state->id3->elapsed);
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000974 ab_jump_to_A_marker();
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000975 }
976 else
977#endif
978 {
Thomas Martitz23489be2009-04-04 20:33:38 +0000979 change_dir(1);
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000980 }
981 break;
Jonathan Gordon5e5bfab2006-08-16 13:25:45 +0000982 case ACTION_WPS_ABSETA_PREVDIR:
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000983 if (global_settings.party_mode)
984 break;
Jonathan Gordon5e5bfab2006-08-16 13:25:45 +0000985#if defined(AB_REPEAT_ENABLE)
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000986 if (ab_repeat_mode_enabled())
Jonathan Gordon9928e342010-09-14 11:56:50 +0000987 ab_set_A_marker(state->id3->elapsed);
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000988 else
989#endif
990 {
Thomas Martitz23489be2009-04-04 20:33:38 +0000991 change_dir(-1);
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000992 }
993 break;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000994 /* menu key functions */
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +0000995 case ACTION_WPS_MENU:
Thomas Martitzce6b1162009-03-19 23:04:39 +0000996 gwps_leave_wps();
Jonathan Gordon91cb68a2007-03-01 11:14:46 +0000997 return GO_TO_ROOT;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000998 break;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +0000999
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001000
Zakk Roberts2f943b02006-04-10 03:51:17 +00001001#ifdef HAVE_QUICKSCREEN
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +00001002 case ACTION_WPS_QUICKSCREEN:
Jonathan Gordon92961262009-01-02 01:29:13 +00001003 {
Thomas Martitz68099092009-03-17 01:39:20 +00001004 gwps_leave_wps();
Kevin Ferraref57d0222005-11-22 21:55:05 +00001005 if (quick_screen_quick(button))
Teruaki Kawashima5b2a5992009-08-29 16:25:04 +00001006 return GO_TO_ROOT;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001007 restore = true;
Jonathan Gordon92961262009-01-02 01:29:13 +00001008 }
1009 break;
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +00001010#endif /* HAVE_QUICKSCREEN */
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001011
1012 /* screen settings */
1013#ifdef BUTTON_F3
Jonathan Gordoncbcc9db2006-08-22 08:23:24 +00001014 case ACTION_F3:
Jonathan Gordon92961262009-01-02 01:29:13 +00001015 {
Thomas Martitz68099092009-03-17 01:39:20 +00001016 gwps_leave_wps();
Jonathan Gordoncbcc9db2006-08-22 08:23:24 +00001017 if (quick_screen_f3(BUTTON_F3))
Teruaki Kawashima5b2a5992009-08-29 16:25:04 +00001018 return GO_TO_ROOT;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001019 restore = true;
Jonathan Gordon92961262009-01-02 01:29:13 +00001020 }
1021 break;
Jonathan Gordon5e5bfab2006-08-16 13:25:45 +00001022#endif /* BUTTON_F3 */
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001023
1024 /* pitch screen */
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +00001025#ifdef HAVE_PITCHSCREEN
1026 case ACTION_WPS_PITCHSCREEN:
Jonathan Gordon92961262009-01-02 01:29:13 +00001027 {
Thomas Martitz68099092009-03-17 01:39:20 +00001028 gwps_leave_wps();
Jonathan Gordon1da2f012008-10-05 13:01:54 +00001029 if (1 == gui_syncpitchscreen_run())
Teruaki Kawashima5b2a5992009-08-29 16:25:04 +00001030 return GO_TO_ROOT;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001031 restore = true;
Jonathan Gordon92961262009-01-02 01:29:13 +00001032 }
1033 break;
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +00001034#endif /* HAVE_PITCHSCREEN */
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001035
1036#ifdef AB_REPEAT_ENABLE
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001037 /* reset A&B markers */
Marcoen Hirschberg5d2b1e32007-04-13 15:42:25 +00001038 case ACTION_WPS_ABRESET:
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001039 if (ab_repeat_mode_enabled())
1040 {
1041 ab_reset_markers();
Thomas Martitz1d52b722009-04-08 17:11:50 +00001042 update = true;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001043 }
1044 break;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001045#endif /* AB_REPEAT_ENABLE */
1046
1047 /* stop and exit wps */
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +00001048 case ACTION_WPS_STOP:
Björn Stenbergfc390af2006-03-19 08:40:31 +00001049 if (global_settings.party_mode)
1050 break;
Magnus Holmgrena50c2b12007-08-22 16:33:34 +00001051 bookmark = true;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001052 exit = true;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001053 break;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001054
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +00001055 case ACTION_WPS_ID3SCREEN:
Jonathan Gordon92961262009-01-02 01:29:13 +00001056 {
Thomas Martitz68099092009-03-17 01:39:20 +00001057 gwps_leave_wps();
Teruaki Kawashima5b2a5992009-08-29 16:25:04 +00001058 if (browse_id3())
1059 return GO_TO_ROOT;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001060 restore = true;
Jonathan Gordon92961262009-01-02 01:29:13 +00001061 }
1062 break;
Thomas Martitz989ed2b2009-07-10 11:53:15 +00001063 /* this case is used by the softlock feature
1064 * it requests a full update here */
1065 case ACTION_REDRAW:
Jonathan Gordon9928e342010-09-14 11:56:50 +00001066 skin_request_full_update(WPS);
Marianne Arnold49c9ab82009-06-18 13:50:11 +00001067 break;
1068 case ACTION_NONE: /* Timeout, do a partial update */
Thomas Martitz1d52b722009-04-08 17:11:50 +00001069 update = true;
Linus Nielsen Feltzing224c0a12006-08-15 12:27:07 +00001070 ffwd_rew(button); /* hopefully fix the ffw/rwd bug */
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001071 break;
Jonathan Gordon73336e92007-08-02 12:13:20 +00001072#ifdef HAVE_RECORDING
1073 case ACTION_WPS_REC:
1074 exit = true;
1075 break;
1076#endif
Thomas Martitz5c9fe522009-07-22 22:10:25 +00001077 case ACTION_WPS_VIEW_PLAYLIST:
1078 gwps_leave_wps();
Thomas Martitzc19e5362010-02-20 19:06:39 +00001079 return GO_TO_PLAYLIST_VIEWER;
Thomas Martitz5c9fe522009-07-22 22:10:25 +00001080 break;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001081 default:
Thomas Martitz49f1ec82010-10-31 15:32:57 +00001082 switch(default_event_handler(button))
1083 { /* music has been stopped by the default handler */
1084 case SYS_USB_CONNECTED:
1085 case SYS_CALL_INCOMING:
1086 case BUTTON_MULTIMEDIA_STOP:
1087 gwps_leave_wps();
1088 return GO_TO_ROOT;
Teruaki Kawashima5b2a5992009-08-29 16:25:04 +00001089 }
Thomas Martitz1d52b722009-04-08 17:11:50 +00001090 update = true;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001091 break;
1092 }
1093
Thomas Martitz28aef1f2009-10-31 14:55:13 +00001094 if (vol_changed)
1095 {
Thomas Martitz28aef1f2009-10-31 14:55:13 +00001096 bool res = false;
Teruaki Kawashima139694c2009-11-04 12:46:31 +00001097 vol_changed = false;
Thomas Martitz28aef1f2009-10-31 14:55:13 +00001098 setvol();
1099 FOR_NB_SCREENS(i)
1100 {
Jonathan Gordon9928e342010-09-14 11:56:50 +00001101 if(update_onvol_change(i))
Thomas Martitz28aef1f2009-10-31 14:55:13 +00001102 res = true;
1103 }
1104 if (res) {
1105 restore = true;
1106 restoretimer = RESTORE_WPS_NEXT_SECOND;
1107 }
1108 }
1109
Thomas Martitzcc697a82009-11-16 01:38:33 +00001110
Thomas Martitz19ec4ff2009-11-16 01:38:36 +00001111 if (restore &&
Thomas Martitzcc697a82009-11-16 01:38:33 +00001112 ((restoretimer == RESTORE_WPS_INSTANTLY) ||
1113 TIME_AFTER(current_tick, restoretimer)))
1114 {
1115 restore = false;
1116 restoretimer = RESTORE_WPS_INSTANTLY;
1117#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
1118 add_event(LCD_EVENT_ACTIVATION, false, wps_lcd_activation_hook);
1119#endif
1120 /* we remove the update delay since it's not very usable in the wps,
1121 * e.g. during volume changing or ffwd/rewind */
1122 sb_skin_set_update_delay(0);
Jonathan Gordon9928e342010-09-14 11:56:50 +00001123 skin_request_full_update(WPS);
1124 update = true;
Jonathan Gordonb2eb44c2009-12-09 07:25:46 +00001125 gwps_enter_wps();
Thomas Martitzcc697a82009-11-16 01:38:33 +00001126 }
Jonathan Gordon9928e342010-09-14 11:56:50 +00001127 else
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001128 {
Thomas Martitzec7a0c52009-04-14 22:13:29 +00001129#if defined(HAVE_BACKLIGHT) || defined(HAVE_REMOTE_LCD)
Jonathan Gordon9928e342010-09-14 11:56:50 +00001130 gwps_caption_backlight(state);
Thomas Martitzec7a0c52009-04-14 22:13:29 +00001131#endif
Daniel Stenberg09fce702005-11-18 09:03:25 +00001132 FOR_NB_SCREENS(i)
Thomas Martitz725733c2009-04-12 00:30:28 +00001133 {
Thomas Martitz7ce12e62009-04-09 08:30:05 +00001134#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
Thomas Martitz7ce12e62009-04-09 08:30:05 +00001135 /* currently, all remotes are readable without backlight
1136 * so still update those */
Thomas Martitzd85c3ec2009-10-20 21:54:59 +00001137 if (lcd_active() || (i != SCREEN_MAIN))
Thomas Martitz7ce12e62009-04-09 08:30:05 +00001138#endif
Thomas Martitz725733c2009-04-12 00:30:28 +00001139 {
Jonathan Gordon9928e342010-09-14 11:56:50 +00001140 bool full_update = skin_do_full_update(WPS, i);
1141 if (update || full_update)
Jonathan Gordon75556fd2010-08-02 14:12:44 +00001142 {
Jonathan Gordon9928e342010-09-14 11:56:50 +00001143 skin_update(WPS, i, full_update ?
Jonathan Gordon75556fd2010-08-02 14:12:44 +00001144 SKIN_REFRESH_ALL : SKIN_REFRESH_NON_STATIC);
Jonathan Gordon9928e342010-09-14 11:56:50 +00001145 }
Thomas Martitz725733c2009-04-12 00:30:28 +00001146 }
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001147 }
Thomas Martitz1d52b722009-04-08 17:11:50 +00001148 update = false;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001149 }
1150
1151 if (exit) {
1152#ifdef HAVE_LCD_CHARCELLS
1153 status_set_record(false);
1154 status_set_audio(false);
1155#endif
Michael Sevakisa2b67032011-06-29 06:37:04 +00001156#if CONFIG_CODEC != SWCODEC
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001157 if (global_settings.fade_on_stop)
Jonathan Gordon4982b872008-06-23 02:45:55 +00001158 fade(false, true);
Michael Sevakisa2b67032011-06-29 06:37:04 +00001159#else
1160 audio_pause();
Michael Sevakis5078d462011-08-23 01:37:59 +00001161 update_non_static();
Michael Sevakisa2b67032011-06-29 06:37:04 +00001162#endif
Magnus Holmgrena50c2b12007-08-22 16:33:34 +00001163 if (bookmark)
Torne Wuff05ace8e2010-03-28 23:27:49 +00001164 bookmark_autobookmark(true);
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001165 audio_stop();
1166#ifdef AB_REPEAT_ENABLE
1167 ab_reset_markers();
1168#endif
Thomas Martitz71471062009-03-19 14:33:22 +00001169 gwps_leave_wps();
Jonathan Gordon73336e92007-08-02 12:13:20 +00001170#ifdef HAVE_RECORDING
1171 if (button == ACTION_WPS_REC)
1172 return GO_TO_RECSCREEN;
1173#endif
Jonathan Gordonfad3ad62007-04-08 02:11:33 +00001174 if (global_settings.browse_current)
1175 return GO_TO_PREVIOUS_BROWSER;
Jonathan Gordon91cb68a2007-03-01 11:14:46 +00001176 return GO_TO_PREVIOUS;
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001177 }
Zakk Roberts87afd0b2006-03-21 07:59:23 +00001178
Jonathan Gordona02702c2009-01-01 05:12:27 +00001179 if (button && !IS_SYSEVENT(button) )
Frank Gevaerts2f8a0082008-11-01 16:14:28 +00001180 storage_spin();
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001181 }
Jonathan Gordon91cb68a2007-03-01 11:14:46 +00001182 return GO_TO_ROOT; /* unreachable - just to reduce compiler warnings */
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001183}
1184
Jonathan Gordon843c7ef2009-04-06 00:39:43 +00001185/* this is called from the playback thread so NO DRAWING! */
1186static void track_changed_callback(void *param)
1187{
Jonathan Gordon9928e342010-09-14 11:56:50 +00001188 struct wps_state *state = skin_get_global_state();
1189 state->id3 = (struct mp3entry*)param;
1190 state->nid3 = audio_next_track();
1191 if (state->id3->cuesheet)
Jonathan Gordon843c7ef2009-04-06 00:39:43 +00001192 {
Jonathan Gordon9928e342010-09-14 11:56:50 +00001193 cue_find_current_track(state->id3->cuesheet, state->id3->elapsed);
Jonathan Gordon843c7ef2009-04-06 00:39:43 +00001194 }
Jonathan Gordon9928e342010-09-14 11:56:50 +00001195 skin_request_full_update(WPS);
Jonathan Gordon843c7ef2009-04-06 00:39:43 +00001196}
1197static void nextid3available_callback(void* param)
1198{
1199 (void)param;
Jonathan Gordon9928e342010-09-14 11:56:50 +00001200 skin_get_global_state()->nid3 = audio_next_track();
1201 skin_request_full_update(WPS);
Jonathan Gordon843c7ef2009-04-06 00:39:43 +00001202}
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001203
Michael Sevakisc537d592011-04-27 03:08:23 +00001204#ifdef AUDIO_FAST_SKIP_PREVIEW
1205/* this is called on the audio_skip caller thread */
1206static void track_skip_callback(void *param)
1207{
1208 struct wps_state *state = skin_get_global_state();
1209 state->id3 = audio_current_track();
1210 state->nid3 = audio_next_track();
1211 skin_request_full_update(WPS);
1212 (void)param;
1213}
1214#endif /* AUDIO_FAST_SKIP_PREVIEW */
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001215
Nils Wallménius20338ca2006-12-13 11:52:21 +00001216static void wps_state_init(void)
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001217{
Jonathan Gordon9928e342010-09-14 11:56:50 +00001218 struct wps_state *state = skin_get_global_state();
1219 state->ff_rewind = false;
1220 state->paused = false;
Thomas Martitz1d52b722009-04-08 17:11:50 +00001221 if(audio_status() & AUDIO_STATUS_PLAY)
1222 {
Jonathan Gordon9928e342010-09-14 11:56:50 +00001223 state->id3 = audio_current_track();
1224 state->nid3 = audio_next_track();
Thomas Martitz1d52b722009-04-08 17:11:50 +00001225 }
1226 else
1227 {
Jonathan Gordon9928e342010-09-14 11:56:50 +00001228 state->id3 = NULL;
1229 state->nid3 = NULL;
Thomas Martitz1d52b722009-04-08 17:11:50 +00001230 }
1231 /* We'll be updating due to restore initialized with true */
Jonathan Gordon9928e342010-09-14 11:56:50 +00001232 skin_request_full_update(WPS);
Jonathan Gordon843c7ef2009-04-06 00:39:43 +00001233 /* add the WPS track event callbacks */
1234 add_event(PLAYBACK_EVENT_TRACK_CHANGE, false, track_changed_callback);
1235 add_event(PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, false, nextid3available_callback);
Michael Sevakiscaf907e2011-05-25 08:35:31 +00001236#if CONFIG_CODEC == SWCODEC
1237 /* Use the same callback as ..._TRACK_CHANGE for when remaining handles have
1238 finished */
1239 add_event(PLAYBACK_EVENT_CUR_TRACK_READY, false, track_changed_callback);
1240#endif
Michael Sevakisc537d592011-04-27 03:08:23 +00001241#ifdef AUDIO_FAST_SKIP_PREVIEW
1242 add_event(PLAYBACK_EVENT_TRACK_SKIP, false, track_skip_callback);
1243#endif
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001244}
Daniel Stenberg09fce702005-11-18 09:03:25 +00001245
Christi Scarboroughf8cc3212005-11-17 20:20:01 +00001246
Thomas Martitzcc054242009-08-03 15:46:21 +00001247#ifdef IPOD_ACCESSORY_PROTOCOL
Thomas Martitz6db726c2009-11-01 13:36:52 +00001248bool is_wps_fading(void)
1249{
Jonathan Gordon9928e342010-09-14 11:56:50 +00001250 return skin_get_global_state()->is_fading;
Thomas Martitz6db726c2009-11-01 13:36:52 +00001251}
1252
Thomas Martitzcc054242009-08-03 15:46:21 +00001253int wps_get_ff_rewind_count(void)
1254{
Jonathan Gordon9928e342010-09-14 11:56:50 +00001255 return skin_get_global_state()->ff_rewind_count;
Thomas Martitzcc054242009-08-03 15:46:21 +00001256}
1257#endif