1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
23 #include <timefuncs.h>
43 #include "mp3_playback.h"
44 #include "backlight.h"
47 #include "sound_menu.h"
49 #include "powermgmt.h"
56 #if (CONFIG_CODEC == SWCODEC)
57 #include "pcm_playback.h"
61 #ifdef CONFIG_CHARGING
65 #ifdef HAVE_LCD_BITMAP
66 #include "peakmeter.h"
72 #ifdef HAVE_REMOTE_LCD
73 #include "lcd-remote.h"
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
);
83 #define sim_plugin_close(x)
84 extern unsigned char pluginbuf
[];
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
= {
101 #ifdef HAVE_LCD_CHARCELLS
103 lcd_get_locked_pattern
,
122 lcd_mono_bitmap_part
,
133 lcd_bitmap_transparent_part
,
134 lcd_bitmap_transparent
,
141 lcd_puts_scroll_style
,
142 &lcd_framebuffer
[0][0],
154 backlight_set_timeout
,
156 #ifdef HAVE_REMOTE_LCD
158 lcd_remote_set_contrast
,
159 lcd_remote_clear_display
,
161 lcd_remote_puts_scroll
,
162 lcd_remote_stop_scroll
,
163 lcd_remote_set_drawmode
,
164 lcd_remote_get_drawmode
,
166 lcd_remote_getstringsize
,
167 lcd_remote_drawpixel
,
173 lcd_remote_mono_bitmap_part
,
174 lcd_remote_mono_bitmap
,
176 lcd_remote_puts_style
,
177 lcd_remote_puts_scroll_style
,
178 &lcd_remote_framebuffer
[0][0],
180 lcd_remote_update_rect
,
183 remote_backlight_off
,
186 {&screens
[SCREEN_MAIN
], &screens
[SCREEN_REMOTE
]},
188 {&screens
[SCREEN_MAIN
]},
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
,
199 #if defined(HAVE_LCD_COLOR) && !defined(SIMULATOR)
204 gui_synclist_set_nb_items
,
205 gui_synclist_set_icon_callback
,
206 gui_synclist_get_nb_items
,
207 gui_synclist_get_sel_pos
,
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
,
218 #ifdef HAVE_LCD_BITMAP
219 gui_synclist_scroll_right
,
220 gui_synclist_scroll_left
,
222 gui_synclist_do_button
,
229 #ifdef HAS_BUTTON_HOLD
234 (open_func
)PREFIX(open
),
238 (creat_func
)PREFIX(creat
),
264 default_event_handler
,
265 default_event_handler_ex
,
268 reset_poweroff_timer
,
272 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
292 /* special simulator hooks */
293 #if defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8
295 sim_lcd_ex_update_rect
,
299 /* strings and memory */
340 #if CONFIG_CODEC != SWCODEC
343 #if CONFIG_CODEC == SWCODEC
351 #if CONFIG_CODEC == SWCODEC
355 /* playback control */
366 audio_has_changed_track
,
368 audio_flush_and_reload_tracks
,
370 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
371 mpeg_get_last_header
,
373 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) || \
374 (CONFIG_CODEC == SWCODEC)
378 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
379 /* MAS communication */
384 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
391 #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
411 /* action handling */
414 action_signalscreenchange
,
424 #ifdef CONFIG_CHARGING
426 # if CONFIG_CHARGING == CHARGING_MONITOR
430 #ifdef HAVE_USB_POWER
442 plugin_get_audio_buffer
,
444 #if defined(DEBUG) || defined(SIMULATOR)
447 #ifdef ROCKBOX_HAS_LOGF
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
,
460 #ifdef HAVE_LCD_BITMAP
462 screen_dump_set_hook
,
467 /* new stuff at the end, sort into place next time
468 the API gets incompatible */
471 #ifdef HAVE_WHEEL_POSITION
478 int plugin_load(const char* plugin
, void* parameter
)
481 struct plugin_header
*hdr
;
488 #ifdef HAVE_LCD_BITMAP
491 #ifdef HAVE_REMOTE_LCD
494 #ifdef HAVE_LCD_COLOR
495 fb_data
* old_backdrop
;
498 if (pfn_tsr_exit
!= NULL
) /* if we have a resident old plugin: */
500 pfn_tsr_exit(); /* force it to exit now */
502 plugin_loaded
= false;
505 gui_syncsplash(0, true, str(LANG_WAIT
));
508 hdr
= sim_plugin_load((char *)plugin
, &pd
);
510 gui_syncsplash(HZ
*2, true, str(LANG_PLUGIN_CANT_OPEN
), plugin
);
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
));
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
));
527 fd
= open(plugin
, O_RDONLY
);
529 gui_syncsplash(HZ
*2, true, str(LANG_PLUGIN_CANT_OPEN
), plugin
);
533 readsize
= read(fd
, pluginbuf
, PLUGIN_BUFFER_SIZE
);
537 gui_syncsplash(HZ
*2, true, str(LANG_READ_FAILED
), plugin
);
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
));
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
));
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
);
561 plugin_loaded
= true;
563 #ifdef HAVE_LCD_BITMAP
564 xm
= lcd_getxmargin();
565 ym
= lcd_getymargin();
567 #ifdef HAVE_LCD_COLOR
568 old_backdrop
= lcd_get_backdrop();
569 lcd_set_backdrop(NULL
);
573 #else /* !HAVE_LCD_BITMAP */
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();
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
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
);
599 lcd_set_drawinfo(DRMODE_SOLID
, LCD_DEFAULT_FG
, LCD_DEFAULT_BG
);
601 #else /* LCD_DEPTH == 1 */
602 lcd_set_drawmode(DRMODE_SOLID
);
603 #endif /* LCD_DEPTH */
604 /* restore margins */
605 lcd_setmargins(xm
,ym
);
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
);
615 lcd_remote_set_drawmode(DRMODE_SOLID
);
617 lcd_remote_setmargins(rxm
, rym
);
618 lcd_remote_clear_display();
622 if (pfn_tsr_exit
== NULL
)
623 plugin_loaded
= false;
625 sim_plugin_close(pd
);
631 case PLUGIN_USB_CONNECTED
:
632 return PLUGIN_USB_CONNECTED
;
635 gui_syncsplash(HZ
*2, true, str(LANG_PLUGIN_ERROR
));
638 action_signalscreenchange();
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
)
650 if (plugin_size
>= PLUGIN_BUFFER_SIZE
)
653 *buffer_size
= PLUGIN_BUFFER_SIZE
-plugin_size
;
654 buffer_pos
= plugin_size
;
658 *buffer_size
= PLUGIN_BUFFER_SIZE
;
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
)
670 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
671 *buffer_size
= audiobufend
- 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 */