1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Björn 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 ****************************************************************************/
30 #include "backlight.h"
31 #include "sound_menu.h"
33 #include "powermgmt.h"
36 #include "option_select.h"
43 #ifdef HAVE_LCD_BITMAP
44 #include "scrollbar.h"
45 #include "peakmeter.h"
51 static unsigned char pluginbuf
[PLUGIN_BUFFER_SIZE
];
52 void *sim_plugin_load(char *plugin
, void **pd
);
53 void sim_plugin_close(void *pd
);
54 void sim_lcd_ex_init(int shades
, unsigned long (*getpixel
)(int, int));
55 void sim_lcd_ex_update_rect(int x
, int y
, int width
, int height
);
57 #define sim_plugin_close(x)
58 extern unsigned char pluginbuf
[];
62 /* for actual plugins only, not for codecs */
63 static bool plugin_loaded
= false;
64 static int plugin_size
= 0;
65 static bool (*pfn_tsr_exit
)(bool reenter
) = NULL
; /* TSR exit callback */
66 static char current_plugin
[MAX_PATH
];
68 char *plugin_get_current_filename(void);
70 extern struct thread_entry threads
[MAXTHREADS
];
72 static const struct plugin_api rockbox_api
= {
84 #ifdef HAVE_LCD_CHARCELLS
86 lcd_get_locked_pattern
,
94 &lcd_framebuffer
[0][0],
105 lcd_mono_bitmap_part
,
118 lcd_bitmap_transparent_part
,
119 lcd_bitmap_transparent
,
121 #if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) \
122 || defined (IRIVER_H10)
125 #elif (LCD_DEPTH < 4) && !defined(SIMULATOR)
128 #endif /* LCD_DEPTH */
130 lcd_puts_scroll_style
,
143 backlight_set_timeout
,
145 backlight_set_timeout_plugged
,
150 #ifdef HAVE_REMOTE_LCD
152 lcd_remote_set_contrast
,
153 lcd_remote_clear_display
,
154 lcd_remote_setmargins
,
156 lcd_remote_puts_scroll
,
157 lcd_remote_stop_scroll
,
158 lcd_remote_set_drawmode
,
159 lcd_remote_get_drawmode
,
161 lcd_remote_getstringsize
,
162 lcd_remote_drawpixel
,
168 lcd_remote_mono_bitmap_part
,
169 lcd_remote_mono_bitmap
,
171 lcd_remote_puts_style
,
172 lcd_remote_puts_scroll_style
,
173 &lcd_remote_framebuffer
[0][0],
175 lcd_remote_update_rect
,
178 remote_backlight_off
,
179 remote_backlight_set_timeout
,
181 remote_backlight_set_timeout_plugged
,
183 #endif /* HAVE_REMOTE_LCD */
185 {&screens
[SCREEN_MAIN
], &screens
[SCREEN_REMOTE
]},
187 {&screens
[SCREEN_MAIN
]},
189 #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
190 lcd_remote_set_foreground
,
191 lcd_remote_get_foreground
,
192 lcd_remote_set_background
,
193 lcd_remote_get_background
,
194 lcd_remote_bitmap_part
,
197 viewport_set_defaults
,
201 gui_synclist_set_nb_items
,
202 gui_synclist_set_icon_callback
,
203 gui_synclist_get_nb_items
,
204 gui_synclist_get_sel_pos
,
206 gui_synclist_select_item
,
207 gui_synclist_add_item
,
208 gui_synclist_del_item
,
209 gui_synclist_limit_scroll
,
210 gui_synclist_do_button
,
211 gui_synclist_set_title
,
219 #ifdef HAS_BUTTON_HOLD
224 (open_func
)PREFIX(open
),
226 (read_func
)PREFIX(read
),
228 (creat_func
)PREFIX(creat
),
229 (write_func
)PREFIX(write
),
244 create_numbered_filename
,
259 default_event_handler
,
260 default_event_handler_ex
,
265 #if (CONFIG_CODEC == SWCODEC)
272 reset_poweroff_timer
,
277 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
278 #ifdef CPU_BOOST_LOGGING
283 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
284 #endif /* !SIMULATOR */
285 #ifdef HAVE_SCHEDULER_BOOSTCTRL
289 #ifdef CACHE_FUNCTIONS_AS_CALL
301 #if CONFIG_CODEC == SWCODEC
302 queue_enable_queue_send
,
317 /* special simulator hooks */
318 #if defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8
320 sim_lcd_ex_update_rect
,
324 /* strings and memory */
367 #if CONFIG_CODEC != SWCODEC
371 #if CONFIG_CODEC == SWCODEC
372 &audio_master_sampr_list
[0],
381 pcm_get_bytes_waiting
,
385 #ifdef HAVE_RECORDING
392 pcm_calculate_rec_peaks
,
393 audio_set_recording_gain
,
394 #endif /* HAVE_RECORDING */
395 #if INPUT_SRC_CAPS != 0
396 audio_set_output_source
,
397 audio_set_input_source
,
404 #endif /* CONFIG_CODEC == SWCODEC */
406 /* playback control */
419 audio_has_changed_track
,
421 audio_flush_and_reload_tracks
,
423 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
424 mpeg_get_last_header
,
426 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) || \
427 (CONFIG_CODEC == SWCODEC)
431 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
432 /* MAS communication */
437 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
444 #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
450 gui_syncstatusbar_draw
,
458 #ifdef HAVE_LCD_COLOR
462 /* action handling */
476 # if CONFIG_CHARGING == CHARGING_MONITOR
480 #ifdef HAVE_USB_POWER
495 plugin_get_audio_buffer
,
497 plugin_get_current_filename
,
498 #ifdef PLUGIN_USE_IRAM
501 #if defined(DEBUG) || defined(SIMULATOR)
504 #ifdef ROCKBOX_HAS_LOGF
510 #if CONFIG_CODEC == SWCODEC
519 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
520 peak_meter_scale_value
,
521 peak_meter_set_use_dbfs
,
522 peak_meter_get_use_dbfs
,
524 #ifdef HAVE_LCD_BITMAP
526 screen_dump_set_hook
,
533 #ifdef HAVE_WHEEL_POSITION
538 #ifdef IRIVER_H100_SERIES
539 /* Routines for the iriver_flash -plugin. */
540 detect_original_firmware
,
541 detect_flashed_ramimage
,
542 detect_flashed_romimage
,
545 #if (CONFIG_CODEC == SWCODEC)
558 buf_request_buffer_handle
,
565 tagcache_search_set_uniqbuf
,
566 tagcache_search_add_filter
,
569 tagcache_search_finish
,
574 search_albumart_files
,
577 /* new stuff at the end, sort into place next time
578 the API gets incompatible */
582 int plugin_load(const char* plugin
, void* parameter
)
585 struct plugin_header
*hdr
;
588 #else /* !SIMULATOR */
594 #endif /* !SIMULATOR */
596 #ifdef HAVE_REMOTE_LCD
601 fb_data
* old_backdrop
;
604 if (pfn_tsr_exit
!= NULL
) /* if we have a resident old plugin: */
606 if (pfn_tsr_exit(!strcmp(current_plugin
, plugin
)) == false )
608 /* not allowing another plugin to load */
612 plugin_loaded
= false;
615 gui_syncsplash(0, ID2P(LANG_WAIT
));
616 strcpy(current_plugin
, plugin
);
619 hdr
= sim_plugin_load((char *)plugin
, &pd
);
621 gui_syncsplash(HZ
*2, str(LANG_PLUGIN_CANT_OPEN
), plugin
);
625 || hdr
->magic
!= PLUGIN_MAGIC
626 || hdr
->target_id
!= TARGET_ID
) {
627 sim_plugin_close(pd
);
628 gui_syncsplash(HZ
*2, str(LANG_PLUGIN_WRONG_MODEL
));
631 if (hdr
->api_version
> PLUGIN_API_VERSION
632 || hdr
->api_version
< PLUGIN_MIN_API_VERSION
) {
633 sim_plugin_close(pd
);
634 gui_syncsplash(HZ
*2, str(LANG_PLUGIN_WRONG_VERSION
));
638 fd
= open(plugin
, O_RDONLY
);
640 gui_syncsplash(HZ
*2, str(LANG_PLUGIN_CANT_OPEN
), plugin
);
644 /* Make sure COP cache is flushed and invalidated before loading */
645 my_core
= switch_core(CURRENT_CORE
^ 1);
647 switch_core(my_core
);
650 readsize
= read(fd
, pluginbuf
, PLUGIN_BUFFER_SIZE
);
654 gui_syncsplash(HZ
*2, str(LANG_READ_FAILED
), plugin
);
657 hdr
= (struct plugin_header
*)pluginbuf
;
659 if ((unsigned)readsize
<= sizeof(struct plugin_header
)
660 || hdr
->magic
!= PLUGIN_MAGIC
661 || hdr
->target_id
!= TARGET_ID
662 || hdr
->load_addr
!= pluginbuf
663 || hdr
->end_addr
> pluginbuf
+ PLUGIN_BUFFER_SIZE
) {
664 gui_syncsplash(HZ
*2, str(LANG_PLUGIN_WRONG_MODEL
));
667 if (hdr
->api_version
> PLUGIN_API_VERSION
668 || hdr
->api_version
< PLUGIN_MIN_API_VERSION
) {
669 gui_syncsplash(HZ
*2, str(LANG_PLUGIN_WRONG_VERSION
));
672 plugin_size
= hdr
->end_addr
- pluginbuf
;
674 /* zero out bss area only, above guards end of pluginbuf */
675 if (plugin_size
> readsize
)
676 memset(pluginbuf
+ readsize
, 0, plugin_size
- readsize
);
679 plugin_loaded
= true;
681 xm
= lcd_getxmargin();
682 ym
= lcd_getymargin();
685 #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1
686 old_backdrop
= lcd_get_backdrop();
691 #ifdef HAVE_REMOTE_LCD
692 rxm
= lcd_remote_getxmargin();
693 rym
= lcd_remote_getymargin();
694 lcd_remote_setmargins(0, 0);
695 lcd_remote_clear_display();
701 rc
= hdr
->entry_point((struct plugin_api
*) &rockbox_api
, parameter
);
702 /* explicitly casting the pointer here to avoid touching every plugin. */
704 button_clear_queue();
706 #ifdef HAVE_LCD_BITMAP
708 lcd_set_backdrop(old_backdrop
);
709 #ifdef HAVE_LCD_COLOR
710 lcd_set_drawinfo(DRMODE_SOLID
, global_settings
.fg_color
,
711 global_settings
.bg_color
);
713 lcd_set_drawinfo(DRMODE_SOLID
, LCD_DEFAULT_FG
, LCD_DEFAULT_BG
);
715 #else /* LCD_DEPTH == 1 */
716 lcd_set_drawmode(DRMODE_SOLID
);
717 #endif /* LCD_DEPTH */
718 #endif /* HAVE_LCD_BITMAP */
720 /* restore margins */
721 lcd_setmargins(xm
,ym
);
725 #ifdef HAVE_REMOTE_LCD
726 #if LCD_REMOTE_DEPTH > 1
727 lcd_remote_set_drawinfo(DRMODE_SOLID
, LCD_REMOTE_DEFAULT_FG
,
728 LCD_REMOTE_DEFAULT_BG
);
730 lcd_remote_set_drawmode(DRMODE_SOLID
);
732 lcd_remote_setmargins(rxm
, rym
);
733 lcd_remote_clear_display();
741 if (pfn_tsr_exit
== NULL
)
742 plugin_loaded
= false;
744 sim_plugin_close(pd
);
750 case PLUGIN_USB_CONNECTED
:
751 return PLUGIN_USB_CONNECTED
;
754 gui_syncsplash(HZ
*2, str(LANG_PLUGIN_ERROR
));
760 /* Returns a pointer to the portion of the plugin buffer that is not already
761 being used. If no plugin is loaded, returns the entire plugin buffer */
762 void* plugin_get_buffer(size_t *buffer_size
)
768 if (plugin_size
>= PLUGIN_BUFFER_SIZE
)
771 *buffer_size
= PLUGIN_BUFFER_SIZE
-plugin_size
;
772 buffer_pos
= plugin_size
;
776 *buffer_size
= PLUGIN_BUFFER_SIZE
;
780 return &pluginbuf
[buffer_pos
];
783 /* Returns a pointer to the mp3 buffer.
784 Playback gets stopped, to avoid conflicts.
785 Talk buffer is stolen as well.
787 void* plugin_get_audio_buffer(size_t *buffer_size
)
789 #if CONFIG_CODEC == SWCODEC
790 return audio_get_buffer(true, buffer_size
);
793 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
794 *buffer_size
= audiobufend
- audiobuf
;
799 #ifdef PLUGIN_USE_IRAM
800 /* Initializes plugin IRAM */
801 void plugin_iram_init(char *iramstart
, char *iramcopy
, size_t iram_size
,
802 char *iedata
, size_t iedata_size
)
804 /* We need to stop audio playback in order to use codec IRAM */
806 memcpy(iramstart
, iramcopy
, iram_size
);
807 memset(iedata
, 0, iedata_size
);
808 memset(iramcopy
, 0, iram_size
);
810 /* writeback cleared iedata and iramcopy areas */
814 #endif /* PLUGIN_USE_IRAM */
816 /* The plugin wants to stay resident after leaving its main function, e.g.
817 runs from timer or own thread. The callback is registered to later
818 instruct it to free its resources before a new plugin gets loaded. */
819 void plugin_tsr(bool (*exit_callback
)(bool))
821 pfn_tsr_exit
= exit_callback
; /* remember the callback for later */
824 char *plugin_get_current_filename(void)
826 return current_plugin
;