redraw the AA much less frequently to save bettery life and also let skins draw over...
[kugel-rb.git] / apps / gui / skin_engine / skin_tokens.c
blobe0d4595122a2a1d24ad811cb14af863178e4456a
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 "audio.h"
33 #include "status.h"
34 #include "power.h"
35 #include "powermgmt.h"
36 #include "sound.h"
37 #include "debug.h"
38 #ifdef HAVE_LCD_CHARCELLS
39 #include "hwcompat.h"
40 #endif
41 #include "abrepeat.h"
42 #include "mp3_playback.h"
43 #include "lang.h"
44 #include "misc.h"
45 #include "led.h"
46 #ifdef HAVE_LCD_BITMAP
47 /* Image stuff */
48 #include "albumart.h"
49 #endif
50 #include "dsp.h"
51 #include "playlist.h"
52 #if CONFIG_CODEC == SWCODEC
53 #include "playback.h"
54 #endif
55 #include "viewport.h"
57 #include "wps_internals.h"
58 #include "wps.h"
60 static char* get_codectype(const struct mp3entry* id3)
62 if (id3->codectype < AFMT_NUM_CODECS) {
63 return (char*)audio_formats[id3->codectype].label;
64 } else {
65 return NULL;
69 /* Extract a part from a path.
71 * buf - buffer extract part to.
72 * buf_size - size of buffer.
73 * path - path to extract from.
74 * level - what to extract. 0 is file name, 1 is parent of file, 2 is
75 * parent of parent, etc.
77 * Returns buf if the desired level was found, NULL otherwise.
79 static char* get_dir(char* buf, int buf_size, const char* path, int level)
81 const char* sep;
82 const char* last_sep;
83 int len;
85 sep = path + strlen(path);
86 last_sep = sep;
88 while (sep > path)
90 if ('/' == *(--sep))
92 if (!level)
93 break;
95 level--;
96 last_sep = sep - 1;
100 if (level || (last_sep <= sep))
101 return NULL;
103 len = MIN(last_sep - sep, buf_size - 1);
104 strlcpy(buf, sep + 1, len + 1);
105 return buf;
108 /* Return the tag found at index i and write its value in buf.
109 The return value is buf if the tag had a value, or NULL if not.
111 intval is used with conditionals/enums: when this function is called,
112 intval should contain the number of options in the conditional/enum.
113 When this function returns, intval is -1 if the tag is non numeric or,
114 if the tag is numeric, *intval is the enum case we want to go to (between 1
115 and the original value of *intval, inclusive).
116 When not treating a conditional/enum, intval should be NULL.
118 const char *get_token_value(struct gui_wps *gwps,
119 struct wps_token *token,
120 char *buf, int buf_size,
121 int *intval)
123 if (!gwps)
124 return NULL;
126 struct wps_data *data = gwps->data;
127 struct wps_state *state = gwps->state;
129 if (!data || !state)
130 return NULL;
132 struct mp3entry *id3;
134 if (token->next)
135 id3 = state->nid3;
136 else
137 id3 = state->id3;
139 if (!id3)
140 return NULL;
142 #if CONFIG_RTC
143 struct tm* tm = NULL;
145 /* if the token is an RTC one, update the time
146 and do the necessary checks */
147 if (token->type >= WPS_TOKENS_RTC_BEGIN
148 && token->type <= WPS_TOKENS_RTC_END)
150 tm = get_time();
152 if (!valid_time(tm))
153 return NULL;
155 #endif
157 int limit = 1;
158 if (intval)
160 limit = *intval;
161 *intval = -1;
164 switch (token->type)
166 case WPS_TOKEN_CHARACTER:
167 if (token->value.c == '\n')
168 return NULL;
169 return &(token->value.c);
171 case WPS_TOKEN_STRING:
172 return (char*)token->value.data;
174 case WPS_TOKEN_TRANSLATEDSTRING:
175 return (char*)P2STR(ID2P(token->value.i));
177 case WPS_TOKEN_TRACK_TIME_ELAPSED:
178 format_time(buf, buf_size,
179 id3->elapsed + state->ff_rewind_count);
180 return buf;
182 case WPS_TOKEN_TRACK_TIME_REMAINING:
183 format_time(buf, buf_size,
184 id3->length - id3->elapsed -
185 state->ff_rewind_count);
186 return buf;
188 case WPS_TOKEN_TRACK_LENGTH:
189 format_time(buf, buf_size, id3->length);
190 return buf;
192 case WPS_TOKEN_PLAYLIST_ENTRIES:
193 snprintf(buf, buf_size, "%d", playlist_amount());
194 return buf;
196 case WPS_TOKEN_PLAYLIST_NAME:
197 return playlist_name(NULL, buf, buf_size);
199 case WPS_TOKEN_PLAYLIST_POSITION:
200 snprintf(buf, buf_size, "%d", playlist_get_display_index());
201 return buf;
203 case WPS_TOKEN_PLAYLIST_SHUFFLE:
204 if ( global_settings.playlist_shuffle )
205 return "s";
206 else
207 return NULL;
208 break;
210 case WPS_TOKEN_VOLUME:
211 snprintf(buf, buf_size, "%d", global_settings.volume);
212 if (intval)
214 if (global_settings.volume == sound_min(SOUND_VOLUME))
216 *intval = 1;
218 else if (global_settings.volume == 0)
220 *intval = limit - 1;
222 else if (global_settings.volume > 0)
224 *intval = limit;
226 else
228 *intval = (limit - 3) * (global_settings.volume
229 - sound_min(SOUND_VOLUME) - 1)
230 / (-1 - sound_min(SOUND_VOLUME)) + 2;
233 return buf;
235 case WPS_TOKEN_TRACK_ELAPSED_PERCENT:
236 if (id3->length <= 0)
237 return NULL;
239 if (intval)
241 *intval = limit * (id3->elapsed + state->ff_rewind_count)
242 / id3->length + 1;
244 snprintf(buf, buf_size, "%d",
245 100*(id3->elapsed + state->ff_rewind_count) / id3->length);
246 return buf;
248 case WPS_TOKEN_METADATA_ARTIST:
249 return id3->artist;
251 case WPS_TOKEN_METADATA_COMPOSER:
252 return id3->composer;
254 case WPS_TOKEN_METADATA_ALBUM:
255 return id3->album;
257 case WPS_TOKEN_METADATA_ALBUM_ARTIST:
258 return id3->albumartist;
260 case WPS_TOKEN_METADATA_GROUPING:
261 return id3->grouping;
263 case WPS_TOKEN_METADATA_GENRE:
264 return id3->genre_string;
266 case WPS_TOKEN_METADATA_DISC_NUMBER:
267 if (id3->disc_string)
268 return id3->disc_string;
269 if (id3->discnum) {
270 snprintf(buf, buf_size, "%d", id3->discnum);
271 return buf;
273 return NULL;
275 case WPS_TOKEN_METADATA_TRACK_NUMBER:
276 if (id3->track_string)
277 return id3->track_string;
279 if (id3->tracknum) {
280 snprintf(buf, buf_size, "%d", id3->tracknum);
281 return buf;
283 return NULL;
285 case WPS_TOKEN_METADATA_TRACK_TITLE:
286 return id3->title;
288 case WPS_TOKEN_METADATA_VERSION:
289 switch (id3->id3version)
291 case ID3_VER_1_0:
292 return "1";
294 case ID3_VER_1_1:
295 return "1.1";
297 case ID3_VER_2_2:
298 return "2.2";
300 case ID3_VER_2_3:
301 return "2.3";
303 case ID3_VER_2_4:
304 return "2.4";
306 default:
307 return NULL;
310 case WPS_TOKEN_METADATA_YEAR:
311 if( id3->year_string )
312 return id3->year_string;
314 if (id3->year) {
315 snprintf(buf, buf_size, "%d", id3->year);
316 return buf;
318 return NULL;
320 case WPS_TOKEN_METADATA_COMMENT:
321 return id3->comment;
323 #ifdef HAVE_ALBUMART
324 case WPS_TOKEN_ALBUMART_FOUND:
325 if (data->albumart && audio_current_aa_hid() >= 0) {
326 return "C";
328 return NULL;
330 case WPS_TOKEN_ALBUMART_DISPLAY:
331 if (!data->albumart)
332 return NULL;
333 if (!data->albumart->draw)
334 data->albumart->draw = true;
335 return NULL;
336 #endif
338 case WPS_TOKEN_FILE_BITRATE:
339 if(id3->bitrate)
340 snprintf(buf, buf_size, "%d", id3->bitrate);
341 else
342 return "?";
343 return buf;
345 case WPS_TOKEN_FILE_CODEC:
346 if (intval)
348 if(id3->codectype == AFMT_UNKNOWN)
349 *intval = AFMT_NUM_CODECS;
350 else
351 *intval = id3->codectype;
353 return get_codectype(id3);
355 case WPS_TOKEN_FILE_FREQUENCY:
356 snprintf(buf, buf_size, "%ld", id3->frequency);
357 return buf;
359 case WPS_TOKEN_FILE_FREQUENCY_KHZ:
360 /* ignore remainders < 100, so 22050 Hz becomes just 22k */
361 if ((id3->frequency % 1000) < 100)
362 snprintf(buf, buf_size, "%ld", id3->frequency / 1000);
363 else
364 snprintf(buf, buf_size, "%ld.%d",
365 id3->frequency / 1000,
366 (id3->frequency % 1000) / 100);
367 return buf;
369 case WPS_TOKEN_FILE_NAME:
370 if (get_dir(buf, buf_size, id3->path, 0)) {
371 /* Remove extension */
372 char* sep = strrchr(buf, '.');
373 if (NULL != sep) {
374 *sep = 0;
376 return buf;
378 else {
379 return NULL;
382 case WPS_TOKEN_FILE_NAME_WITH_EXTENSION:
383 return get_dir(buf, buf_size, id3->path, 0);
385 case WPS_TOKEN_FILE_PATH:
386 return id3->path;
388 case WPS_TOKEN_FILE_SIZE:
389 snprintf(buf, buf_size, "%ld", id3->filesize / 1024);
390 return buf;
392 case WPS_TOKEN_FILE_VBR:
393 return id3->vbr ? "(avg)" : NULL;
395 case WPS_TOKEN_FILE_DIRECTORY:
396 return get_dir(buf, buf_size, id3->path, token->value.i);
398 case WPS_TOKEN_BATTERY_PERCENT:
400 int l = battery_level();
402 if (intval)
404 limit = MAX(limit, 2);
405 if (l > -1) {
406 /* First enum is used for "unknown level". */
407 *intval = (limit - 1) * l / 100 + 2;
408 } else {
409 *intval = 1;
413 if (l > -1) {
414 snprintf(buf, buf_size, "%d", l);
415 return buf;
416 } else {
417 return "?";
421 case WPS_TOKEN_BATTERY_VOLTS:
423 unsigned int v = battery_voltage();
424 snprintf(buf, buf_size, "%d.%02d", v / 1000, (v % 1000) / 10);
425 return buf;
428 case WPS_TOKEN_BATTERY_TIME:
430 int t = battery_time();
431 if (t >= 0)
432 snprintf(buf, buf_size, "%dh %dm", t / 60, t % 60);
433 else
434 return "?h ?m";
435 return buf;
438 #if CONFIG_CHARGING
439 case WPS_TOKEN_BATTERY_CHARGER_CONNECTED:
441 if(charger_input_state==CHARGER)
442 return "p";
443 else
444 return NULL;
446 #endif
447 #if CONFIG_CHARGING >= CHARGING_MONITOR
448 case WPS_TOKEN_BATTERY_CHARGING:
450 if (charge_state == CHARGING || charge_state == TOPOFF) {
451 return "c";
452 } else {
453 return NULL;
456 #endif
457 case WPS_TOKEN_BATTERY_SLEEPTIME:
459 if (get_sleep_timer() == 0)
460 return NULL;
461 else
463 format_time(buf, buf_size, get_sleep_timer() * 1000);
464 return buf;
468 case WPS_TOKEN_PLAYBACK_STATUS:
470 int status = audio_status();
471 int mode = 1;
472 if (status == AUDIO_STATUS_PLAY)
473 mode = 2;
474 if (is_wps_fading() ||
475 (status & AUDIO_STATUS_PAUSE && !status_get_ffmode()))
476 mode = 3;
477 if (status_get_ffmode() == STATUS_FASTFORWARD)
478 mode = 4;
479 if (status_get_ffmode() == STATUS_FASTBACKWARD)
480 mode = 5;
482 if (intval) {
483 *intval = mode;
486 snprintf(buf, buf_size, "%d", mode-1);
487 return buf;
490 case WPS_TOKEN_REPEAT_MODE:
491 if (intval)
492 *intval = global_settings.repeat_mode + 1;
493 snprintf(buf, buf_size, "%d", global_settings.repeat_mode);
494 return buf;
496 case WPS_TOKEN_RTC_PRESENT:
497 #if CONFIG_RTC
498 return "c";
499 #else
500 return NULL;
501 #endif
503 #if CONFIG_RTC
504 case WPS_TOKEN_RTC_12HOUR_CFG:
505 if (intval)
506 *intval = global_settings.timeformat + 1;
507 snprintf(buf, buf_size, "%d", global_settings.timeformat);
508 return buf;
510 case WPS_TOKEN_RTC_DAY_OF_MONTH:
511 /* d: day of month (01..31) */
512 snprintf(buf, buf_size, "%02d", tm->tm_mday);
513 return buf;
515 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED:
516 /* e: day of month, blank padded ( 1..31) */
517 snprintf(buf, buf_size, "%2d", tm->tm_mday);
518 return buf;
520 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED:
521 /* H: hour (00..23) */
522 snprintf(buf, buf_size, "%02d", tm->tm_hour);
523 return buf;
525 case WPS_TOKEN_RTC_HOUR_24:
526 /* k: hour ( 0..23) */
527 snprintf(buf, buf_size, "%2d", tm->tm_hour);
528 return buf;
530 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED:
531 /* I: hour (01..12) */
532 snprintf(buf, buf_size, "%02d",
533 (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12);
534 return buf;
536 case WPS_TOKEN_RTC_HOUR_12:
537 /* l: hour ( 1..12) */
538 snprintf(buf, buf_size, "%2d",
539 (tm->tm_hour % 12 == 0) ? 12 : tm->tm_hour % 12);
540 return buf;
542 case WPS_TOKEN_RTC_MONTH:
543 /* m: month (01..12) */
544 if (intval)
545 *intval = tm->tm_mon + 1;
546 snprintf(buf, buf_size, "%02d", tm->tm_mon + 1);
547 return buf;
549 case WPS_TOKEN_RTC_MINUTE:
550 /* M: minute (00..59) */
551 snprintf(buf, buf_size, "%02d", tm->tm_min);
552 return buf;
554 case WPS_TOKEN_RTC_SECOND:
555 /* S: second (00..59) */
556 snprintf(buf, buf_size, "%02d", tm->tm_sec);
557 return buf;
559 case WPS_TOKEN_RTC_YEAR_2_DIGITS:
560 /* y: last two digits of year (00..99) */
561 snprintf(buf, buf_size, "%02d", tm->tm_year % 100);
562 return buf;
564 case WPS_TOKEN_RTC_YEAR_4_DIGITS:
565 /* Y: year (1970...) */
566 snprintf(buf, buf_size, "%04d", tm->tm_year + 1900);
567 return buf;
569 case WPS_TOKEN_RTC_AM_PM_UPPER:
570 /* p: upper case AM or PM indicator */
571 return tm->tm_hour/12 == 0 ? "AM" : "PM";
573 case WPS_TOKEN_RTC_AM_PM_LOWER:
574 /* P: lower case am or pm indicator */
575 return tm->tm_hour/12 == 0 ? "am" : "pm";
577 case WPS_TOKEN_RTC_WEEKDAY_NAME:
578 /* a: abbreviated weekday name (Sun..Sat) */
579 return str(LANG_WEEKDAY_SUNDAY + tm->tm_wday);
581 case WPS_TOKEN_RTC_MONTH_NAME:
582 /* b: abbreviated month name (Jan..Dec) */
583 return str(LANG_MONTH_JANUARY + tm->tm_mon);
585 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON:
586 /* u: day of week (1..7); 1 is Monday */
587 if (intval)
588 *intval = (tm->tm_wday == 0) ? 7 : tm->tm_wday;
589 snprintf(buf, buf_size, "%1d", tm->tm_wday + 1);
590 return buf;
592 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN:
593 /* w: day of week (0..6); 0 is Sunday */
594 if (intval)
595 *intval = tm->tm_wday + 1;
596 snprintf(buf, buf_size, "%1d", tm->tm_wday);
597 return buf;
598 #else
599 case WPS_TOKEN_RTC_DAY_OF_MONTH:
600 case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED:
601 case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED:
602 case WPS_TOKEN_RTC_HOUR_24:
603 case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED:
604 case WPS_TOKEN_RTC_HOUR_12:
605 case WPS_TOKEN_RTC_MONTH:
606 case WPS_TOKEN_RTC_MINUTE:
607 case WPS_TOKEN_RTC_SECOND:
608 case WPS_TOKEN_RTC_AM_PM_UPPER:
609 case WPS_TOKEN_RTC_AM_PM_LOWER:
610 case WPS_TOKEN_RTC_YEAR_2_DIGITS:
611 return "--";
612 case WPS_TOKEN_RTC_YEAR_4_DIGITS:
613 return "----";
614 case WPS_TOKEN_RTC_WEEKDAY_NAME:
615 case WPS_TOKEN_RTC_MONTH_NAME:
616 return "---";
617 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON:
618 case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN:
619 return "-";
620 #endif
622 #ifdef HAVE_LCD_CHARCELLS
623 case WPS_TOKEN_PROGRESSBAR:
625 char *end = utf8encode(data->wps_progress_pat[0], buf);
626 *end = '\0';
627 return buf;
630 case WPS_TOKEN_PLAYER_PROGRESSBAR:
631 if(is_new_player())
633 /* we need 11 characters (full line) for
634 progress-bar */
635 strlcpy(buf, " ", buf_size);
637 else
639 /* Tell the user if we have an OldPlayer */
640 strlcpy(buf, " <Old LCD> ", buf_size);
642 return buf;
643 #endif
645 #ifdef HAVE_TAGCACHE
646 case WPS_TOKEN_DATABASE_PLAYCOUNT:
647 if (intval) {
648 *intval = id3->playcount + 1;
650 snprintf(buf, buf_size, "%ld", id3->playcount);
651 return buf;
653 case WPS_TOKEN_DATABASE_RATING:
654 if (intval) {
655 *intval = id3->rating + 1;
657 snprintf(buf, buf_size, "%d", id3->rating);
658 return buf;
660 case WPS_TOKEN_DATABASE_AUTOSCORE:
661 if (intval)
662 *intval = id3->score + 1;
664 snprintf(buf, buf_size, "%d", id3->score);
665 return buf;
666 #endif
668 #if (CONFIG_CODEC == SWCODEC)
669 case WPS_TOKEN_CROSSFADE:
670 if (intval)
671 *intval = global_settings.crossfade + 1;
672 snprintf(buf, buf_size, "%d", global_settings.crossfade);
673 return buf;
675 case WPS_TOKEN_REPLAYGAIN:
677 int val;
679 if (global_settings.replaygain_type == REPLAYGAIN_OFF)
680 val = 1; /* off */
681 else
683 int type =
684 get_replaygain_mode(id3->track_gain_string != NULL,
685 id3->album_gain_string != NULL);
686 if (type < 0)
687 val = 6; /* no tag */
688 else
689 val = type + 2;
691 if (global_settings.replaygain_type == REPLAYGAIN_SHUFFLE)
692 val += 2;
695 if (intval)
696 *intval = val;
698 switch (val)
700 case 1:
701 case 6:
702 return "+0.00 dB";
703 break;
704 case 2:
705 case 4:
706 strlcpy(buf, id3->track_gain_string, buf_size);
707 break;
708 case 3:
709 case 5:
710 strlcpy(buf, id3->album_gain_string, buf_size);
711 break;
713 return buf;
715 #endif /* (CONFIG_CODEC == SWCODEC) */
717 #if (CONFIG_CODEC != MAS3507D)
718 case WPS_TOKEN_SOUND_PITCH:
720 int val = sound_get_pitch();
721 snprintf(buf, buf_size, "%d.%d",
722 val / 10, val % 10);
723 return buf;
725 #endif
727 case WPS_TOKEN_MAIN_HOLD:
728 #ifdef HAS_BUTTON_HOLD
729 if (button_hold())
730 #else
731 if (is_keys_locked())
732 #endif /*hold switch or softlock*/
733 return "h";
734 else
735 return NULL;
737 #ifdef HAS_REMOTE_BUTTON_HOLD
738 case WPS_TOKEN_REMOTE_HOLD:
739 if (remote_button_hold())
740 return "r";
741 else
742 return NULL;
743 #endif
745 #if (CONFIG_LED == LED_VIRTUAL) || defined(HAVE_REMOTE_LCD)
746 case WPS_TOKEN_VLED_HDD:
747 if(led_read(HZ/2))
748 return "h";
749 else
750 return NULL;
751 #endif
752 case WPS_TOKEN_BUTTON_VOLUME:
753 if (data->button_time_volume &&
754 TIME_BEFORE(current_tick, data->button_time_volume +
755 token->value.i * TIMEOUT_UNIT))
756 return "v";
757 return NULL;
758 case WPS_TOKEN_LASTTOUCH:
759 #ifdef HAVE_TOUCHSCREEN
760 if (TIME_BEFORE(current_tick, token->value.i * TIMEOUT_UNIT +
761 touchscreen_last_touch()))
762 return "t";
763 #endif
764 return NULL;
766 case WPS_TOKEN_SETTING:
768 if (intval)
770 /* Handle contionals */
771 const struct settings_list *s = settings+token->value.i;
772 switch (s->flags&F_T_MASK)
774 case F_T_INT:
775 case F_T_UINT:
776 if (s->flags&F_RGB)
777 /* %?St|name|<#000000|#000001|...|#FFFFFF> */
778 /* shouldn't overflow since colors are stored
779 * on 16 bits ...
780 * but this is pretty useless anyway */
781 *intval = *(int*)s->setting + 1;
782 else if (s->cfg_vals == NULL)
783 /* %?St|name|<1st choice|2nd choice|...> */
784 *intval = (*(int*)s->setting-s->int_setting->min)
785 /s->int_setting->step + 1;
786 else
787 /* %?St|name|<1st choice|2nd choice|...> */
788 /* Not sure about this one. cfg_name/vals are
789 * indexed from 0 right? */
790 *intval = *(int*)s->setting + 1;
791 break;
792 case F_T_BOOL:
793 /* %?St|name|<if true|if false> */
794 *intval = *(bool*)s->setting?1:2;
795 break;
796 case F_T_CHARPTR:
797 /* %?St|name|<if non empty string|if empty>
798 * The string's emptyness discards the setting's
799 * prefix and suffix */
800 *intval = ((char*)s->setting)[0]?1:2;
801 break;
802 default:
803 /* This shouldn't happen ... but you never know */
804 *intval = -1;
805 break;
808 cfg_to_string(token->value.i,buf,buf_size);
809 return buf;
812 default:
813 return NULL;