Update several codec Makefiles so that the codec libs build again on Coldfire targets...
[Rockbox.git] / apps / plugin.c
blobbc8419d313d5ab81b937c61b5cf37fbe85fb1aad
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Bj�n Stenberg
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include <stdbool.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <atoi.h>
23 #include <timefuncs.h>
24 #include <ctype.h>
25 #include "debug.h"
26 #include "button.h"
27 #include "lcd.h"
28 #include "dir.h"
29 #include "file.h"
30 #include "kernel.h"
31 #include "usb.h"
32 #include "sprintf.h"
33 #include "logf.h"
34 #include "screens.h"
35 #include "misc.h"
36 #include "i2c.h"
37 #include "mas.h"
38 #include "plugin.h"
39 #include "lang.h"
40 #include "keyboard.h"
41 #include "mpeg.h"
42 #include "buffer.h"
43 #include "mp3_playback.h"
44 #include "backlight.h"
45 #include "ata.h"
46 #include "talk.h"
47 #include "sound_menu.h"
48 #include "mp3data.h"
49 #include "powermgmt.h"
50 #include "system.h"
51 #include "timer.h"
52 #include "sound.h"
53 #include "database.h"
54 #include "splash.h"
55 #include "list.h"
56 #if (CONFIG_CODEC == SWCODEC)
57 #include "pcm_playback.h"
58 #include "dsp.h"
59 #endif
61 #ifdef CONFIG_CHARGING
62 #include "power.h"
63 #endif
65 #ifdef HAVE_LCD_BITMAP
66 #include "peakmeter.h"
67 #include "widgets.h"
68 #include "bmp.h"
69 #include "bidi.h"
70 #endif
72 #ifdef HAVE_REMOTE_LCD
73 #include "lcd-remote.h"
74 #endif
76 #ifdef SIMULATOR
77 static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE];
78 void *sim_plugin_load(char *plugin, void **pd);
79 void sim_plugin_close(void *pd);
80 void sim_lcd_ex_init(int shades, unsigned long (*getpixel)(int, int));
81 void sim_lcd_ex_update_rect(int x, int y, int width, int height);
82 #else
83 #define sim_plugin_close(x)
84 extern unsigned char pluginbuf[];
85 #include "bitswap.h"
86 #endif
88 /* for actual plugins only, not for codecs */
89 static bool plugin_loaded = false;
90 static int plugin_size = 0;
91 static void (*pfn_tsr_exit)(void) = NULL; /* TSR exit callback */
93 static const struct plugin_api rockbox_api = {
95 /* lcd */
96 lcd_set_contrast,
97 lcd_clear_display,
98 lcd_puts,
99 lcd_puts_scroll,
100 lcd_stop_scroll,
101 #ifdef HAVE_LCD_CHARCELLS
102 lcd_define_pattern,
103 lcd_get_locked_pattern,
104 lcd_unlock_pattern,
105 lcd_putc,
106 lcd_put_cursor,
107 lcd_remove_cursor,
108 PREFIX(lcd_icon),
109 lcd_double_height,
110 #else
111 lcd_setmargins,
112 lcd_set_drawmode,
113 lcd_get_drawmode,
114 lcd_setfont,
115 lcd_getstringsize,
116 lcd_drawpixel,
117 lcd_drawline,
118 lcd_hline,
119 lcd_vline,
120 lcd_drawrect,
121 lcd_fillrect,
122 lcd_mono_bitmap_part,
123 lcd_mono_bitmap,
124 #if LCD_DEPTH > 1
125 lcd_set_foreground,
126 lcd_get_foreground,
127 lcd_set_background,
128 lcd_get_background,
129 lcd_bitmap_part,
130 lcd_bitmap,
131 #endif
132 #if LCD_DEPTH == 16
133 lcd_bitmap_transparent_part,
134 lcd_bitmap_transparent,
135 #endif
136 bidi_l2v,
137 font_get_bits,
138 font_load,
139 lcd_putsxy,
140 lcd_puts_style,
141 lcd_puts_scroll_style,
142 &lcd_framebuffer[0][0],
143 lcd_blit,
144 lcd_update,
145 lcd_update_rect,
146 scrollbar,
147 checkbox,
148 font_get,
149 font_getstringsize,
150 font_get_width,
151 #endif
152 backlight_on,
153 backlight_off,
154 backlight_set_timeout,
155 gui_syncsplash,
156 #ifdef HAVE_REMOTE_LCD
157 /* remote lcd */
158 lcd_remote_set_contrast,
159 lcd_remote_clear_display,
160 lcd_remote_puts,
161 lcd_remote_puts_scroll,
162 lcd_remote_stop_scroll,
163 lcd_remote_set_drawmode,
164 lcd_remote_get_drawmode,
165 lcd_remote_setfont,
166 lcd_remote_getstringsize,
167 lcd_remote_drawpixel,
168 lcd_remote_drawline,
169 lcd_remote_hline,
170 lcd_remote_vline,
171 lcd_remote_drawrect,
172 lcd_remote_fillrect,
173 lcd_remote_mono_bitmap_part,
174 lcd_remote_mono_bitmap,
175 lcd_remote_putsxy,
176 lcd_remote_puts_style,
177 lcd_remote_puts_scroll_style,
178 &lcd_remote_framebuffer[0][0],
179 lcd_remote_update,
180 lcd_remote_update_rect,
182 remote_backlight_on,
183 remote_backlight_off,
184 #endif
185 #if NB_SCREENS == 2
186 {&screens[SCREEN_MAIN], &screens[SCREEN_REMOTE]},
187 #else
188 {&screens[SCREEN_MAIN]},
189 #endif
190 #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
191 lcd_remote_set_foreground,
192 lcd_remote_get_foreground,
193 lcd_remote_set_background,
194 lcd_remote_get_background,
195 lcd_remote_bitmap_part,
196 lcd_remote_bitmap,
197 #endif
199 #if defined(HAVE_LCD_COLOR) && !defined(SIMULATOR)
200 lcd_yuv_blit,
201 #endif
202 /* list */
203 gui_synclist_init,
204 gui_synclist_set_nb_items,
205 gui_synclist_set_icon_callback,
206 gui_synclist_get_nb_items,
207 gui_synclist_get_sel_pos,
208 gui_synclist_draw,
209 gui_synclist_select_item,
210 gui_synclist_select_next,
211 gui_synclist_select_previous,
212 gui_synclist_select_next_page,
213 gui_synclist_select_previous_page,
214 gui_synclist_add_item,
215 gui_synclist_del_item,
216 gui_synclist_limit_scroll,
217 gui_synclist_flash,
218 #ifdef HAVE_LCD_BITMAP
219 gui_synclist_scroll_right,
220 gui_synclist_scroll_left,
221 #endif
222 gui_synclist_do_button,
224 /* button */
225 button_get,
226 button_get_w_tmo,
227 button_status,
228 button_clear_queue,
229 #ifdef HAS_BUTTON_HOLD
230 button_hold,
231 #endif
233 /* file */
234 (open_func)PREFIX(open),
235 close,
236 (read_func)read,
237 PREFIX(lseek),
238 (creat_func)PREFIX(creat),
239 (write_func)write,
240 PREFIX(remove),
241 PREFIX(rename),
242 PREFIX(ftruncate),
243 PREFIX(filesize),
244 fdprintf,
245 read_line,
246 settings_parseline,
247 #ifndef SIMULATOR
248 ata_sleep,
249 ata_disk_is_active,
250 #endif
251 reload_directory,
253 /* dir */
254 PREFIX(opendir),
255 PREFIX(closedir),
256 PREFIX(readdir),
257 PREFIX(mkdir),
258 PREFIX(rmdir),
260 /* kernel/ system */
261 PREFIX(sleep),
262 yield,
263 &current_tick,
264 default_event_handler,
265 default_event_handler_ex,
266 create_thread,
267 remove_thread,
268 reset_poweroff_timer,
269 #ifndef SIMULATOR
270 system_memory_guard,
271 &cpu_frequency,
272 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
273 cpu_boost,
274 #endif
275 timer_register,
276 timer_unregister,
277 timer_set_period,
278 #endif
279 queue_init,
280 queue_delete,
281 queue_post,
282 queue_wait_w_tmo,
283 usb_acknowledge,
284 #ifdef RB_PROFILE
285 profile_thread,
286 profstop,
287 profile_func_enter,
288 profile_func_exit,
289 #endif
291 #ifdef SIMULATOR
292 /* special simulator hooks */
293 #if defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8
294 sim_lcd_ex_init,
295 sim_lcd_ex_update_rect,
296 #endif
297 #endif
299 /* strings and memory */
300 snprintf,
301 vsnprintf,
302 strcpy,
303 strncpy,
304 strlen,
305 strrchr,
306 strcmp,
307 strncmp,
308 strcasecmp,
309 strncasecmp,
310 memset,
311 memcpy,
312 memmove,
313 _ctype_,
314 atoi,
315 strchr,
316 strcat,
317 memchr,
318 memcmp,
319 strcasestr,
320 /* unicode stuff */
321 utf8decode,
322 iso_decode,
323 utf16LEdecode,
324 utf16BEdecode,
325 utf8encode,
326 utf8length,
327 utf8seek,
329 /* sound */
330 sound_set,
331 set_sound,
333 sound_min,
334 sound_max,
335 #ifndef SIMULATOR
336 mp3_play_data,
337 mp3_play_pause,
338 mp3_play_stop,
339 mp3_is_playing,
340 #if CONFIG_CODEC != SWCODEC
341 bitswap,
342 #endif
343 #if CONFIG_CODEC == SWCODEC
344 pcm_play_data,
345 pcm_play_stop,
346 pcm_set_frequency,
347 pcm_is_playing,
348 pcm_play_pause,
349 #endif
350 #endif
351 #if CONFIG_CODEC == SWCODEC
352 pcm_calculate_peaks,
353 #endif
355 /* playback control */
356 PREFIX(audio_play),
357 audio_stop,
358 audio_pause,
359 audio_resume,
360 audio_next,
361 audio_prev,
362 audio_ff_rewind,
363 audio_next_track,
364 playlist_amount,
365 audio_status,
366 audio_has_changed_track,
367 audio_current_track,
368 audio_flush_and_reload_tracks,
369 audio_get_file_pos,
370 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
371 mpeg_get_last_header,
372 #endif
373 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) || \
374 (CONFIG_CODEC == SWCODEC)
375 sound_set_pitch,
376 #endif
378 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
379 /* MAS communication */
380 mas_readmem,
381 mas_writemem,
382 mas_readreg,
383 mas_writereg,
384 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
385 mas_codec_writereg,
386 mas_codec_readreg,
387 i2c_begin,
388 i2c_end,
389 i2c_write,
390 #endif
391 #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
393 /* menu */
394 menu_init,
395 menu_exit,
396 menu_show,
397 menu_run,
398 menu_cursor,
399 menu_description,
400 menu_delete,
401 menu_count,
402 menu_moveup,
403 menu_movedown,
404 menu_draw,
405 menu_insert,
406 menu_set_cursor,
407 set_option,
408 set_int,
409 set_bool,
411 /* action handling */
412 get_custom_action,
413 get_action,
414 action_signalscreenchange,
415 action_userabort,
417 /* power */
418 battery_level,
419 battery_level_safe,
420 battery_time,
421 #ifndef SIMULATOR
422 battery_voltage,
423 #endif
424 #ifdef CONFIG_CHARGING
425 charger_inserted,
426 # if CONFIG_CHARGING == CHARGING_MONITOR
427 charging_state,
428 # endif
429 #endif
430 #ifdef HAVE_USB_POWER
431 usb_powered,
432 #endif
434 /* misc */
435 srand,
436 rand,
437 (qsort_func)qsort,
438 kbd_input,
439 get_time,
440 set_time,
441 plugin_get_buffer,
442 plugin_get_audio_buffer,
443 plugin_tsr,
444 #if defined(DEBUG) || defined(SIMULATOR)
445 debugf,
446 #endif
447 #ifdef ROCKBOX_HAS_LOGF
448 logf,
449 #endif
450 &global_settings,
451 mp3info,
452 count_mp3_frames,
453 create_xing_header,
454 find_next_frame,
455 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
456 peak_meter_scale_value,
457 peak_meter_set_use_dbfs,
458 peak_meter_get_use_dbfs,
459 #endif
460 #ifdef HAVE_LCD_BITMAP
461 read_bmp_file,
462 screen_dump_set_hook,
463 #endif
464 show_logo,
465 tree_get_context,
467 /* new stuff at the end, sort into place next time
468 the API gets incompatible */
470 strtok_r,
471 #ifdef HAVE_WHEEL_POSITION
472 wheel_status,
473 wheel_send_events,
474 #endif
475 ata_spindown,
478 int plugin_load(const char* plugin, void* parameter)
480 int rc;
481 struct plugin_header *hdr;
482 #ifdef SIMULATOR
483 void *pd;
484 #else
485 int fd;
486 ssize_t readsize;
487 #endif
488 #ifdef HAVE_LCD_BITMAP
489 int xm, ym;
490 #endif
491 #ifdef HAVE_REMOTE_LCD
492 int rxm, rym;
493 #endif
494 #ifdef HAVE_LCD_COLOR
495 fb_data* old_backdrop;
496 #endif
498 if (pfn_tsr_exit != NULL) /* if we have a resident old plugin: */
500 pfn_tsr_exit(); /* force it to exit now */
501 pfn_tsr_exit = NULL;
502 plugin_loaded = false;
505 gui_syncsplash(0, true, str(LANG_WAIT));
507 #ifdef SIMULATOR
508 hdr = sim_plugin_load((char *)plugin, &pd);
509 if (pd == NULL) {
510 gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin);
511 return -1;
513 if (hdr == NULL
514 || hdr->magic != PLUGIN_MAGIC
515 || hdr->target_id != TARGET_ID) {
516 sim_plugin_close(pd);
517 gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_MODEL));
518 return -1;
520 if (hdr->api_version > PLUGIN_API_VERSION
521 || hdr->api_version < PLUGIN_MIN_API_VERSION) {
522 sim_plugin_close(pd);
523 gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_VERSION));
524 return -1;
526 #else
527 fd = open(plugin, O_RDONLY);
528 if (fd < 0) {
529 gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_CANT_OPEN), plugin);
530 return fd;
533 readsize = read(fd, pluginbuf, PLUGIN_BUFFER_SIZE);
534 close(fd);
536 if (readsize < 0) {
537 gui_syncsplash(HZ*2, true, str(LANG_READ_FAILED), plugin);
538 return -1;
540 hdr = (struct plugin_header *)pluginbuf;
542 if ((unsigned)readsize <= sizeof(struct plugin_header)
543 || hdr->magic != PLUGIN_MAGIC
544 || hdr->target_id != TARGET_ID
545 || hdr->load_addr != pluginbuf
546 || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE) {
547 gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_MODEL));
548 return -1;
550 if (hdr->api_version > PLUGIN_API_VERSION
551 || hdr->api_version < PLUGIN_MIN_API_VERSION) {
552 gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_WRONG_VERSION));
553 return -1;
555 plugin_size = hdr->end_addr - pluginbuf;
557 /* zero out bss area only, above guards end of pluginbuf */
558 memset(pluginbuf + readsize, 0, plugin_size - readsize);
559 #endif
561 plugin_loaded = true;
563 #ifdef HAVE_LCD_BITMAP
564 xm = lcd_getxmargin();
565 ym = lcd_getymargin();
566 lcd_setmargins(0,0);
567 #ifdef HAVE_LCD_COLOR
568 old_backdrop = lcd_get_backdrop();
569 lcd_set_backdrop(NULL);
570 #endif
571 lcd_clear_display();
572 lcd_update();
573 #else /* !HAVE_LCD_BITMAP */
574 lcd_clear_display();
575 #endif
577 #ifdef HAVE_REMOTE_LCD
578 rxm = lcd_remote_getxmargin();
579 rym = lcd_remote_getymargin();
580 lcd_remote_setmargins(0, 0);
581 lcd_remote_clear_display();
582 lcd_remote_update();
583 #endif
585 invalidate_icache();
587 rc = hdr->entry_point((struct plugin_api*) &rockbox_api, parameter);
588 /* explicitly casting the pointer here to avoid touching every plugin. */
590 button_clear_queue();
592 #ifdef HAVE_LCD_BITMAP
593 #if LCD_DEPTH > 1
594 #ifdef HAVE_LCD_COLOR
595 lcd_set_backdrop(old_backdrop);
596 lcd_set_drawinfo(DRMODE_SOLID, global_settings.fg_color,
597 global_settings.bg_color);
598 #else
599 lcd_set_drawinfo(DRMODE_SOLID, LCD_DEFAULT_FG, LCD_DEFAULT_BG);
600 #endif
601 #else /* LCD_DEPTH == 1 */
602 lcd_set_drawmode(DRMODE_SOLID);
603 #endif /* LCD_DEPTH */
604 /* restore margins */
605 lcd_setmargins(xm,ym);
606 lcd_clear_display();
607 lcd_update();
608 #endif /* HAVE_LCD_BITMAP */
610 #ifdef HAVE_REMOTE_LCD
611 #if LCD_REMOTE_DEPTH > 1
612 lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
613 LCD_REMOTE_DEFAULT_BG);
614 #else
615 lcd_remote_set_drawmode(DRMODE_SOLID);
616 #endif
617 lcd_remote_setmargins(rxm, rym);
618 lcd_remote_clear_display();
619 lcd_remote_update();
620 #endif
622 if (pfn_tsr_exit == NULL)
623 plugin_loaded = false;
625 sim_plugin_close(pd);
627 switch (rc) {
628 case PLUGIN_OK:
629 break;
631 case PLUGIN_USB_CONNECTED:
632 return PLUGIN_USB_CONNECTED;
634 default:
635 gui_syncsplash(HZ*2, true, str(LANG_PLUGIN_ERROR));
636 break;
638 action_signalscreenchange();
639 return PLUGIN_OK;
642 /* Returns a pointer to the portion of the plugin buffer that is not already
643 being used. If no plugin is loaded, returns the entire plugin buffer */
644 void* plugin_get_buffer(int* buffer_size)
646 int buffer_pos;
648 if (plugin_loaded)
650 if (plugin_size >= PLUGIN_BUFFER_SIZE)
651 return NULL;
653 *buffer_size = PLUGIN_BUFFER_SIZE-plugin_size;
654 buffer_pos = plugin_size;
656 else
658 *buffer_size = PLUGIN_BUFFER_SIZE;
659 buffer_pos = 0;
662 return &pluginbuf[buffer_pos];
665 /* Returns a pointer to the mp3 buffer.
666 Playback gets stopped, to avoid conflicts. */
667 void* plugin_get_audio_buffer(int* buffer_size)
669 audio_stop();
670 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
671 *buffer_size = audiobufend - audiobuf;
672 return audiobuf;
675 /* The plugin wants to stay resident after leaving its main function, e.g.
676 runs from timer or own thread. The callback is registered to later
677 instruct it to free its resources before a new plugin gets loaded. */
678 void plugin_tsr(void (*exit_callback)(void))
680 pfn_tsr_exit = exit_callback; /* remember the callback for later */