1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
32 #include "backlight.h"
33 #include "sound_menu.h"
35 #include "powermgmt.h"
38 #include "option_select.h"
47 #ifdef HAVE_LCD_BITMAP
48 #include "scrollbar.h"
49 #include "peakmeter.h"
55 static unsigned char pluginbuf
[PLUGIN_BUFFER_SIZE
];
56 void *sim_plugin_load(char *plugin
, void **pd
);
57 void sim_plugin_close(void *pd
);
58 void sim_lcd_ex_init(int shades
, unsigned long (*getpixel
)(int, int));
59 void sim_lcd_ex_update_rect(int x
, int y
, int width
, int height
);
61 #define sim_plugin_close(x)
62 extern unsigned char pluginbuf
[];
66 /* for actual plugins only, not for codecs */
67 static bool plugin_loaded
= false;
68 static int plugin_size
= 0;
69 static bool (*pfn_tsr_exit
)(bool reenter
) = NULL
; /* TSR exit callback */
70 static char current_plugin
[MAX_PATH
];
72 char *plugin_get_current_filename(void);
74 extern struct thread_entry threads
[MAXTHREADS
];
76 static const struct plugin_api rockbox_api
= {
87 #ifdef HAVE_LCD_CHARCELLS
89 lcd_get_locked_pattern
,
97 &lcd_framebuffer
[0][0],
108 lcd_mono_bitmap_part
,
121 lcd_bitmap_transparent_part
,
122 lcd_bitmap_transparent
,
124 #if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) \
125 || defined(IRIVER_H10) || defined(COWON_D2)
128 #elif (LCD_DEPTH < 4) && !defined(SIMULATOR)
131 #endif /* LCD_DEPTH */
133 lcd_puts_scroll_style
,
134 #ifdef HAVE_LCD_INVERT
135 lcd_set_invert_display
,
136 #endif /* HAVE_LCD_INVERT */
137 #if defined(HAVE_LCD_ENABLE) && defined(HAVE_LCD_COLOR)
149 #endif /* HAVE_LCD_BITMAP */
154 backlight_set_timeout
,
155 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
156 backlight_set_brightness
,
157 #endif /* HAVE_BACKLIGHT_BRIGHTNESS */
160 backlight_set_timeout_plugged
,
166 #ifdef HAVE_REMOTE_LCD
168 lcd_remote_set_contrast
,
169 lcd_remote_clear_display
,
171 lcd_remote_puts_scroll
,
172 lcd_remote_stop_scroll
,
173 lcd_remote_set_drawmode
,
174 lcd_remote_get_drawmode
,
176 lcd_remote_getstringsize
,
177 lcd_remote_drawpixel
,
183 lcd_remote_mono_bitmap_part
,
184 lcd_remote_mono_bitmap
,
186 lcd_remote_puts_style
,
187 lcd_remote_puts_scroll_style
,
188 &lcd_remote_framebuffer
[0][0],
190 lcd_remote_update_rect
,
193 remote_backlight_off
,
194 remote_backlight_set_timeout
,
196 remote_backlight_set_timeout_plugged
,
198 #endif /* HAVE_REMOTE_LCD */
200 {&screens
[SCREEN_MAIN
], &screens
[SCREEN_REMOTE
]},
202 {&screens
[SCREEN_MAIN
]},
204 #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
205 lcd_remote_set_foreground
,
206 lcd_remote_get_foreground
,
207 lcd_remote_set_background
,
208 lcd_remote_get_background
,
209 lcd_remote_bitmap_part
,
212 viewport_set_defaults
,
216 gui_synclist_set_nb_items
,
217 gui_synclist_set_icon_callback
,
218 gui_synclist_get_nb_items
,
219 gui_synclist_get_sel_pos
,
221 gui_synclist_select_item
,
222 gui_synclist_add_item
,
223 gui_synclist_del_item
,
224 gui_synclist_limit_scroll
,
225 gui_synclist_do_button
,
226 gui_synclist_set_title
,
228 simplelist_info_init
,
229 simplelist_show_list
,
235 #ifdef HAVE_BUTTON_DATA
240 #ifdef HAS_BUTTON_HOLD
243 #ifdef HAVE_TOUCHSCREEN
244 touchscreen_set_mode
,
247 #ifdef HAVE_BUTTON_LIGHT
248 buttonlight_set_timeout
,
251 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
252 buttonlight_set_brightness
,
253 #endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
254 #endif /* HAVE_BUTTON_LIGHT */
257 (open_func
)PREFIX(open
),
259 (read_func
)PREFIX(read
),
261 (creat_func
)PREFIX(creat
),
262 (write_func
)PREFIX(write
),
273 #if USING_STORAGE_CALLBACK
274 register_storage_idle_func
,
275 unregister_storage_idle_func
,
276 #endif /* USING_STORAGE_CALLBACK */
278 create_numbered_filename
,
293 default_event_handler
,
294 default_event_handler_ex
,
299 #if (CONFIG_CODEC == SWCODEC)
306 reset_poweroff_timer
,
311 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
312 #ifdef CPU_BOOST_LOGGING
317 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
318 #endif /* !SIMULATOR */
319 #ifdef HAVE_SCHEDULER_BOOSTCTRL
323 #ifdef CACHE_FUNCTIONS_AS_CALL
335 #if CONFIG_CODEC == SWCODEC
336 queue_enable_queue_send
,
346 __cyg_profile_func_enter
,
347 __cyg_profile_func_exit
,
351 /* special simulator hooks */
352 #if defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8
354 sim_lcd_ex_update_rect
,
358 /* strings and memory */
401 #if CONFIG_CODEC != SWCODEC
405 #if CONFIG_CODEC == SWCODEC
406 &audio_master_sampr_list
[0],
415 pcm_get_bytes_waiting
,
419 #ifdef HAVE_RECORDING
426 pcm_calculate_rec_peaks
,
427 audio_set_recording_gain
,
428 #endif /* HAVE_RECORDING */
429 #if INPUT_SRC_CAPS != 0
430 audio_set_output_source
,
431 audio_set_input_source
,
438 #endif /* CONFIG_CODEC == SWCODEC */
440 /* playback control */
453 audio_has_changed_track
,
455 audio_flush_and_reload_tracks
,
457 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
458 mpeg_get_last_header
,
460 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) || \
461 (CONFIG_CODEC == SWCODEC)
465 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
466 /* MAS communication */
471 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
478 #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
484 gui_syncstatusbar_draw
,
493 #ifdef HAVE_LCD_COLOR
497 /* action handling */
511 # if CONFIG_CHARGING == CHARGING_MONITOR
515 #ifdef HAVE_USB_POWER
530 plugin_get_audio_buffer
,
532 plugin_get_current_filename
,
533 #ifdef PLUGIN_USE_IRAM
536 #if defined(DEBUG) || defined(SIMULATOR)
539 #ifdef ROCKBOX_HAS_LOGF
545 #if CONFIG_CODEC == SWCODEC
554 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
555 peak_meter_scale_value
,
556 peak_meter_set_use_dbfs
,
557 peak_meter_get_use_dbfs
,
559 #ifdef HAVE_LCD_BITMAP
561 screen_dump_set_hook
,
568 #ifdef HAVE_WHEEL_POSITION
573 #ifdef IRIVER_H100_SERIES
574 /* Routines for the iriver_flash -plugin. */
575 detect_original_firmware
,
576 detect_flashed_ramimage
,
577 detect_flashed_romimage
,
580 #if (CONFIG_CODEC == SWCODEC)
593 buf_request_buffer_handle
,
600 tagcache_search_set_uniqbuf
,
601 tagcache_search_add_filter
,
604 tagcache_search_finish
,
605 tagcache_get_numeric
,
610 search_albumart_files
,
615 #ifdef HAVE_SEMAPHORE_OBJECTS
622 /* new stuff at the end, sort into place next time
623 the API gets incompatible */
626 int plugin_load(const char* plugin
, const void* parameter
)
629 struct plugin_header
*hdr
;
632 #else /* !SIMULATOR */
638 #endif /* !SIMULATOR */
641 fb_data
* old_backdrop
;
644 if (pfn_tsr_exit
!= NULL
) /* if we have a resident old plugin: */
646 if (pfn_tsr_exit(!strcmp(current_plugin
, plugin
)) == false )
648 /* not allowing another plugin to load */
652 plugin_loaded
= false;
655 splash(0, ID2P(LANG_WAIT
));
656 strcpy(current_plugin
, plugin
);
659 hdr
= sim_plugin_load((char *)plugin
, &pd
);
661 splashf(HZ
*2, str(LANG_PLUGIN_CANT_OPEN
), plugin
);
665 || hdr
->magic
!= PLUGIN_MAGIC
666 || hdr
->target_id
!= TARGET_ID
) {
667 sim_plugin_close(pd
);
668 splash(HZ
*2, str(LANG_PLUGIN_WRONG_MODEL
));
671 if (hdr
->api_version
> PLUGIN_API_VERSION
672 || hdr
->api_version
< PLUGIN_MIN_API_VERSION
) {
673 sim_plugin_close(pd
);
674 splash(HZ
*2, str(LANG_PLUGIN_WRONG_VERSION
));
678 fd
= open(plugin
, O_RDONLY
);
680 splashf(HZ
*2, str(LANG_PLUGIN_CANT_OPEN
), plugin
);
684 /* Make sure COP cache is flushed and invalidated before loading */
685 my_core
= switch_core(CURRENT_CORE
^ 1);
687 switch_core(my_core
);
690 readsize
= read(fd
, pluginbuf
, PLUGIN_BUFFER_SIZE
);
694 splashf(HZ
*2, str(LANG_READ_FAILED
), plugin
);
697 hdr
= (struct plugin_header
*)pluginbuf
;
699 if ((unsigned)readsize
<= sizeof(struct plugin_header
)
700 || hdr
->magic
!= PLUGIN_MAGIC
701 || hdr
->target_id
!= TARGET_ID
702 || hdr
->load_addr
!= pluginbuf
703 || hdr
->end_addr
> pluginbuf
+ PLUGIN_BUFFER_SIZE
) {
704 splash(HZ
*2, str(LANG_PLUGIN_WRONG_MODEL
));
707 if (hdr
->api_version
> PLUGIN_API_VERSION
708 || hdr
->api_version
< PLUGIN_MIN_API_VERSION
) {
709 splash(HZ
*2, str(LANG_PLUGIN_WRONG_VERSION
));
712 plugin_size
= hdr
->end_addr
- pluginbuf
;
714 /* zero out bss area only, above guards end of pluginbuf */
715 if (plugin_size
> readsize
)
716 memset(pluginbuf
+ readsize
, 0, plugin_size
- readsize
);
719 plugin_loaded
= true;
722 #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1
723 old_backdrop
= lcd_get_backdrop();
728 #ifdef HAVE_REMOTE_LCD
729 lcd_remote_clear_display();
735 rc
= hdr
->entry_point(&rockbox_api
, parameter
);
737 button_clear_queue();
739 #ifdef HAVE_LCD_BITMAP
741 lcd_set_backdrop(old_backdrop
);
742 #ifdef HAVE_LCD_COLOR
743 lcd_set_drawinfo(DRMODE_SOLID
, global_settings
.fg_color
,
744 global_settings
.bg_color
);
746 lcd_set_drawinfo(DRMODE_SOLID
, LCD_DEFAULT_FG
, LCD_DEFAULT_BG
);
748 #else /* LCD_DEPTH == 1 */
749 lcd_set_drawmode(DRMODE_SOLID
);
750 #endif /* LCD_DEPTH */
751 #endif /* HAVE_LCD_BITMAP */
756 #ifdef HAVE_REMOTE_LCD
757 #if LCD_REMOTE_DEPTH > 1
758 lcd_remote_set_drawinfo(DRMODE_SOLID
, LCD_REMOTE_DEFAULT_FG
,
759 LCD_REMOTE_DEFAULT_BG
);
761 lcd_remote_set_drawmode(DRMODE_SOLID
);
763 lcd_remote_clear_display();
771 if (pfn_tsr_exit
== NULL
)
772 plugin_loaded
= false;
774 sim_plugin_close(pd
);
780 case PLUGIN_USB_CONNECTED
:
781 return PLUGIN_USB_CONNECTED
;
784 splash(HZ
*2, str(LANG_PLUGIN_ERROR
));
791 /* Returns a pointer to the portion of the plugin buffer that is not already
792 being used. If no plugin is loaded, returns the entire plugin buffer */
793 void* plugin_get_buffer(size_t *buffer_size
)
799 if (plugin_size
>= PLUGIN_BUFFER_SIZE
)
802 *buffer_size
= PLUGIN_BUFFER_SIZE
-plugin_size
;
803 buffer_pos
= plugin_size
;
807 *buffer_size
= PLUGIN_BUFFER_SIZE
;
811 return &pluginbuf
[buffer_pos
];
814 /* Returns a pointer to the mp3 buffer.
815 Playback gets stopped, to avoid conflicts.
816 Talk buffer is stolen as well.
818 void* plugin_get_audio_buffer(size_t *buffer_size
)
820 #if CONFIG_CODEC == SWCODEC
821 return audio_get_buffer(true, buffer_size
);
824 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
825 *buffer_size
= audiobufend
- audiobuf
;
830 #ifdef PLUGIN_USE_IRAM
831 /* Initializes plugin IRAM */
832 void plugin_iram_init(char *iramstart
, char *iramcopy
, size_t iram_size
,
833 char *iedata
, size_t iedata_size
)
835 /* We need to stop audio playback in order to use codec IRAM */
837 memcpy(iramstart
, iramcopy
, iram_size
);
838 memset(iedata
, 0, iedata_size
);
839 memset(iramcopy
, 0, iram_size
);
841 /* writeback cleared iedata and iramcopy areas */
845 #endif /* PLUGIN_USE_IRAM */
847 /* The plugin wants to stay resident after leaving its main function, e.g.
848 runs from timer or own thread. The callback is registered to later
849 instruct it to free its resources before a new plugin gets loaded. */
850 void plugin_tsr(bool (*exit_callback
)(bool))
852 pfn_tsr_exit
= exit_callback
; /* remember the callback for later */
855 char *plugin_get_current_filename(void)
857 return current_plugin
;