summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/gui/gwps-common.c341
-rw-r--r--apps/gui/gwps-common.h5
-rw-r--r--apps/gui/gwps.c40
-rw-r--r--apps/gui/gwps.h2
4 files changed, 220 insertions, 168 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index 665f6f4bb0..a6ef9b04d3 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -55,11 +55,191 @@ static void draw_player_fullbar(struct gui_wps *gwps,
55 /* 3% of 30min file == 54s step size */ 55 /* 3% of 30min file == 54s step size */
56#define MIN_FF_REWIND_STEP 500 56#define MIN_FF_REWIND_STEP 500
57 57
58/*
59 * returns the image_id between
60 * a..z and A..Z
61 */
62#ifdef HAVE_LCD_BITMAP
63static int get_image_id(int c)
64{
65 if(c >= 'a' && c <= 'z')
66 c -= 'a';
67 if(c >= 'A' && c <= 'Z')
68 c = c - 'A' + 26;
69 return c;
70}
71#endif
72/*
73 * parse the given buffer for following static tags:
74 * %x - load image for always display
75 * %xl - preload image
76 * %we - enable statusbar on wps regardless of the global setting
77 * %wd - disable statusbar on wps regardless of the global setting
78 * and also for:
79 * # - a comment line
80 *
81 * it returns true if one of these tags is found and handled
82 * false otherwise
83 */
84bool wps_data_preload_tags(struct wps_data *data, unsigned char *buf,
85 const char *bmpdir, size_t bmpdirlen)
86{
87 if(!data || !buf) return false;
88
89 char c;
90#ifndef HAVE_LCD_BITMAP
91 /* no bitmap-lcd == no bitmap loading */
92 (void)bmpdir;
93 (void)bmpdirlen;
94#endif
95 /* jump over the UTF-8 BOM(Byte Order Mark) if exist
96 * the BOM for UTF-8 is 3 bytes long and looks like so:
97 * 1. Byte: 0xEF
98 * 2. Byte: 0xBB
99 * 3. Byte: 0xBF
100 */
101 if(buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf)
102 buf+=3;
103
104 if(*buf == '#')
105 return true;
106 if('%' != *buf)
107 return false;
108 buf++;
109
110 c = *buf;
111 switch (c)
112 {
113#ifdef HAVE_LCD_BITMAP
114 case 'w':
115 /*
116 * if tag found then return because these two tags must be on
117 * must be on their own line
118 */
119 if(*(buf+1) == 'd' || *(buf+1) == 'e')
120 {
121 data->wps_sb_tag = true;
122 if( *(buf+1) == 'e' )
123 data->show_sb_on_wps = true;
124 return true;
125 }
126 break;
127
128 case 'x':
129 /* Preload images so the %xd# tag can display it */
130 {
131 int ret = 0;
132 int n;
133 char *ptr = buf+1;
134 char *pos = NULL;
135 char imgname[MAX_PATH];
136 char qual = *ptr;
137
138 if (qual == 'l' || qual == '|') /* format:
139 %x|n|filename.bmp|x|y|
140 or
141 %xl|n|filename.bmp|x|y|
142 */
143 {
144 ptr = strchr(ptr, '|') + 1;
145 pos = strchr(ptr, '|');
146 if (pos)
147 {
148 /* get the image ID */
149 n = get_image_id(*ptr);
150
151 if(n < 0 || n >= MAX_IMAGES)
152 {
153 /* Skip the rest of the line */
154 while(*buf != '\n')
155 buf++;
156 return false;
157 }
158 ptr = pos+1;
159
160 /* check the image number and load state */
161 if (data->img[n].loaded)
162 {
163 /* Skip the rest of the line */
164 while(*buf != '\n')
165 buf++;
166 return false;
167 }
168 else
169 {
170 /* get filename */
171 pos = strchr(ptr, '|');
172 if ((pos - ptr) <
173 (int)sizeof(imgname)-ROCKBOX_DIR_LEN-2)
174 {
175 memcpy(imgname, bmpdir, bmpdirlen);
176 imgname[bmpdirlen] = '/';
177 memcpy(&imgname[bmpdirlen+1],
178 ptr, pos - ptr);
179 imgname[bmpdirlen+1+pos-ptr] = 0;
180 }
181 else
182 /* filename too long */
183 imgname[0] = 0;
184
185 ptr = pos+1;
186
187 /* get x-position */
188 pos = strchr(ptr, '|');
189 if (pos)
190 data->img[n].x = atoi(ptr);
191 else
192 {
193 /* weird syntax, bail out */
194 buf++;
195 return false;
196 }
197
198 /* get y-position */
199 ptr = pos+1;
200 pos = strchr(ptr, '|');
201 if (pos)
202 data->img[n].y = atoi(ptr);
203 else
204 {
205 /* weird syntax, bail out */
206 buf++;
207 return false;
208 }
209
210 /* load the image */
211 ret = read_bmp_file(imgname, &data->img[n].w,
212 &data->img[n].h, data->img_buf_ptr,
213 data->img_buf_free);
214 if (ret > 0)
215 {
216 data->img[n].ptr = data->img_buf_ptr;
217 data->img_buf_ptr += ret;
218 data->img_buf_free -= ret;
219 data->img[n].loaded = true;
220 if(qual == '|')
221 data->img[n].always_display = true;
222 }
223 return true;
224 }
225 }
226 }
227 }
228
229 break;
230#endif
231 }
232 /* no of these tags found */
233 return false;
234}
235
236
58/* draws the statusbar on the given wps-screen */ 237/* draws the statusbar on the given wps-screen */
59#ifdef HAVE_LCD_BITMAP 238#ifdef HAVE_LCD_BITMAP
60static void gui_wps_statusbar_draw(struct gui_wps *wps, bool force) 239static void gui_wps_statusbar_draw(struct gui_wps *wps, bool force)
61{ 240{
62 bool draw = global_settings.statusbar; 241 bool draw = global_settings.statusbar;
242
63 if(wps->data->wps_sb_tag 243 if(wps->data->wps_sb_tag
64 && wps->data->show_sb_on_wps) 244 && wps->data->show_sb_on_wps)
65 draw = true; 245 draw = true;
@@ -781,13 +961,7 @@ static void format_display(struct gui_wps *gwps, char* buf,
781 961
782 case 'x': /* image support */ 962 case 'x': /* image support */
783#ifdef HAVE_LCD_BITMAP 963#ifdef HAVE_LCD_BITMAP
784 /* skip preload or regular image tag */ 964 if ('d' == *(fmt+1) )
785 if ('l' == *(fmt+1) || '|' == *(fmt+1))
786 {
787 while (*fmt && *fmt != '\n')
788 fmt++;
789 }
790 else if ('d' == *(fmt+1) )
791 { 965 {
792 fmt+=2; 966 fmt+=2;
793 967
@@ -925,23 +1099,13 @@ void fade(bool fade_in)
925} 1099}
926 1100
927/* Set format string to use for WPS, splitting it into lines */ 1101/* Set format string to use for WPS, splitting it into lines */
928void gui_wps_format(struct wps_data *data, const char *bmpdir, 1102void gui_wps_format(struct wps_data *data)
929 size_t bmpdirlen)
930{ 1103{
931 char* buf = data->format_buffer; 1104 char* buf = data->format_buffer;
932 char* start_of_line = data->format_buffer; 1105 char* start_of_line = data->format_buffer;
933 int line = 0; 1106 int line = 0;
934 int subline; 1107 int subline;
935 char c, lastc = 0; 1108 char c;
936#ifndef HAVE_LCD_BITMAP
937 /* no bitmap lcd == no bitmap loading */
938 (void)bmpdir;
939 (void)bmpdirlen;
940#else
941 unsigned char* img_buf_ptr = data->img_buf; /* where in image buffer */
942
943 int img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
944#endif
945 if(!data) 1109 if(!data)
946 return; 1110 return;
947 1111
@@ -955,16 +1119,11 @@ void gui_wps_format(struct wps_data *data, const char *bmpdir,
955 data->subline_expire_time[line] = 0; 1119 data->subline_expire_time[line] = 0;
956 data->curr_subline[line] = SUBLINE_RESET; 1120 data->curr_subline[line] = SUBLINE_RESET;
957 } 1121 }
958 1122
959 line = 0; 1123 line = 0;
960 subline = 0; 1124 subline = 0;
961 data->format_lines[line][subline] = buf; 1125 data->format_lines[line][subline] = buf;
962 1126
963#ifdef HAVE_LCD_BITMAP
964 bool wps_tag_found = false;
965 data->wps_sb_tag = false;
966 data->show_sb_on_wps = false;
967#endif
968 while ((*buf) && (line < WPS_MAX_LINES)) 1127 while ((*buf) && (line < WPS_MAX_LINES))
969 { 1128 {
970 c = *buf; 1129 c = *buf;
@@ -976,18 +1135,7 @@ void gui_wps_format(struct wps_data *data, const char *bmpdir,
976 * don't skip %x lines (pre-load bitmaps) 1135 * don't skip %x lines (pre-load bitmaps)
977 */ 1136 */
978 case '%': 1137 case '%':
979#ifdef HAVE_LCD_BITMAP 1138 buf++;
980 if(*(buf+1) == 'w' && (*(buf+2) == 'd' || *(buf+2) == 'e')
981 && !wps_tag_found)
982 {
983 data->wps_sb_tag = true;
984 if( *(buf+1) == 'w' && *(buf+2) == 'e' )
985 data->show_sb_on_wps = true;
986 wps_tag_found = true;
987 }
988 if (*(buf+1) != 'x')
989#endif
990 buf++;
991 break; 1139 break;
992 1140
993 case '\r': /* CR */ 1141 case '\r': /* CR */
@@ -1029,126 +1177,7 @@ void gui_wps_format(struct wps_data *data, const char *bmpdir,
1029 subline = 0; 1177 subline = 0;
1030 } 1178 }
1031 break; 1179 break;
1032
1033 case 'x':
1034#ifdef HAVE_LCD_BITMAP
1035 /* Preload images so the %xd# tag can display it */
1036 {
1037 int ret = 0;
1038 int n;
1039 char *ptr = buf+1;
1040 char *pos = NULL;
1041 char imgname[MAX_PATH];
1042 char qual = *ptr;
1043
1044 if(lastc != '%')
1045 break;
1046
1047 if (qual == 'l' || qual == '|') /* format:
1048 %x|n|filename.bmp|x|y|
1049 or
1050 %xl|n|filename.bmp|x|y|
1051 */
1052 {
1053 ptr = strchr(ptr, '|') + 1;
1054 pos = strchr(ptr, '|');
1055 if (pos)
1056 {
1057 /* get the image ID */
1058 n = *ptr;
1059 if(n >= 'a' && n <= 'z')
1060 n -= 'a';
1061 if(n >= 'A' && n <= 'Z')
1062 n = n - 'A' + 26;
1063
1064 if(n < 0 || n >= MAX_IMAGES)
1065 {
1066 /* Skip the rest of the line */
1067 while(*buf != '\n')
1068 buf++;
1069 break;
1070 }
1071 ptr = pos+1;
1072
1073 /* check the image number and load state */
1074 if (data->img[n].loaded)
1075 {
1076 /* Skip the rest of the line */
1077 while(*buf != '\n')
1078 buf++;
1079 break;
1080 }
1081 else
1082 {
1083 /* get filename */
1084 pos = strchr(ptr, '|');
1085 if ((pos - ptr) <
1086 (int)sizeof(imgname)-ROCKBOX_DIR_LEN-2)
1087 {
1088 memcpy(imgname, bmpdir, bmpdirlen);
1089 imgname[bmpdirlen] = '/';
1090 memcpy(&imgname[bmpdirlen+1],
1091 ptr, pos - ptr);
1092 imgname[bmpdirlen+1+pos-ptr] = 0;
1093 }
1094 else
1095 /* filename too long */
1096 imgname[0] = 0;
1097
1098 ptr = pos+1;
1099
1100 /* get x-position */
1101 pos = strchr(ptr, '|');
1102 if (pos)
1103 data->img[n].x = atoi(ptr);
1104 else
1105 {
1106 /* weird syntax, bail out */
1107 buf++;
1108 break;
1109 }
1110
1111 /* get y-position */
1112 ptr = pos+1;
1113 pos = strchr(ptr, '|');
1114 if (pos)
1115 data->img[n].y = atoi(ptr);
1116 else
1117 {
1118 /* weird syntax, bail out */
1119 buf++;
1120 break;
1121 }
1122
1123 pos++;
1124
1125 /* reposition buf pointer to next WPS element */
1126 while (*pos && *pos != ';' && *pos != '\n')
1127 pos++;
1128
1129 buf = pos;
1130
1131 /* load the image */
1132 ret = read_bmp_file(imgname, &data->img[n].w,
1133 &data->img[n].h, (char *)img_buf_ptr,
1134 img_buf_free);
1135 if (ret > 0)
1136 {
1137 data->img[n].ptr = img_buf_ptr;
1138 img_buf_ptr += ret;
1139 img_buf_free -= ret;
1140 data->img[n].loaded = true;
1141 if(qual == '|')
1142 data->img[n].always_display = true;
1143 }
1144 }
1145 }
1146 }
1147 }
1148#endif
1149 break;
1150 } 1180 }
1151 lastc = c;
1152 buf++; 1181 buf++;
1153 } 1182 }
1154} 1183}
diff --git a/apps/gui/gwps-common.h b/apps/gui/gwps-common.h
index e9c1a42299..7909270419 100644
--- a/apps/gui/gwps-common.h
+++ b/apps/gui/gwps-common.h
@@ -25,8 +25,7 @@
25 25
26void gui_wps_format_time(char* buf, int buf_size, long time); 26void gui_wps_format_time(char* buf, int buf_size, long time);
27void fade(bool fade_in); 27void fade(bool fade_in);
28void gui_wps_format(struct wps_data *data, const char *bmpdir, 28void gui_wps_format(struct wps_data *data);
29 size_t bmpdirlen);
30bool gui_wps_refresh(struct gui_wps *gwps, int ffwd_offset, 29bool gui_wps_refresh(struct gui_wps *gwps, int ffwd_offset,
31 unsigned char refresh_mode); 30 unsigned char refresh_mode);
32bool gui_wps_display(void); 31bool gui_wps_display(void);
@@ -34,6 +33,8 @@ void setvol(void);
34bool update_onvol_change(struct gui_wps * gwps); 33bool update_onvol_change(struct gui_wps * gwps);
35bool update(struct gui_wps *gwps); 34bool update(struct gui_wps *gwps);
36bool ffwd_rew(int button); 35bool ffwd_rew(int button);
36bool wps_data_preload_tags(struct wps_data *data, unsigned char *buf,
37 const char *bmpdir, size_t bmpdirlen);
37#ifdef WPS_KEYLOCK 38#ifdef WPS_KEYLOCK
38void display_keylock_text(bool locked); 39void display_keylock_text(bool locked);
39void waitfor_nokey(void); 40void waitfor_nokey(void);
diff --git a/apps/gui/gwps.c b/apps/gui/gwps.c
index 52242d856e..bd7591fb37 100644
--- a/apps/gui/gwps.c
+++ b/apps/gui/gwps.c
@@ -734,6 +734,8 @@ static void wps_clear(struct wps_data *data )
734 data->img[i].display = false; 734 data->img[i].display = false;
735 data->img[i].always_display = false; 735 data->img[i].always_display = false;
736 } 736 }
737 data->wps_sb_tag = false;
738 data->show_sb_on_wps = false;
737} 739}
738#else 740#else
739#define wps_clear(a) 741#define wps_clear(a)
@@ -764,7 +766,7 @@ bool wps_data_load(struct wps_data *wps_data,
764 wps_clear(wps_data); 766 wps_clear(wps_data);
765 strncpy(wps_data->format_buffer, buf, sizeof(wps_data->format_buffer)); 767 strncpy(wps_data->format_buffer, buf, sizeof(wps_data->format_buffer));
766 wps_data->format_buffer[sizeof(wps_data->format_buffer) - 1] = 0; 768 wps_data->format_buffer[sizeof(wps_data->format_buffer) - 1] = 0;
767 gui_wps_format(wps_data, NULL, 0); 769 gui_wps_format(wps_data);
768 return true; 770 return true;
769 } 771 }
770 else 772 else
@@ -798,16 +800,34 @@ bool wps_data_load(struct wps_data *wps_data,
798 800
799 if (fd >= 0) 801 if (fd >= 0)
800 { 802 {
801 int numread = read(fd, wps_data->format_buffer, 803 unsigned int start = 0;
802 sizeof(wps_data->format_buffer) - 1); 804
803 805 wps_reset(wps_data);
804 if (numread > 0)
805 {
806#ifdef HAVE_LCD_BITMAP 806#ifdef HAVE_LCD_BITMAP
807 wps_clear(wps_data); 807 wps_data->img_buf_ptr = wps_data->img_buf; /* where in image buffer */
808
809 wps_data->img_buf_free = IMG_BUFSIZE; /* free space in image buffer */
808#endif 810#endif
809 wps_data->format_buffer[numread] = 0; 811 while( ( read_line(fd, &wps_data->format_buffer[start],
810 gui_wps_format(wps_data, buf, bmpdirlen); 812 sizeof(wps_data->format_buffer)-start) ) > 0 )
813 {
814 if(!wps_data_preload_tags(wps_data,
815 &wps_data->format_buffer[start],
816 buf, bmpdirlen))
817 {
818 start += strlen(&wps_data->format_buffer[start]);
819
820 if (start < sizeof(wps_data->format_buffer) - 1)
821 {
822 wps_data->format_buffer[start++] = '\n';
823 wps_data->format_buffer[start] = 0;
824 }
825 }
826 }
827
828 if (start > 0)
829 {
830 gui_wps_format(wps_data);
811 } 831 }
812 832
813 close(fd); 833 close(fd);
@@ -853,7 +873,7 @@ bool wps_data_load(struct wps_data *wps_data,
853 } 873 }
854 wps_data->wps_loaded = true; 874 wps_data->wps_loaded = true;
855 875
856 return numread > 0; 876 return start > 0;
857 } 877 }
858 } 878 }
859 879
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 66199bcfc4..4072e17cfa 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -255,6 +255,8 @@ struct wps_data
255#ifdef HAVE_LCD_BITMAP 255#ifdef HAVE_LCD_BITMAP
256 struct gui_img img[MAX_IMAGES]; 256 struct gui_img img[MAX_IMAGES];
257 unsigned char img_buf[IMG_BUFSIZE]; 257 unsigned char img_buf[IMG_BUFSIZE];
258 unsigned char* img_buf_ptr;
259 int img_buf_free;
258 bool wps_sb_tag; 260 bool wps_sb_tag;
259 bool show_sb_on_wps; 261 bool show_sb_on_wps;
260#endif 262#endif