summaryrefslogtreecommitdiff
path: root/apps/gui/wps_parser.c
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2007-11-11 12:29:37 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2007-11-11 12:29:37 +0000
commit9d4bed7ff06818b098926932db824a8d6532bfee (patch)
tree0a1cfa6a98a75a2badc1a8d2a2d7839454522beb /apps/gui/wps_parser.c
parentf34720b163aff1d167ae031f23f3250356aa2c1b (diff)
downloadrockbox-9d4bed7ff06818b098926932db824a8d6532bfee.tar.gz
rockbox-9d4bed7ff06818b098926932db824a8d6532bfee.zip
Album art support. Based on FS#3045, but heavily modified to adapt to MoB and for cleanness.
The cover pictures are loaded from external bitmaps. JPEG and embedded art are not supported. The pictures will only be drawn on the main display. There is no resizing but it is possible to specify the WPS bitmap size in the bitmap names (e.g. cover.100x100.bmp). The bitmaps are stored in the main buffer and read directly from there. Currently, duplicate bitmaps will simply be present several times in the buffer, but this will be improved. To enable for a target, #define HAVE_ALBUMART in its config file. For more information, see the wiki page: http://www.rockbox.org/wiki/AlbumArt. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15572 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/gui/wps_parser.c')
-rw-r--r--apps/gui/wps_parser.c225
1 files changed, 225 insertions, 0 deletions
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 8471bff7d8..097a60c90f 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -113,6 +113,7 @@ static int parse_progressbar(const char *wps_bufptr,
113 struct wps_token *token, struct wps_data *wps_data); 113 struct wps_token *token, struct wps_data *wps_data);
114static int parse_dir_level(const char *wps_bufptr, 114static int parse_dir_level(const char *wps_bufptr,
115 struct wps_token *token, struct wps_data *wps_data); 115 struct wps_token *token, struct wps_data *wps_data);
116
116#ifdef HAVE_LCD_BITMAP 117#ifdef HAVE_LCD_BITMAP
117static int parse_image_special(const char *wps_bufptr, 118static int parse_image_special(const char *wps_bufptr,
118 struct wps_token *token, struct wps_data *wps_data); 119 struct wps_token *token, struct wps_data *wps_data);
@@ -126,6 +127,13 @@ static int parse_image_load(const char *wps_bufptr,
126 struct wps_token *token, struct wps_data *wps_data); 127 struct wps_token *token, struct wps_data *wps_data);
127#endif /*HAVE_LCD_BITMAP */ 128#endif /*HAVE_LCD_BITMAP */
128 129
130#ifdef HAVE_ALBUMART
131static int parse_albumart_load(const char *wps_bufptr,
132 struct wps_token *token, struct wps_data *wps_data);
133static int parse_albumart_conditional(const char *wps_bufptr,
134 struct wps_token *token, struct wps_data *wps_data);
135#endif /* HAVE_ALBUMART */
136
129#ifdef CONFIG_RTC 137#ifdef CONFIG_RTC
130#define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC 138#define WPS_RTC_REFRESH WPS_REFRESH_DYNAMIC
131#else 139#else
@@ -283,6 +291,11 @@ static const struct wps_tag all_tags[] = {
283 291
284 { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load }, 292 { WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load },
285 { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special }, 293 { WPS_TOKEN_IMAGE_PROGRESS_BAR, "P", 0, parse_image_special },
294#ifdef HAVE_ALBUMART
295 { WPS_NO_TOKEN, "Cl", 0, parse_albumart_load },
296 { WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_DYNAMIC,
297 parse_albumart_conditional },
298#endif
286#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1)) 299#if (LCD_DEPTH > 1) || (defined(HAVE_LCD_REMOTE) && (LCD_REMOTE_DEPTH > 1))
287 { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special }, 300 { WPS_TOKEN_IMAGE_BACKDROP, "X", 0, parse_image_special },
288#endif 301#endif
@@ -606,6 +619,215 @@ static int parse_progressbar(const char *wps_bufptr,
606#endif 619#endif
607} 620}
608 621
622#ifdef HAVE_ALBUMART
623static int parse_albumart_load(const char *wps_bufptr,
624 struct wps_token *token,
625 struct wps_data *wps_data)
626{
627 const char* _pos;
628 bool parsing;
629 const short xalign_mask = WPS_ALBUMART_ALIGN_LEFT |
630 WPS_ALBUMART_ALIGN_CENTER |
631 WPS_ALBUMART_ALIGN_RIGHT;
632 const short yalign_mask = WPS_ALBUMART_ALIGN_TOP |
633 WPS_ALBUMART_ALIGN_CENTER |
634 WPS_ALBUMART_ALIGN_BOTTOM;
635
636 (void)token; /* silence warning */
637
638 /* reset albumart info in wps */
639 wps_data->wps_uses_albumart = WPS_ALBUMART_NONE;
640 wps_data->albumart_max_width = -1;
641 wps_data->albumart_max_height = -1;
642 wps_data->albumart_xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */
643 wps_data->albumart_yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */
644
645 /* format: %Cl|x|y|[[l|c|r][d|i|s]mwidth]|[[t|c|b][d|i|s]mheight]| */
646
647 /* initial validation and parsing of x and y components */
648 if (*wps_bufptr != '|')
649 return 0; /* malformed token: e.g. %Cl7 */
650
651 _pos = wps_bufptr + 1;
652 if (!isdigit(*_pos))
653 return 0; /* malformed token: e.g. %Cl|@ */
654 wps_data->albumart_x = atoi(_pos);
655
656 _pos = strchr(_pos, '|');
657 if (!_pos || !isdigit(*(++_pos)))
658 return 0; /* malformed token: e.g. %Cl|7\n or %Cl|7|@ */
659
660 wps_data->albumart_y = atoi(_pos);
661
662 _pos = strchr(_pos, '|');
663 if (!_pos)
664 return 0; /* malformed token: no | after y coordinate
665 e.g. %Cl|7|59\n */
666
667 /* parsing width field */
668 parsing = true;
669 while (parsing)
670 {
671 /* apply each modifier in turn */
672 ++_pos;
673 switch (*_pos)
674 {
675 case 'l':
676 case 'L':
677 case '+':
678 wps_data->albumart_xalign =
679 (wps_data->albumart_xalign & xalign_mask) |
680 WPS_ALBUMART_ALIGN_LEFT;
681 break;
682 case 'c':
683 case 'C':
684 wps_data->albumart_xalign =
685 (wps_data->albumart_xalign & xalign_mask) |
686 WPS_ALBUMART_ALIGN_CENTER;
687 break;
688 case 'r':
689 case 'R':
690 case '-':
691 wps_data->albumart_xalign =
692 (wps_data->albumart_xalign & xalign_mask) |
693 WPS_ALBUMART_ALIGN_RIGHT;
694 break;
695 case 'd':
696 case 'D':
697 wps_data->albumart_xalign |= WPS_ALBUMART_DECREASE;
698 break;
699 case 'i':
700 case 'I':
701 wps_data->albumart_xalign |= WPS_ALBUMART_INCREASE;
702 break;
703 case 's':
704 case 'S':
705 wps_data->albumart_xalign |=
706 (WPS_ALBUMART_DECREASE | WPS_ALBUMART_INCREASE);
707 break;
708 default:
709 parsing = false;
710 break;
711 }
712 }
713 /* extract max width data */
714 if (*_pos != '|')
715 {
716 if (!isdigit(*_pos))
717 return 0; /* malformed token: e.g. %Cl|7|59|# */
718 wps_data->albumart_max_width = atoi(_pos);
719 _pos = strchr(_pos, '|');
720 if (!_pos)
721 return 0; /* malformed token: no | after width field
722 e.g. %Cl|7|59|200\n */
723 }
724
725 /* parsing height field */
726 parsing = true;
727 while (parsing)
728 {
729 /* apply each modifier in turn */
730 ++_pos;
731 switch (*_pos)
732 {
733 case 't':
734 case 'T':
735 case '-':
736 wps_data->albumart_yalign =
737 (wps_data->albumart_yalign & yalign_mask) |
738 WPS_ALBUMART_ALIGN_TOP;
739 break;
740 case 'c':
741 case 'C':
742 wps_data->albumart_yalign =
743 (wps_data->albumart_yalign & yalign_mask) |
744 WPS_ALBUMART_ALIGN_CENTER;
745 break;
746 case 'b':
747 case 'B':
748 case '+':
749 wps_data->albumart_yalign =
750 (wps_data->albumart_yalign & yalign_mask) |
751 WPS_ALBUMART_ALIGN_BOTTOM;
752 break;
753 case 'd':
754 case 'D':
755 wps_data->albumart_yalign |= WPS_ALBUMART_DECREASE;
756 break;
757 case 'i':
758 case 'I':
759 wps_data->albumart_yalign |= WPS_ALBUMART_INCREASE;
760 break;
761 case 's':
762 case 'S':
763 wps_data->albumart_yalign |=
764 (WPS_ALBUMART_DECREASE | WPS_ALBUMART_INCREASE);
765 break;
766 default:
767 parsing = false;
768 break;
769 }
770 }
771 /* extract max height data */
772 if (*_pos != '|')
773 {
774 if (!isdigit(*_pos))
775 return 0; /* malformed token e.g. %Cl|7|59|200|@ */
776 wps_data->albumart_max_height = atoi(_pos);
777 _pos = strchr(_pos, '|');
778 if (!_pos)
779 return 0; /* malformed token: no closing |
780 e.g. %Cl|7|59|200|200\n */
781 }
782
783 /* if we got here, we parsed everything ok .. ! */
784 if (wps_data->albumart_max_width < 0)
785 wps_data->albumart_max_width = 0;
786 else if (wps_data->albumart_max_width > LCD_WIDTH)
787 wps_data->albumart_max_width = LCD_WIDTH;
788
789 if (wps_data->albumart_max_height < 0)
790 wps_data->albumart_max_height = 0;
791 else if (wps_data->albumart_max_height > LCD_HEIGHT)
792 wps_data->albumart_max_height = LCD_HEIGHT;
793
794 wps_data->wps_uses_albumart = WPS_ALBUMART_LOAD;
795
796 /* Skip the rest of the line */
797 return skip_end_of_line(wps_bufptr);
798}
799
800static int parse_albumart_conditional(const char *wps_bufptr,
801 struct wps_token *token,
802 struct wps_data *wps_data)
803{
804 struct wps_token *prevtoken = token;
805 --prevtoken;
806 if (wps_data->num_tokens >= 1 && prevtoken->type == WPS_TOKEN_CONDITIONAL)
807 {
808 /* This %C is part of a %?C construct.
809 It's either %?C<blah> or %?Cn<blah> */
810 token->type = WPS_TOKEN_ALBUMART_FOUND;
811 if (*wps_bufptr == 'n' && *(wps_bufptr + 1) == '<')
812 {
813 token->next = true;
814 return 1;
815 }
816 else if (*wps_bufptr == '<')
817 {
818 return 0;
819 }
820 else
821 {
822 token->type = WPS_NO_TOKEN;
823 return 0;
824 }
825 }
826 else
827 return 0;
828};
829#endif /* HAVE_ALBUMART */
830
609/* Parse a generic token from the given string. Return the length read */ 831/* Parse a generic token from the given string. Return the length read */
610static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) 832static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
611{ 833{
@@ -915,6 +1137,9 @@ static void wps_reset(struct wps_data *data)
915 bool rwps = data->remote_wps; /* remember whether the data is for a RWPS */ 1137 bool rwps = data->remote_wps; /* remember whether the data is for a RWPS */
916#endif 1138#endif
917 memset(data, 0, sizeof(*data)); 1139 memset(data, 0, sizeof(*data));
1140#ifdef HAVE_ALBUMART
1141 data->wps_uses_albumart = WPS_ALBUMART_NONE;
1142#endif
918 wps_data_init(data); 1143 wps_data_init(data);
919#ifdef HAVE_REMOTE_LCD 1144#ifdef HAVE_REMOTE_LCD
920 data->remote_wps = rwps; 1145 data->remote_wps = rwps;