summaryrefslogtreecommitdiff
path: root/apps/plugins/databox/databox.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/databox/databox.c')
-rw-r--r--apps/plugins/databox/databox.c395
1 files changed, 0 insertions, 395 deletions
diff --git a/apps/plugins/databox/databox.c b/apps/plugins/databox/databox.c
deleted file mode 100644
index 25836a7f07..0000000000
--- a/apps/plugins/databox/databox.c
+++ /dev/null
@@ -1,395 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Björn Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "databox.h"
20
21PLUGIN_HEADER
22
23/* variable button definitions */
24#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
25 (CONFIG_KEYPAD == IRIVER_H300_PAD)
26#define DBX_SELECT BUTTON_SELECT
27#define DBX_STOP BUTTON_OFF
28#elif CONFIG_KEYPAD == RECORDER_PAD
29#define DBX_SELECT BUTTON_PLAY
30#define DBX_STOP BUTTON_OFF
31#elif CONFIG_KEYPAD == ONDIO_PAD
32#define DBX_SELECT BUTTON_MENU
33#define DBX_STOP BUTTON_OFF
34#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
35 (CONFIG_KEYPAD == IPOD_3G_PAD)
36#define DBX_SELECT BUTTON_SELECT
37#define DBX_STOP BUTTON_MENU
38#elif CONFIG_KEYPAD == PLAYER_PAD
39#define DBX_SELECT BUTTON_PLAY
40#define DBX_STOP BUTTON_STOP
41#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
42#define DBX_SELECT BUTTON_SELECT
43#define DBX_STOP BUTTON_PLAY
44#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
45#define DBX_SELECT BUTTON_SELECT
46#define DBX_STOP BUTTON_PLAY
47#elif CONFIG_KEYPAD == GIGABEAT_PAD
48#define DBX_SELECT BUTTON_SELECT
49#define DBX_STOP BUTTON_A
50#elif CONFIG_KEYPAD == IRIVER_H10_PAD
51#define DBX_SELECT BUTTON_REW
52#define DBX_STOP BUTTON_PLAY
53#elif CONFIG_KEYPAD == SANSA_E200_PAD
54#define DBX_SELECT BUTTON_SELECT
55#define DBX_STOP BUTTON_POWER
56#endif
57
58#define MAX_TOKENS 70
59
60/* here is a global api struct pointer. while not strictly necessary,
61 it's nice not to have to pass the api pointer in all function calls
62 in the plugin */
63struct plugin_api* rb;
64struct token tokenbuf[MAX_TOKENS];
65
66struct print printing;
67struct editor editor;
68struct editing editing;
69
70extern int acceptedmask;
71
72void databox_init(void) {
73#ifdef HAVE_LCD_BITMAP
74 printing.fontfixed = rb->font_get(FONT_SYSFIXED);
75 rb->lcd_setfont(FONT_SYSFIXED);
76 printing.font_w = printing.fontfixed->maxwidth;
77 printing.font_h = printing.fontfixed->height;
78#endif
79 printing.line=0;
80 printing.position=0;
81 editor.editingmode = INVALID_MARK;
82 editor.token = tokenbuf;
83}
84
85#ifdef HAVE_LCD_BITMAP
86void print(char *word, int invert) {
87 int strlen=rb->strlen(word), newpos=printing.position+strlen+1;
88 if(newpos*printing.font_w>LCD_WIDTH) {
89 printing.line++;
90 printing.position=0;
91 newpos=printing.position+strlen+1;
92 }
93 /* Fixme: the display code needs to keep the current item visible instead of
94 * just displaying the first items. */
95 if (printing.font_h*printing.line >= LCD_HEIGHT)
96 return;
97 rb->lcd_putsxy(printing.font_w*printing.position,printing.font_h*printing.line,word);
98 if(invert) {
99 rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
100 rb->lcd_fillrect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h);
101 rb->lcd_set_drawmode(DRMODE_SOLID);
102 }
103 rb->lcd_update_rect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h);
104 printing.position=newpos;
105}
106#else /* HAVE_LCD_CHARCELLS */
107#define MARKER_LEFT 0x81
108#define MARKER_RIGHT 0x82
109void print(char *word, int invert) {
110 int strlen = rb->strlen(word);
111 int newpos = printing.position + strlen + (invert ? 3 : 1);
112 if (newpos > 11) {
113 printing.line++;
114 printing.position = 0;
115 newpos = printing.position + strlen + (invert ? 3 : 1);
116 }
117 /* Fixme: the display code needs to keep the current item visible instead of
118 * just displaying the first items. */
119 if (printing.line >= 2)
120 return;
121 if (invert) {
122 rb->lcd_putc(printing.position, printing.line, MARKER_LEFT);
123 rb->lcd_puts(printing.position + 1, printing.line, word);
124 rb->lcd_putc(printing.position + strlen + 1, printing.line, MARKER_RIGHT);
125 }
126 else
127 rb->lcd_puts(printing.position, printing.line, word);
128 printing.position = newpos;
129}
130#endif
131
132void displaytstream(struct token *token) {
133 int index=0;
134 while(token[index].kind!=TOKEN_EOF||index==editor.currentindex) {
135 if(editing.selecting&&index==editor.currentindex) {
136 print(tokentypetostring(editing.selection_candidates[editing.currentselection]),1);
137 }
138 else
139 print(tokentostring(&token[index]),index==editor.currentindex ? 1 : 0);
140 index++;
141 }
142}
143
144void buildchoices(int mask) {
145 int i;
146 for(i=0;i<20;i++)
147 editing.selection_candidates[i]=-1;
148 i=0;
149 if(editing.selecting&&
150 editing.old_token.kind!=TOKEN_EOF &&
151 editing.old_token.kind!=TOKEN_INVALID) {
152 editing.selection_candidates[i++]=TOKEN_EDIT;
153 }
154 if((mask&ACCEPT_EOF)&&editor.valid)
155 editing.selection_candidates[i++]=TOKEN_EOF;
156 if(mask&ACCEPT_NOT)
157 editing.selection_candidates[i++]=TOKEN_NOT;
158 if(mask&ACCEPT_BOOLOP) {
159 editing.selection_candidates[i++]=TOKEN_AND;
160 editing.selection_candidates[i++]=TOKEN_OR;
161 }
162 if(mask&ACCEPT_NUMOP) {
163 editing.selection_candidates[i++]=TOKEN_GT;
164 editing.selection_candidates[i++]=TOKEN_GTE;
165 editing.selection_candidates[i++]=TOKEN_LT;
166 editing.selection_candidates[i++]=TOKEN_LTE;
167 editing.selection_candidates[i++]=TOKEN_NE;
168 editing.selection_candidates[i++]=TOKEN_EQ;
169 }
170 if(mask&ACCEPT_STROP) {
171 editing.selection_candidates[i++]=TOKEN_CONTAINS;
172 editing.selection_candidates[i++]=TOKEN_EQUALS;
173 editing.selection_candidates[i++]=TOKEN_STARTSWITH;
174 editing.selection_candidates[i++]=TOKEN_ENDSWITH;
175 }
176 if(mask&ACCEPT_LPAREN) {
177 editing.selection_candidates[i++]=TOKEN_LPAREN;
178 }
179 if(mask&ACCEPT_RPAREN) {
180 editing.selection_candidates[i++]=TOKEN_RPAREN;
181 }
182 if(mask&ACCEPT_NUMARG) {
183 editing.selection_candidates[i++]=TOKEN_NUM;
184 editing.selection_candidates[i++]=TOKEN_YEAR;
185 editing.selection_candidates[i++]=TOKEN_RATING;
186 editing.selection_candidates[i++]=TOKEN_PLAYCOUNT;
187 editing.selection_candidates[i++]=TOKEN_AUTORATING;
188 editing.selection_candidates[i++]=TOKEN_TRACKNUM;
189 editing.selection_candidates[i++]=TOKEN_PLAYTIME;
190 editing.selection_candidates[i++]=TOKEN_SAMPLERATE;
191 editing.selection_candidates[i++]=TOKEN_BITRATE;
192 }
193 if(mask&ACCEPT_STRARG) {
194 editing.selection_candidates[i++]=TOKEN_STRING;
195 editing.selection_candidates[i++]=TOKEN_TITLE;
196 editing.selection_candidates[i++]=TOKEN_ARTIST;
197 editing.selection_candidates[i++]=TOKEN_ALBUM;
198 editing.selection_candidates[i++]=TOKEN_GENRE;
199 editing.selection_candidates[i++]=TOKEN_FILENAME;
200 }
201 editing.selectionmax=i;
202}
203
204/* returns tokencount or 0 if error */
205int readtstream(char *filename,struct token *token,int max) {
206 int tokencount=0;
207 int filelen,i;
208 int fd;
209 rb->memset(token,0,max*sizeof(struct token));
210 fd=rb->open(filename,O_RDONLY);
211 if(fd>=0) {
212 filelen=rb->filesize(fd);
213 if(filelen>0) {
214 if(filelen % sizeof(struct token)) {
215 rb->splash(HZ*2,true,"Filesize not a multiple of sizeof(struct token)");
216 rb->close(fd);
217 return 0;
218 }
219 tokencount=(filelen/sizeof(struct token))-1;
220 for(i=0;i<tokencount&&i<max;i++) {
221 rb->read(fd,&token[i],sizeof(struct token));
222 token[i].intvalue=BE32(token[i].intvalue);
223 }
224 }
225 rb->close(fd);
226 }
227 return tokencount;
228}
229
230int writetstream(char *filename,struct token *token) {
231 int fd,i;
232 fd=rb->open(filename,O_WRONLY|O_CREAT|O_TRUNC);
233 if(fd<0)
234 return 0;
235 i=0;
236 while(token[i].kind!=TOKEN_EOF) {
237 token[i].intvalue=BE32(token[i].intvalue);
238 rb->write(fd,&token[i++],sizeof(struct token));
239 }
240 token[i].intvalue=BE32(token[i].intvalue);
241 rb->write(fd,&token[i++],sizeof(struct token));
242 rb->close(fd);
243 return i;
244}
245
246/* this is the plugin entry point */
247enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
248{
249 int button,done=0,abort=0;
250 char filename[100],buf[100];
251 /* if you don't use the parameter, you can do like
252 this to avoid the compiler warning about it */
253 (void)parameter;
254
255 /* if you are using a global api pointer, don't forget to copy it!
256 otherwise you will get lovely "I04: IllInstr" errors... :-) */
257 rb = api;
258
259 /* now go ahead and have fun! */
260 rb->splash(HZ*2, true, "Databox! Enter filename ^.^");
261 databox_init();
262 filename[0] = '\0';
263 if(rb->kbd_input(filename, sizeof filename)) {
264 rb->splash(HZ*2, true, "Cancelled...");
265 return PLUGIN_OK;
266 }
267 /* add / in front if omitted */
268 if(filename[0]!='/') {
269 rb->strncpy(buf+1,filename,sizeof(filename)-1);
270 buf[0]='/';
271 rb->strcpy(filename,buf);
272 }
273 /* add extension if omitted */
274 if(rb->strncasecmp(filename+rb->strlen(filename)-4,".rsp",4)) {
275 rb->strcat(filename,".rsp");
276 }
277 editor.currentindex=editor.tokencount
278 =readtstream(filename,editor.token,MAX_TOKENS);
279 editing.currentselection=0;
280 editing.selecting=0;
281 if(editor.currentindex==0) {
282 editor.valid=check_tokenstream(editor.token,editor.editingmode);
283 check_accepted(editor.token,editor.currentindex);
284 editing.selecting=1;
285 buildchoices(acceptedmask);
286 rb->memset(&editing.old_token,0,sizeof(struct token));
287 }
288 do {
289#ifdef HAVE_LCD_BITMAP
290 rb->lcd_setfont(FONT_SYSFIXED);
291#endif
292 rb->lcd_clear_display();
293 printing.line=0;
294 printing.position=0;
295 displaytstream(editor.token);
296 editor.valid=check_tokenstream(editor.token,editor.editingmode);
297 check_accepted(editor.token,editor.currentindex);
298#ifdef HAVE_LCD_BITMAP
299 rb->lcd_update();
300#endif
301 button = rb->button_get(true);
302 switch (button) {
303 case BUTTON_LEFT:
304#ifdef BUTTON_DOWN
305 case BUTTON_DOWN:
306#endif
307 if (editing.selecting)
308 editing.currentselection = (editing.currentselection +
309 editing.selectionmax-1) % editing.selectionmax;
310 else
311 editor.currentindex = (editor.currentindex + editor.tokencount)
312 % (editor.tokencount+1);
313 break;
314
315 case BUTTON_RIGHT:
316#ifdef BUTTON_UP
317 case BUTTON_UP:
318#endif
319 if (editing.selecting)
320 editing.currentselection = (editing.currentselection+1)
321 % editing.selectionmax;
322 else
323 editor.currentindex = (editor.currentindex+1)
324 % (editor.tokencount+1);
325 break;
326
327 case DBX_SELECT:
328 if(editing.selecting) {
329 buildtoken(editing.selection_candidates[editing.currentselection],
330 &editor.token[editor.currentindex]);
331 editing.selecting=0;
332 if(editor.token[editor.currentindex].kind==TOKEN_EOF)
333 done=1;
334 else if(editor.currentindex==editor.tokencount) {
335 editor.tokencount++;
336 editor.currentindex++;
337 editor.valid=check_tokenstream(editor.token,editor.editingmode);
338 check_accepted(editor.token,editor.currentindex);
339 editing.selecting=1;
340 editing.currentselection=0;
341 buildchoices(acceptedmask);
342 rb->memcpy(&editing.old_token,&editor.token[editor.currentindex],
343 sizeof(struct token));
344 }
345 }
346 else {
347 editing.selecting=1;
348 editing.currentselection=0;
349 buildchoices(acceptedmask);
350 rb->memcpy(&editing.old_token,&editor.token[editor.currentindex],
351 sizeof(struct token));
352 }
353 break;
354
355 case DBX_STOP:
356 if(editing.selecting) {
357 rb->memcpy(&editor.token[editor.currentindex],&editing.old_token,
358 sizeof(struct token));
359 editing.selecting=0;
360 }
361 else
362 abort=1;
363 break;
364
365 default:
366 if (rb->default_event_handler(button) == SYS_USB_CONNECTED) {
367#ifdef HAVE_LCD_BITMAP
368 rb->lcd_setfont(FONT_UI);
369#endif
370 return PLUGIN_USB_CONNECTED;
371 }
372 break;
373 }
374 } while (!done&&!abort);
375#ifdef HAVE_LCD_BITMAP
376 rb->lcd_setfont(FONT_UI);
377#endif
378 if(abort)
379 return PLUGIN_OK;
380
381 if(editor.valid&&editor.tokencount>0) {
382 if(writetstream(filename,editor.token)) {
383 rb->splash(HZ*2,true,"Wrote file succesfully ^.^");
384 return PLUGIN_OK;
385 }
386 else {
387 rb->splash(HZ*2,true,"Error while writing file :(");
388 return PLUGIN_ERROR;
389 }
390 }
391 else {
392 rb->splash(HZ*2,true,"Search query invalid, not saving.");
393 return PLUGIN_OK;
394 }
395}