new skin token: %cx - 24 hour time format enabled in the setting.. e.g %?cx<24 hour...
[kugel-rb.git] / apps / gui / skin_engine / skin_tokens.c
blob6dbceca906d0cba400811677f01114875a94923e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002-2007 Björn Stenberg
11 * Copyright (C) 2007-2008 Nicolas Pennequin
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
22 #include "font.h"
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include "action.h"
27 #include "system.h"
28 #include "settings.h"
29 #include "settings_list.h"
30 #include "rbunicode.h"
31 #include "timefuncs.h"
32 #include "status.h"
33 #include "power.h"
34 #include "powermgmt.h"
35 #include "sound.h"
36 #include "debug.h"
37 #ifdef HAVE_LCD_CHARCELLS
38 #include "hwcompat.h"
39 #endif
40 #include "abrepeat.h"
41 #include "lang.h"
42 #include "misc.h"
43 #include "led.h"
44 #ifdef HAVE_LCD_BITMAP
45 /* Image stuff */
46 #include "albumart.h"
47 #endif
48 #include "dsp.h"
49 #include "playlist.h"
50 #if CONFIG_CODEC == SWCODEC
51 #include "playback.h"
52 #endif
53 #include "viewport.h"
55 #include "wps_internals.h"
56 #include "root_menu.h"
57 #ifdef HAVE_RECORDING
58 #include "recording.h"
59 #endif
61 static char* get_codectype(const struct mp3entry* id3)
63 if (id3 && id3->codectype < AFMT_NUM_CODECS) {
64 return (char*)audio_formats[id3->codectype].label;
65 } else {
66 return NULL;
70 /* Extract a part from a path.
72 * buf - buffer extract part to.
73 * buf_size - size of buffer.
74 * path - path to extract from.
75 * level - what to extract. 0 is file name, 1 is parent of file, 2 is
76 * parent of parent, etc.
78 * Returns buf if the desired level was found, NULL otherwise.
80 static char* get_dir(char* buf, int buf_size, const char* path, int level)
82 const char* sep;
83 const char* last_sep;
84 int len;
86 sep = path + strlen(path);
87 last_sep = sep;
89 while (sep > path)
91 if ('/' == *(--sep))
93 if (!level)
94 break;
96 level--;
97 last_sep = sep - 1;
101 if (level || (last_sep <= sep))
102 return NULL;
104 len = MIN(last_sep - sep, buf_size - 1);
105 strlcpy(buf, sep + 1, len + 1);
106 return buf;
109 /* Return the tag found at index i and write its value in buf.
110 The return value is buf if the tag had a value, or NULL if not.
112 intval is used with conditionals/enums: when this function is called,
113 intval should contain the number of options in the conditional/enum.
114 When this function returns, intval is -1 if the tag is non numeric or,
115 if the tag is numeric, *intval is the enum case we want to go to (between 1
116 and the original value of *intval, inclusive).
117 When not treating a conditional/enum, intval should be NULL.
120 /* a few convinience macros for the id3 == NULL case
121 * depends on a few variable names in get_token_value() */
123 #define HANDLE_NULL_ID3(id3field) (LIKELY(id3) ? (id3field) : NULL)
125 #define HANDLE_NULL_ID3_NUM_ZERO { if (UNLIKELY(!id3)) return zero_str; }
127 #define HANDLE_NULL_ID3_NUM_INTVAL(id3field) \
128 do { \
129 if (intval) { \
130 *intval = (LIKELY(id3) ? (id3field) + 1 : 0); \
132 if (LIKELY(id3)) \
134 snprintf(buf, buf_size, "%ld", (id3field)); \
135 return buf; \
137 return zero_str; \
138 } while (0)
140 const char *get_token_value(struct gui_wps *gwps,
141 struct wps_token *token,
142 char *buf, int buf_size,
143 int *intval)
145 if (!gwps)
146 return NULL;
148 struct wps_data *data = gwps->data;
149 struct wps_state *state = gwps->state;
150 int elapsed, length;
151 static const char * const zero_str = "0";
153 if (!data || !state)
154 return NULL;
156 struct mp3entry *id3;
158 if (token->next)
159 id3 = state->nid3;
160 else
161 id3 = state->id3;
163 if (id3)
165 elapsed = id3->elapsed;
166 length = id3->length;
168 else
170 elapsed = 0;
171 length = 0;
174 #if CONFIG_RTC
175 struct tm* tm = NULL;
177 /* if the token is an RTC one, update the time
178 and do the necessary checks */
179 if (token->type >= WPS_TOKENS_RTC_BEGIN
180 && token->type <= WPS_TOKENS_RTC_END)
182 tm = get_time();
184 if (!valid_time(tm))
185 return NULL;
187 #endif
189 int limit = 1;
190 if (intval)
192 limit = *intval;
193 *intval = -1;
196 switch (token->type)
198 case WPS_TOKEN_CHARACTER:
199 if (token->value.c == '\n')
200 return NULL;
201 return &(token->value.c);
203 case WPS_TOKEN_STRING:
204 return (char*)token->value.data;
206 case WPS_TOKEN_TRANSLATEDSTRING:
207 return (char*)P2STR(ID2P(token->value.i));
209 case WPS_TOKEN_TRACK_TIME_ELAPSED:
210 format_time(buf, buf_size,
211 elapsed + state->ff_rewind_count);
212 return buf;
214 case WPS_TOKEN_TRACK_TIME_REMAINING:
215 format_time(buf, buf_size,
216 length - elapsed -
217 state->ff_rewind_count);
218 return buf;
220 case WPS_TOKEN_TRACK_LENGTH:
221 format_time(buf, buf_size, length);
222 return buf;
224 case WPS_TOKEN_PLAYLIST_ENTRIES:
225 snprintf(buf, buf_size, "%d", playlist_amount());
226 return buf;
228 case WPS_TOKEN_PLAYLIST_NAME:
229 return playlist_name(NULL, buf, buf_size);
231 case WPS_TOKEN_PLAYLIST_POSITION:
232 snprintf(buf, buf_size, "%d", playlist_get_display_index());
233 return buf;
235 case WPS_TOKEN_PLAYLIST_SHUFFLE:
236 if ( global_settings.playlist_shuffle )
237 return "s";
238 else
239 return NULL;
240 break;
242 case WPS_TOKEN_VOLUME:
243 snprintf(buf, buf_size, "%d", global_settings.volume);
244 if (intval)
246 if (global_settings.volume == sound_min(SOUND_VOLUME))
248 *intval = 1;
250 else if (global_settings.volume == 0)
252 *intval = limit - 1;
254 else if (global_settings.volume > 0)
256 *intval = limit;
258 else
260 *intval = (limit - 3) * (global_settings.volume
261 - sound_min(SOUND_VOLUME) - 1)
262 / (-1 - sound_min(SOUND_VOLUME)) + 2;
265 return buf;
267 case WPS_TOKEN_TRACK_ELAPSED_PERCENT:
268 if (length <= 0)
269 return NULL;
271 if (intval)
273 *intval = limit * (elapsed + state->ff_rewind_count)
274 / length + 1;
276 snprintf(buf, buf_size, "%d",
277 100*(elapsed + state->ff_rewind_count) / length);
278 return buf;
280 case WPS_TOKEN_METADATA_ARTIST:
281 return HANDLE_NULL_ID3(id3->artist);
283 case WPS_TOKEN_METADATA_COMPOSER:
284 return HANDLE_NULL_ID3(id3->composer);
286 case WPS_TOKEN_METADATA_ALBUM:
287 return HANDLE_NULL_ID3(id3->album);
289 case WPS_TOKEN_METADATA_ALBUM_ARTIST:
290 return HANDLE_NULL_ID3(id3->albumartist);
292 case WPS_TOKEN_METADATA_GROUPING:
293 return HANDLE_NULL_ID3(id3->grouping);
295 case WPS_TOKEN_METADATA_GENRE:
296 return HANDLE_NULL_ID3(id3->genre_string);
298 case WPS_TOKEN_METADATA_DISC_NUMBER:
299 if (LIKELY(id3)) {
300 if (id3->disc_string)
301 return id3->disc_string;
302 if (id3->discnum) {
303 snprintf(buf, buf_size, "%d", id3->discnum);
304 return buf;
307 return NULL;
309 case WPS_TOKEN_METADATA_TRACK_NUMBER:
310 if (LIKELY(id3)) {
311 if (id3->track_string)
312 return id3->track_string;
314 if (id3->tracknum) {
315 snprintf(buf, buf_size, "%d", id3->tracknum);
316 return buf;
319 return NULL;
321 case WPS_TOKEN_METADATA_TRACK_TITLE:
322 return HANDLE_NULL_ID3(id3->title);
324 case WPS_TOKEN_METADATA_VERSION:
325 if (LIKELY(id3))
327 switch (id3->id3version)
329 case ID3_VER_1_0:
330 return "1";
332 case ID3_VER_1_1:
333 return "1.1";
335 case ID3_VER_2_2:
336 return "2.2";
338 case ID3_VER_2_3:
339 return "2.3";
341 case ID3_VER_2_4:
342 return "2.4";
344 default:
345 break;
348 return NULL;
350 case WPS_TOKEN_METADATA_YEAR:
351 if (LIKELY(id3)) {
352 if( id3->year_string )
353 return id3->year_string;
355 if (id3->year) {
356 snprintf(buf, buf_size, "%d", id3->year);
357 return buf;
360 return NULL;
362 case WPS_TOKEN_METADATA_COMMENT:
363 return HANDLE_NULL_ID3(id3->comment);
365 #ifdef HAVE_ALBUMART
366 case WPS_TOKEN_ALBUMART_FOUND:
367 if (data->albumart) {
368 if (playback_current_aa_hid(data->playback_aa_slot) >= 0)
369 return "C";
371 return NULL;
373 case WPS_TOKEN_ALBUMART_DISPLAY:
374 if (!data->albumart)
375 return NULL;
376 if (!data->albumart->draw)
377 data->albumart->draw = true;
378 return NULL;
379 #endif
381 case WPS_TOKEN_FILE_BITRATE:
382 if(id3 && id3->bitrate)
383 snprintf(buf, buf_size, "%d", id3->bitrate);
384 else
385 return "?";
386 return buf;
388 case WPS_TOKEN_FILE_CODEC:
389 if (intval)
391 if (UNLIKELY(!id3))
392 *intval = 0;
393 else if(id3->codectype == AFMT_UNKNOWN)
394 *intval = AFMT_NUM_CODECS;
395 else
396 *intval = id3->codectype;
398 return get_codectype(id3);
400 case WPS_TOKEN_FILE_FREQUENCY:
401 HANDLE_NULL_ID3_NUM_ZERO;
402 snprintf(buf, buf_size, "%ld", id3->frequency);
403 return buf;
405 case WPS_TOKEN_FILE_FREQUENCY_KHZ:
406 HANDLE_NULL_ID3_NUM_ZERO;
407 /* ignore remainders < 100, so 22050 Hz becomes just 22k */
408 if ((id3->frequency % 1000) < 100)
409 snprintf(buf, buf_size, "%ld", id3->frequency / 1000);
410 else
411 snprintf(buf, buf_size, "%ld.%d",
412 id3->frequency / 1000,
413 (id3->frequency % 1000) / 100);
414 return buf;
416 case WPS_TOKEN_FILE_NAME:
417 if (LIKELY(id3) && get_dir(buf, buf_size, id3->path, 0)) {
418 /* Remove extension */
419 char* sep = strrchr(buf, '.');
420 if (NULL != sep) {
421 *sep = 0;
423 return buf;
425 else {
426 return NULL;
429 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION:
430 if (LIKELY(id3))
431 return get_dir(buf, buf_size, id3->path, 0);
432 return NULL;
434 case WPS_TOKEN_FILE_PATH:
435 return HANDLE_NULL_ID3(id3->path);
437 case WPS_TOKEN_FILE_SIZE:
438 HANDLE_NULL_ID3_NUM_ZERO;
439 snprintf(buf, buf_size, "%ld", id3->filesize / 1024);
440 return buf;
442 case WPS_TOKEN_FILE_VBR:
443 return (LIKELY(id3) && id3->vbr) ? "(avg)" : NULL;
445 case WPS_TOKEN_FILE_DIRECTORY:
446 if (LIKELY(id3))
447 return get_dir(buf, buf_size, id3->path, token->value.i);
448 return NULL;
450 case WPS_TOKEN_BATTERY_PERCENT:
452 int l = battery_level();
454 if (intval)
456 limit = MAX(limit, 2);
457 if (l > -1) {
458 /* First enum is used for "unknown level". */
459 *intval = (limit - 1) * l / 100 + 2;
460 } else {
461 *intval = 1;
465 if (l > -1) {
466 snprintf(buf, buf_size, "%d", l);
467 return buf;
468 } else {
469 return "?";
473 case WPS_TOKEN_BATTERY_VOLTS:
475 unsigned int v = battery_voltage();
476 snprintf(buf, buf_size, "%d.%02d", v / 1000, (v % 1000) / 10);
477 return buf;
480 case WPS_TOKEN_BATTERY_TIME:
482 int t = battery_time();
483 if (t >= 0)
484 snprintf(buf, buf_size, "%dh %dm", t / 60, t % 60);
485 else
486 return "?h ?m";
487 return buf;
490 #if CONFIG_CHARGING
491 case WPS_TOKEN_BATTERY_CHARGER_CONNECTED:
493 if(charger_input_state==CHARGER)
494 return "p";
495 else
496 return NULL;
498 #endif
499 #if CONFIG_CHARGING >= CHARGING_MONITOR
500 case WPS_TOKEN_BATTERY_CHARGING:
502 if (charge_state == CHARGING || charge_state == TOPOFF) {
503 return "c";
504 } else {
505 return NULL;
508 #endif
509 case WPS_TOKEN_BATTERY_SLEEPTIME:
511 if (get_sleep_timer() == 0)
512 return NULL;
513 else
515 format_time(buf, buf_size, get_sleep_timer() * 1000);
516 return buf;
520 case WPS_TOKEN_PLAYBACK_STATUS:
522 int status = current_playmode();
523 /* music */
524 int mode = 1; /* stop */
525 if (status == STATUS_PLAY)
526 mode = 2; /* play */
527 if (state->is_fading ||
528 (status == STATUS_PAUSE && !status_get_ffmode()))
529 mode = 3; /* pause */
530 else
531 { /* ff / rwd */
532 if (status_get_ffmode() == STATUS_FASTFORWARD)
533 mode = 4;
534 if (status_get_ffmode() == STATUS_FASTBACKWARD)
535 mode = 5;
537 #ifdef HAVE_RECORDING
538 /* recording */
539 if (status == STATUS_RECORD)
540 mode = 6;
541 else if (status == STATUS_RECORD_PAUSE)
542 mode = 7;
543 #endif
544 #if CONFIG_TUNER
545 /* radio */
546 if (status == STATUS_RADIO)
547 mode = 8;
548 else if (status == STATUS_RADIO_PAUSE)
549 mode = 9;
550 #endif
552 if (intval) {
553 *intval = mode;
556 snprintf(buf, buf_size, "%d", mode-1);
557 return buf;
560 case WPS_TOKEN_REPEAT_MODE:
561 if (intval)
562 *intval = global_settings.repeat_mode + 1;
563 snprintf(buf, buf_size, "%d", global_settings.repeat_mode);
564 return buf;
566 case WPS_TOKEN_RTC_PRESENT:
567 #if CONFIG_RTC
568 return "c";
569 #else
570 return NULL;
571 #endif
572 case WPS_TOKEN_RTC_24HR_SETTING_MODE:
573 #if CONFIG_RTC
574 return global_settings.timeformat?NULL:"z";
575 #else
576 return NULL;
577 #endif
579 #if CONFIG_RTC
580 case WPS_TOKEN_RTC_12HOUR_CFG:
581 if (intval)
582 *intval = global_settings.timeformat + 1;
583 snprintf(buf, buf_size, "%d", global_settings.timeformat);
584 return buf;
586 case WPS_TOKEN_RTC_DAY_OF_MONTH:
587 /* d: day of month (01..31) */
588 snprintf(buf, buf_size, "%02d", tm->tm_mday);
589 return buf;
591 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED:
592 /* e: day of month, blank padded ( 1..31) */
593 snprintf(buf, buf_size, "%2d", tm->tm_mday);
594 return buf;
596 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED:
597 /* H: hour (00..23) */
598 snprintf(buf, buf_size, "%02d", tm->tm_hour);
599 return buf;
601 case WPS_TOKEN_RTC_HOUR_24:
602 /* k: hour ( 0..23) */
603 snprintf(buf, buf_size, "%2d", tm->tm_hour);
604 return buf;
606 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED:
607 /* I: hour (01..12) */
608 snprintf(buf, buf_size, "%02d",
609 (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12);
610 return buf;
612 case WPS_TOKEN_RTC_HOUR_12:
613 /* l: hour ( 1..12) */
614 snprintf(buf, buf_size, "%2d",
615 (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12);
616 return buf;
618 case WPS_TOKEN_RTC_MONTH:
619 /* m: month (01..12) */
620 if (intval)
621 *intval = tm->tm_mon + 1;
622 snprintf(buf, buf_size, "%02d", tm->tm_mon + 1);
623 return buf;
625 case WPS_TOKEN_RTC_MINUTE:
626 /* M: minute (00..59) */
627 snprintf(buf, buf_size, "%02d", tm->tm_min);
628 return buf;
630 case WPS_TOKEN_RTC_SECOND:
631 /* S: second (00..59) */
632 snprintf(buf, buf_size, "%02d", tm->tm_sec);
633 return buf;
635 case WPS_TOKEN_RTC_YEAR_2_DIGITS:
636 /* y: last two digits of year (00..99) */
637 snprintf(buf, buf_size, "%02d", tm->tm_year % 100);
638 return buf;
640 case WPS_TOKEN_RTC_YEAR_4_DIGITS:
641 /* Y: year (1970...) */
642 snprintf(buf, buf_size, "%04d", tm->tm_year + 1900);
643 return buf;
645 case WPS_TOKEN_RTC_AM_PM_UPPER:
646 /* p: upper case AM or PM indicator */
647 return tm->tm_hour/12 == 0 ? "AM" : "PM";
649 case WPS_TOKEN_RTC_AM_PM_LOWER:
650 /* P: lower case am or pm indicator */
651 return tm->tm_hour/12 == 0 ? "am" : "pm";
653 case WPS_TOKEN_RTC_WEEKDAY_NAME:
654 /* a: abbreviated weekday name (Sun..Sat) */
655 return str(LANG_WEEKDAY_SUNDAY + tm->tm_wday);
657 case WPS_TOKEN_RTC_MONTH_NAME:
658 /* b: abbreviated month name (Jan..Dec) */
659 return str(LANG_MONTH_JANUARY + tm->tm_mon);
661 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON:
662 /* u: day of week (1..7); 1 is Monday */
663 if (intval)
664 *intval = (tm->tm_wday == 0) ? 7 : tm->tm_wday;
665 snprintf(buf, buf_size, "%1d", tm->tm_wday + 1);
666 return buf;
668 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN:
669 /* w: day of week (0..6); 0 is Sunday */
670 if (intval)
671 *intval = tm->tm_wday + 1;
672 snprintf(buf, buf_size, "%1d", tm->tm_wday);
673 return buf;
674 #else
675 case WPS_TOKEN_RTC_DAY_OF_MONTH:
676 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED:
677 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED:
678 case WPS_TOKEN_RTC_HOUR_24:
679 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED:
680 case WPS_TOKEN_RTC_HOUR_12:
681 case WPS_TOKEN_RTC_MONTH:
682 case WPS_TOKEN_RTC_MINUTE:
683 case WPS_TOKEN_RTC_SECOND:
684 case WPS_TOKEN_RTC_AM_PM_UPPER:
685 case WPS_TOKEN_RTC_AM_PM_LOWER:
686 case WPS_TOKEN_RTC_YEAR_2_DIGITS:
687 return "--";
688 case WPS_TOKEN_RTC_YEAR_4_DIGITS:
689 return "----";
690 case WPS_TOKEN_RTC_WEEKDAY_NAME:
691 case WPS_TOKEN_RTC_MONTH_NAME:
692 return "---";
693 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON:
694 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN:
695 return "-";
696 #endif
698 #ifdef HAVE_LCD_CHARCELLS
699 case WPS_TOKEN_PROGRESSBAR:
701 char *end = utf8encode(data->wps_progress_pat[0], buf);
702 *end = '\0';
703 return buf;
706 case WPS_TOKEN_PLAYER_PROGRESSBAR:
707 if(is_new_player())
709 /* we need 11 characters (full line) for
710 progress-bar */
711 strlcpy(buf, " ", buf_size);
713 else
715 /* Tell the user if we have an OldPlayer */
716 strlcpy(buf, " <Old LCD> ", buf_size);
718 return buf;
719 #endif
722 #ifdef HAVE_TAGCACHE
723 case WPS_TOKEN_DATABASE_PLAYCOUNT:
724 HANDLE_NULL_ID3_NUM_INTVAL(id3->playcount);
726 case WPS_TOKEN_DATABASE_RATING:
727 HANDLE_NULL_ID3_NUM_INTVAL(id3->rating);
729 case WPS_TOKEN_DATABASE_AUTOSCORE:
730 HANDLE_NULL_ID3_NUM_INTVAL(id3->score);
731 #endif
733 #if (CONFIG_CODEC == SWCODEC)
734 case WPS_TOKEN_CROSSFADE:
735 if (intval)
736 *intval = global_settings.crossfade + 1;
737 snprintf(buf, buf_size, "%d", global_settings.crossfade);
738 return buf;
740 case WPS_TOKEN_REPLAYGAIN:
742 int val;
744 if (global_settings.replaygain_type == REPLAYGAIN_OFF)
745 val = 1; /* off */
746 else
748 int type;
749 if (LIKELY(id3))
750 type = get_replaygain_mode(id3->track_gain_string != NULL,
751 id3->album_gain_string != NULL);
752 else
753 type = -1;
755 if (type < 0)
756 val = 6; /* no tag */
757 else
758 val = type + 2;
760 if (global_settings.replaygain_type == REPLAYGAIN_SHUFFLE)
761 val += 2;
764 if (intval)
765 *intval = val;
767 switch (val)
769 case 1:
770 case 6:
771 return "+0.00 dB";
772 break;
773 /* due to above, coming here with !id3 shouldn't be possible */
774 case 2:
775 case 4:
776 strlcpy(buf, id3->track_gain_string, buf_size);
777 break;
778 case 3:
779 case 5:
780 strlcpy(buf, id3->album_gain_string, buf_size);
781 break;
783 return buf;
785 #endif /* (CONFIG_CODEC == SWCODEC) */
787 #if (CONFIG_CODEC != MAS3507D)
788 case WPS_TOKEN_SOUND_PITCH:
790 int32_t pitch = sound_get_pitch();
791 snprintf(buf, buf_size, "%ld.%ld",
792 pitch / PITCH_SPEED_PRECISION,
793 (pitch % PITCH_SPEED_PRECISION) / (PITCH_SPEED_PRECISION / 10));
794 return buf;
796 #endif
798 case WPS_TOKEN_MAIN_HOLD:
799 #ifdef HAS_BUTTON_HOLD
800 if (button_hold())
801 #else
802 if (is_keys_locked())
803 #endif /*hold switch or softlock*/
804 return "h";
805 else
806 return NULL;
808 #ifdef HAS_REMOTE_BUTTON_HOLD
809 case WPS_TOKEN_REMOTE_HOLD:
810 if (remote_button_hold())
811 return "r";
812 else
813 return NULL;
814 #endif
816 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
817 case WPS_TOKEN_VLED_HDD:
818 if(led_read(HZ/2))
819 return "h";
820 else
821 return NULL;
822 #endif
823 case WPS_TOKEN_BUTTON_VOLUME:
824 if (global_status.last_volume_change &&
825 TIME_BEFORE(current_tick, global_status.last_volume_change +
826 token->value.i * TIMEOUT_UNIT))
827 return "v";
828 return NULL;
829 case WPS_TOKEN_LASTTOUCH:
830 #ifdef HAVE_TOUCHSCREEN
831 if (TIME_BEFORE(current_tick, token->value.i * TIMEOUT_UNIT +
832 touchscreen_last_touch()))
833 return "t";
834 #endif
835 return NULL;
837 case WPS_TOKEN_SETTING:
839 if (intval)
841 /* Handle contionals */
842 const struct settings_list *s = settings+token->value.i;
843 switch (s->flags&F_T_MASK)
845 case F_T_INT:
846 case F_T_UINT:
847 if (s->flags&F_RGB)
848 /* %?St|name|<#000000|#000001|...|#FFFFFF> */
849 /* shouldn't overflow since colors are stored
850 * on 16 bits ...
851 * but this is pretty useless anyway */
852 *intval = *(int*)s->setting + 1;
853 else if (s->cfg_vals == NULL)
854 /* %?St|name|<1st choice|2nd choice|...> */
855 *intval = (*(int*)s->setting-s->int_setting->min)
856 /s->int_setting->step + 1;
857 else
858 /* %?St|name|<1st choice|2nd choice|...> */
859 /* Not sure about this one. cfg_name/vals are
860 * indexed from 0 right? */
861 *intval = *(int*)s->setting + 1;
862 break;
863 case F_T_BOOL:
864 /* %?St|name|<if true|if false> */
865 *intval = *(bool*)s->setting?1:2;
866 break;
867 case F_T_CHARPTR:
868 /* %?St|name|<if non empty string|if empty>
869 * The string's emptyness discards the setting's
870 * prefix and suffix */
871 *intval = ((char*)s->setting)[0]?1:2;
872 break;
873 default:
874 /* This shouldn't happen ... but you never know */
875 *intval = -1;
876 break;
879 cfg_to_string(token->value.i,buf,buf_size);
880 return buf;
882 case WPS_TOKEN_CURRENT_SCREEN:
884 int curr_screen = current_screen();
886 #ifdef HAVE_RECORDING
887 /* override current_screen() for recording screen since it may
888 * be entered from the radio screen */
889 if (in_recording_screen())
890 curr_screen = GO_TO_RECSCREEN;
891 #endif
893 switch (curr_screen)
895 case GO_TO_WPS:
896 curr_screen = 2;
897 break;
898 #ifdef HAVE_RECORDING
899 case GO_TO_RECSCREEN:
900 curr_screen = 3;
901 break;
902 #endif
903 #if CONFIG_TUNER
904 case GO_TO_FM:
905 curr_screen = 4;
906 break;
907 #endif
908 default: /* lists */
909 curr_screen = 1;
910 break;
912 if (intval)
915 *intval = curr_screen;
917 snprintf(buf, buf_size, "%d", curr_screen);
918 return buf;
921 default:
922 return NULL;