diff options
Diffstat (limited to 'apps/plugins/databox/databox.c')
-rw-r--r-- | apps/plugins/databox/databox.c | 395 |
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 | |||
21 | PLUGIN_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 */ | ||
63 | struct plugin_api* rb; | ||
64 | struct token tokenbuf[MAX_TOKENS]; | ||
65 | |||
66 | struct print printing; | ||
67 | struct editor editor; | ||
68 | struct editing editing; | ||
69 | |||
70 | extern int acceptedmask; | ||
71 | |||
72 | void 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 | ||
86 | void 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 | ||
109 | void 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 | |||
132 | void 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 | |||
144 | void 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 */ | ||
205 | int 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 | |||
230 | int 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 */ | ||
247 | enum 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 | } | ||