Merge tag 'v3.13-final' into maemo-port
[maemo-rb.git] / apps / plugin.c
blob24443b58d97d6ee7fb73f55c360b057c785ea3ce
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include "plugin.h"
22 #include <ctype.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include "debug.h"
26 #include "i2c.h"
27 #include "lang.h"
28 #include "led.h"
29 #include "keyboard.h"
30 #include "backlight.h"
31 #include "sound_menu.h"
32 #include "mp3data.h"
33 #include "powermgmt.h"
34 #include "splash.h"
35 #include "logf.h"
36 #include "option_select.h"
37 #include "talk.h"
38 #include "version.h"
39 #include "storage.h"
40 #include "pcmbuf.h"
41 #include "errno.h"
42 #include "diacritic.h"
43 #include "filefuncs.h"
44 #include "load_code.h"
46 #if CONFIG_CHARGING
47 #include "power.h"
48 #endif
50 #ifdef HAVE_LCD_BITMAP
51 #include "scrollbar.h"
52 #include "peakmeter.h"
53 #include "bmp.h"
54 #include "bidi.h"
55 #endif
57 #ifdef USB_ENABLE_HID
58 #include "usbstack/usb_hid.h"
59 #endif
61 #if defined (SIMULATOR)
62 #define PREFIX(_x_) sim_ ## _x_
63 #elif defined (APPLICATION)
64 #define PREFIX(_x_) app_ ## _x_
65 #else
66 #define PREFIX(_x_) _x_
67 #endif
69 #if defined (APPLICATION)
70 /* For symmetry reasons (we want app_ and sim_ to behave similarly), some
71 * wrappers are needed */
72 static int app_close(int fd)
74 return close(fd);
77 static ssize_t app_read(int fd, void *buf, size_t count)
79 return read(fd,buf,count);
82 static off_t app_lseek(int fd, off_t offset, int whence)
84 return lseek(fd,offset,whence);
87 static ssize_t app_write(int fd, const void *buf, size_t count)
89 return write(fd,buf,count);
92 static int app_ftruncate(int fd, off_t length)
94 return ftruncate(fd,length);
96 #endif
98 #if defined(HAVE_PLUGIN_CHECK_OPEN_CLOSE) && (MAX_OPEN_FILES>32)
99 #warning "MAX_OPEN_FILES>32, disabling plugin file open/close checking"
100 #undef HAVE_PLUGIN_CHECK_OPEN_CLOSE
101 #endif
103 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
104 static unsigned int open_files;
105 #endif
107 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
108 static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE];
109 void sim_lcd_ex_init(unsigned long (*getpixel)(int, int));
110 void sim_lcd_ex_update_rect(int x, int y, int width, int height);
111 #else
112 extern unsigned char pluginbuf[];
113 #include "bitswap.h"
114 #endif
116 /* for actual plugins only, not for codecs */
117 static int plugin_size = 0;
118 static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */
119 static char current_plugin[MAX_PATH];
120 /* NULL if no plugin is loaded, otherwise the handle that lc_open() returned */
121 static void *current_plugin_handle;
123 char *plugin_get_current_filename(void);
125 /* Some wrappers used to monitor open and close and detect leaks*/
126 static int open_wrapper(const char* pathname, int flags, ...);
127 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
128 static int close_wrapper(int fd);
129 static int creat_wrapper(const char *pathname, mode_t mode);
130 #endif
132 static const struct plugin_api rockbox_api = {
134 /* lcd */
135 #ifdef HAVE_LCD_CONTRAST
136 lcd_set_contrast,
137 #endif
138 lcd_update,
139 lcd_clear_display,
140 lcd_getstringsize,
141 lcd_putsxy,
142 lcd_putsxyf,
143 lcd_puts,
144 lcd_putsf,
145 lcd_puts_scroll,
146 lcd_stop_scroll,
147 #ifdef HAVE_LCD_CHARCELLS
148 lcd_define_pattern,
149 lcd_get_locked_pattern,
150 lcd_unlock_pattern,
151 lcd_putc,
152 lcd_put_cursor,
153 lcd_remove_cursor,
154 lcd_icon,
155 lcd_double_height,
156 #else
157 &lcd_static_framebuffer[0][0],
158 lcd_set_viewport,
159 lcd_set_framebuffer,
160 lcd_bmp_part,
161 lcd_update_rect,
162 lcd_set_drawmode,
163 lcd_get_drawmode,
164 screen_helper_setfont,
165 lcd_drawpixel,
166 lcd_drawline,
167 lcd_hline,
168 lcd_vline,
169 lcd_drawrect,
170 lcd_fillrect,
171 lcd_mono_bitmap_part,
172 lcd_mono_bitmap,
173 #if LCD_DEPTH > 1
174 lcd_set_foreground,
175 lcd_get_foreground,
176 lcd_set_background,
177 lcd_get_background,
178 lcd_bitmap_part,
179 lcd_bitmap,
180 lcd_get_backdrop,
181 lcd_set_backdrop,
182 #endif
183 #if LCD_DEPTH == 16
184 lcd_bitmap_transparent_part,
185 lcd_bitmap_transparent,
186 #if MEMORYSIZE > 2
187 lcd_blit_yuv,
188 #if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) \
189 || defined(IRIVER_H10) || defined(COWON_D2) || defined(PHILIPS_HDD1630) \
190 || defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_FUZEV2) \
191 || defined(TOSHIBA_GIGABEAT_S) || defined(PHILIPS_SA9200)
192 lcd_yuv_set_options,
193 #endif
194 #endif /* MEMORYSIZE > 2 */
195 #elif (LCD_DEPTH < 4) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
196 lcd_blit_mono,
197 lcd_blit_grey_phase,
198 #endif /* LCD_DEPTH */
199 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
200 lcd_blit_pal256,
201 lcd_pal256_update_pal,
202 #endif
203 lcd_puts_style,
204 lcd_puts_scroll_style,
205 #ifdef HAVE_LCD_INVERT
206 lcd_set_invert_display,
207 #endif /* HAVE_LCD_INVERT */
208 #if defined(HAVE_LCD_MODES)
209 lcd_set_mode,
210 #endif
211 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
212 &button_queue,
213 #endif
214 bidi_l2v,
215 #ifdef HAVE_LCD_BITMAP
216 is_diacritic,
217 #endif
218 font_get_bits,
219 font_load,
220 font_unload,
221 font_get,
222 font_getstringsize,
223 font_get_width,
224 screen_clear_area,
225 gui_scrollbar_draw,
226 #endif /* HAVE_LCD_BITMAP */
227 get_codepage_name,
229 backlight_on,
230 backlight_off,
231 backlight_set_timeout,
232 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
233 backlight_set_brightness,
234 #endif /* HAVE_BACKLIGHT_BRIGHTNESS */
236 #if CONFIG_CHARGING
237 backlight_set_timeout_plugged,
238 #endif
239 is_backlight_on,
240 splash,
241 splashf,
243 #ifdef HAVE_REMOTE_LCD
244 /* remote lcd */
245 lcd_remote_set_contrast,
246 lcd_remote_clear_display,
247 lcd_remote_puts,
248 lcd_remote_puts_scroll,
249 lcd_remote_stop_scroll,
250 lcd_remote_set_drawmode,
251 lcd_remote_get_drawmode,
252 lcd_remote_setfont,
253 lcd_remote_getstringsize,
254 lcd_remote_drawpixel,
255 lcd_remote_drawline,
256 lcd_remote_hline,
257 lcd_remote_vline,
258 lcd_remote_drawrect,
259 lcd_remote_fillrect,
260 lcd_remote_mono_bitmap_part,
261 lcd_remote_mono_bitmap,
262 lcd_remote_putsxy,
263 lcd_remote_puts_style,
264 lcd_remote_puts_scroll_style,
265 &lcd_remote_static_framebuffer[0][0],
266 lcd_remote_update,
267 lcd_remote_update_rect,
269 remote_backlight_on,
270 remote_backlight_off,
271 remote_backlight_set_timeout,
272 #if CONFIG_CHARGING
273 remote_backlight_set_timeout_plugged,
274 #endif
275 #endif /* HAVE_REMOTE_LCD */
276 #if NB_SCREENS == 2
277 {&screens[SCREEN_MAIN], &screens[SCREEN_REMOTE]},
278 #else
279 {&screens[SCREEN_MAIN]},
280 #endif
281 #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
282 lcd_remote_set_foreground,
283 lcd_remote_get_foreground,
284 lcd_remote_set_background,
285 lcd_remote_get_background,
286 lcd_remote_bitmap_part,
287 lcd_remote_bitmap,
288 #endif
289 viewport_set_defaults,
290 #ifdef HAVE_LCD_BITMAP
291 viewportmanager_theme_enable,
292 viewportmanager_theme_undo,
293 viewport_set_fullscreen,
294 #endif
296 /* list */
297 gui_synclist_init,
298 gui_synclist_set_nb_items,
299 gui_synclist_set_icon_callback,
300 gui_synclist_get_nb_items,
301 gui_synclist_get_sel_pos,
302 gui_synclist_draw,
303 gui_synclist_select_item,
304 gui_synclist_add_item,
305 gui_synclist_del_item,
306 gui_synclist_limit_scroll,
307 gui_synclist_do_button,
308 gui_synclist_set_title,
309 gui_syncyesno_run,
310 simplelist_info_init,
311 simplelist_show_list,
313 /* button */
314 button_get,
315 button_get_w_tmo,
316 button_status,
317 #ifdef HAVE_BUTTON_DATA
318 button_get_data,
319 button_status_wdata,
320 #endif
321 button_clear_queue,
322 button_queue_count,
323 #ifdef HAS_BUTTON_HOLD
324 button_hold,
325 #endif
326 #ifdef HAVE_TOUCHSCREEN
327 touchscreen_set_mode,
328 touchscreen_get_mode,
329 #endif
331 #ifdef HAVE_BUTTON_LIGHT
332 buttonlight_set_timeout,
333 buttonlight_off,
334 buttonlight_on,
335 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
336 buttonlight_set_brightness,
337 #endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
338 #endif /* HAVE_BUTTON_LIGHT */
340 /* file */
341 open_utf8,
342 (open_func)open_wrapper,
343 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
344 close_wrapper,
345 #else
346 PREFIX(close),
347 #endif
348 (read_func)PREFIX(read),
349 PREFIX(lseek),
350 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
351 (creat_func)creat_wrapper,
352 #else
353 PREFIX(creat),
354 #endif
355 (write_func)PREFIX(write),
356 PREFIX(remove),
357 PREFIX(rename),
358 PREFIX(ftruncate),
359 filesize,
360 fdprintf,
361 read_line,
362 settings_parseline,
363 storage_sleep,
364 storage_spin,
365 storage_spindown,
366 #if USING_STORAGE_CALLBACK
367 register_storage_idle_func,
368 unregister_storage_idle_func,
369 #endif /* USING_STORAGE_CALLBACK */
370 reload_directory,
371 create_numbered_filename,
372 file_exists,
373 strip_extension,
374 crc_32,
375 filetype_get_attr,
377 /* dir */
378 (opendir_func)opendir,
379 (closedir_func)closedir,
380 (readdir_func)readdir,
381 mkdir,
382 rmdir,
383 dir_exists,
384 dir_get_info,
386 /* browsing */
387 browse_context_init,
388 rockbox_browse,
390 /* kernel/ system */
391 #if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE
392 __div0,
393 #endif
394 sleep,
395 yield,
396 &current_tick,
397 default_event_handler,
398 default_event_handler_ex,
399 create_thread,
400 thread_self,
401 thread_exit,
402 thread_wait,
403 #if (CONFIG_CODEC == SWCODEC)
404 thread_thaw,
405 #ifdef HAVE_PRIORITY_SCHEDULING
406 thread_set_priority,
407 #endif
408 mutex_init,
409 mutex_lock,
410 mutex_unlock,
411 #endif
413 reset_poweroff_timer,
414 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
415 system_memory_guard,
416 &cpu_frequency,
418 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
419 #ifdef CPU_BOOST_LOGGING
420 cpu_boost_,
421 #else
422 cpu_boost,
423 #endif
424 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
425 #endif /* PLATFORM_NATIVE */
426 #ifdef HAVE_SCHEDULER_BOOSTCTRL
427 trigger_cpu_boost,
428 cancel_cpu_boost,
429 #endif
431 commit_dcache,
432 commit_discard_dcache,
433 commit_discard_idcache,
435 lc_open,
436 lc_open_from_mem,
437 lc_get_header,
438 lc_close,
440 timer_register,
441 timer_unregister,
442 timer_set_period,
444 queue_init,
445 queue_delete,
446 queue_post,
447 queue_wait_w_tmo,
448 #if CONFIG_CODEC == SWCODEC
449 queue_enable_queue_send,
450 queue_empty,
451 queue_wait,
452 queue_send,
453 queue_reply,
454 #endif
455 usb_acknowledge,
456 #ifdef USB_ENABLE_HID
457 usb_hid_send,
458 #endif
459 #ifdef RB_PROFILE
460 profile_thread,
461 profstop,
462 __cyg_profile_func_enter,
463 __cyg_profile_func_exit,
464 #endif
465 add_event,
466 remove_event,
467 send_event,
469 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
470 /* special simulator hooks */
471 #if defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8
472 sim_lcd_ex_init,
473 sim_lcd_ex_update_rect,
474 #endif
475 #endif
477 /* strings and memory */
478 snprintf,
479 vsnprintf,
480 strcpy,
481 strlcpy,
482 strlen,
483 strrchr,
484 strcmp,
485 strncmp,
486 strcasecmp,
487 strncasecmp,
488 memset,
489 memcpy,
490 memmove,
491 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
492 _ctype_,
493 #endif
494 atoi,
495 strchr,
496 strcat,
497 strlcat,
498 memchr,
499 memcmp,
500 strcasestr,
501 strtok_r,
502 /* unicode stuff */
503 utf8decode,
504 iso_decode,
505 utf16LEdecode,
506 utf16BEdecode,
507 utf8encode,
508 utf8length,
509 utf8seek,
511 /* the buflib memory management library */
512 buflib_init,
513 buflib_available,
514 buflib_alloc,
515 buflib_alloc_ex,
516 buflib_alloc_maximum,
517 buflib_buffer_in,
518 buflib_buffer_out,
519 buflib_free,
520 buflib_shrink,
521 buflib_get_data,
522 buflib_get_name,
524 /* sound */
525 sound_set,
526 sound_default,
527 sound_min,
528 sound_max,
529 sound_unit,
530 sound_val2phys,
531 #ifdef AUDIOHW_HAVE_EQ
532 sound_enum_hw_eq_band_setting,
533 #endif
534 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
535 mp3_play_data,
536 mp3_play_pause,
537 mp3_play_stop,
538 mp3_is_playing,
539 #if CONFIG_CODEC != SWCODEC
540 bitswap,
541 #endif
542 #endif
543 #if CONFIG_CODEC == SWCODEC
544 &audio_master_sampr_list[0],
545 &hw_freq_sampr[0],
546 pcm_apply_settings,
547 pcm_play_data,
548 pcm_play_stop,
549 pcm_set_frequency,
550 pcm_is_playing,
551 pcm_is_paused,
552 pcm_play_pause,
553 pcm_get_bytes_waiting,
554 pcm_calculate_peaks,
555 pcm_get_peak_buffer,
556 pcm_play_lock,
557 pcm_play_unlock,
558 beep_play,
559 #ifdef HAVE_RECORDING
560 &rec_freq_sampr[0],
561 pcm_init_recording,
562 pcm_close_recording,
563 pcm_record_data,
564 pcm_stop_recording,
565 pcm_calculate_rec_peaks,
566 audio_set_recording_gain,
567 #endif /* HAVE_RECORDING */
568 #if INPUT_SRC_CAPS != 0
569 audio_set_output_source,
570 audio_set_input_source,
571 #endif
572 dsp_set_crossfeed_type ,
573 dsp_eq_enable,
574 dsp_dither_enable,
575 #ifdef HAVE_PITCHCONTROL
576 dsp_set_timestretch,
577 #endif
578 dsp_configure,
579 dsp_get_config,
580 dsp_process,
582 mixer_channel_status,
583 mixer_channel_get_buffer,
584 mixer_channel_calculate_peaks,
585 mixer_channel_play_data,
586 mixer_channel_play_pause,
587 mixer_channel_stop,
588 mixer_channel_set_amplitude,
589 mixer_channel_get_bytes_waiting,
590 mixer_channel_set_buffer_hook,
592 system_sound_play,
593 keyclick_click,
594 #endif /* CONFIG_CODEC == SWCODEC */
595 /* playback control */
596 playlist_amount,
597 playlist_resume,
598 playlist_resume_track,
599 playlist_start,
600 playlist_add,
601 playlist_sync,
602 playlist_remove_all_tracks,
603 playlist_create,
604 playlist_insert_track,
605 playlist_insert_directory,
606 playlist_shuffle,
607 audio_play,
608 audio_stop,
609 audio_pause,
610 audio_resume,
611 audio_next,
612 audio_prev,
613 audio_ff_rewind,
614 audio_next_track,
615 audio_status,
616 audio_current_track,
617 audio_flush_and_reload_tracks,
618 audio_get_file_pos,
619 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
620 mpeg_get_last_header,
621 #endif
622 #if ((CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) || \
623 (CONFIG_CODEC == SWCODEC)) && defined (HAVE_PITCHCONTROL)
624 sound_set_pitch,
625 #endif
627 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
628 /* MAS communication */
629 mas_readmem,
630 mas_writemem,
631 mas_readreg,
632 mas_writereg,
633 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
634 mas_codec_writereg,
635 mas_codec_readreg,
636 i2c_begin,
637 i2c_end,
638 i2c_write,
639 #endif
640 #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
642 /* menu */
643 do_menu,
644 /* statusbars */
645 &statusbars,
646 gui_syncstatusbar_draw,
648 /* options */
649 get_settings_list,
650 find_setting,
651 option_screen,
652 set_option,
653 set_bool_options,
654 set_int,
655 set_bool,
656 #ifdef HAVE_LCD_COLOR
657 set_color,
658 #endif
660 /* action handling */
661 get_custom_action,
662 get_action,
663 #ifdef HAVE_TOUCHSCREEN
664 action_get_touchscreen_press,
665 #endif
666 action_userabort,
668 /* power */
669 battery_level,
670 battery_level_safe,
671 battery_time,
672 battery_voltage,
673 #if CONFIG_CHARGING
674 charger_inserted,
675 # if CONFIG_CHARGING >= CHARGING_MONITOR
676 charging_state,
677 # endif
678 #endif
679 #ifdef HAVE_USB_POWER
680 usb_powered,
681 #endif
683 /* misc */
684 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
685 &errno,
686 #endif
687 srand,
688 rand,
689 (qsort_func)qsort,
690 kbd_input,
691 get_time,
692 set_time,
693 #if CONFIG_RTC
694 mktime,
695 #endif
696 plugin_get_buffer,
697 plugin_get_audio_buffer,
698 plugin_tsr,
699 plugin_get_current_filename,
700 #if defined(DEBUG) || defined(SIMULATOR)
701 debugf,
702 #endif
703 #ifdef ROCKBOX_HAS_LOGF
704 _logf,
705 #endif
706 &global_settings,
707 &global_status,
708 talk_disable,
709 #if CONFIG_CODEC == SWCODEC
710 codec_thread_do_callback,
711 codec_load_file,
712 codec_run_proc,
713 codec_close,
714 get_codec_filename,
715 find_array_ptr,
716 remove_array_ptr,
717 round_value_to_list32,
718 #endif /* CONFIG_CODEC == SWCODEC */
719 get_metadata,
720 mp3info,
721 count_mp3_frames,
722 create_xing_header,
723 find_next_frame,
724 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
725 peak_meter_scale_value,
726 peak_meter_set_use_dbfs,
727 peak_meter_get_use_dbfs,
728 #endif
729 #ifdef HAVE_LCD_BITMAP
730 read_bmp_file,
731 read_bmp_fd,
732 #ifdef HAVE_JPEG
733 read_jpeg_file,
734 read_jpeg_fd,
735 #endif
736 screen_dump_set_hook,
737 #endif
738 show_logo,
739 tree_get_context,
740 tree_get_entries,
741 tree_get_entry_at,
742 set_current_file,
743 set_dirfilter,
745 #ifdef HAVE_WHEEL_POSITION
746 wheel_status,
747 wheel_send_events,
748 #endif
750 #ifdef IRIVER_H100_SERIES
751 /* Routines for the iriver_flash -plugin. */
752 detect_original_firmware,
753 detect_flashed_ramimage,
754 detect_flashed_romimage,
755 #endif
756 led,
757 #if (CONFIG_CODEC == SWCODEC)
758 bufopen,
759 bufalloc,
760 bufclose,
761 bufseek,
762 bufadvance,
763 bufread,
764 bufgetdata,
765 bufgettail,
766 bufcuttail,
768 buf_handle_offset,
769 buf_set_base_handle,
770 buf_used,
771 #endif
773 #ifdef HAVE_TAGCACHE
774 tagcache_search,
775 tagcache_search_set_uniqbuf,
776 tagcache_search_add_filter,
777 tagcache_get_next,
778 tagcache_retrieve,
779 tagcache_search_finish,
780 tagcache_get_numeric,
781 #if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
782 tagcache_fill_tags,
783 #endif
784 #endif
786 #ifdef HAVE_ALBUMART
787 search_albumart_files,
788 #endif
790 #ifdef HAVE_SEMAPHORE_OBJECTS
791 semaphore_init,
792 semaphore_wait,
793 semaphore_release,
794 #endif
796 rbversion,
798 /* new stuff at the end, sort into place next time
799 the API gets incompatible */
803 int plugin_load(const char* plugin, const void* parameter)
805 struct plugin_header *p_hdr;
806 struct lc_header *hdr;
808 if (current_plugin_handle && pfn_tsr_exit)
809 { /* if we have a resident old plugin and a callback */
810 if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false )
812 /* not allowing another plugin to load */
813 return PLUGIN_OK;
815 lc_close(current_plugin_handle);
816 current_plugin_handle = pfn_tsr_exit = NULL;
819 splash(0, ID2P(LANG_WAIT));
820 strcpy(current_plugin, plugin);
822 current_plugin_handle = lc_open(plugin, pluginbuf, PLUGIN_BUFFER_SIZE);
823 if (current_plugin_handle == NULL) {
824 splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
825 return -1;
828 p_hdr = lc_get_header(current_plugin_handle);
830 hdr = p_hdr ? &p_hdr->lc_hdr : NULL;
833 if (hdr == NULL
834 || hdr->magic != PLUGIN_MAGIC
835 || hdr->target_id != TARGET_ID
836 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
837 || hdr->load_addr != pluginbuf
838 || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE
839 #endif
842 lc_close(current_plugin_handle);
843 splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
844 return -1;
846 if (hdr->api_version > PLUGIN_API_VERSION
847 || hdr->api_version < PLUGIN_MIN_API_VERSION)
849 lc_close(current_plugin_handle);
850 splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
851 return -1;
853 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
854 plugin_size = hdr->end_addr - pluginbuf;
855 #else
856 plugin_size = 0;
857 #endif
859 *(p_hdr->api) = &rockbox_api;
861 lcd_clear_display();
862 lcd_update();
864 #ifdef HAVE_REMOTE_LCD
865 lcd_remote_clear_display();
866 lcd_remote_update();
867 #endif
868 push_current_activity(ACTIVITY_PLUGIN);
869 /* some plugins assume the entry cache doesn't move and save pointers to it
870 * they should be fixed properly instead of this lock */
871 tree_lock_cache(tree_get_context());
873 FOR_NB_SCREENS(i)
874 viewportmanager_theme_enable(i, false, NULL);
876 #ifdef HAVE_TOUCHSCREEN
877 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
878 #endif
880 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
881 open_files = 0;
882 #endif
884 int rc = p_hdr->entry_point(parameter);
886 tree_unlock_cache(tree_get_context());
887 pop_current_activity();
889 if (!pfn_tsr_exit)
890 { /* close handle if plugin is no tsr one */
891 lc_close(current_plugin_handle);
892 current_plugin_handle = NULL;
895 /* Go back to the global setting in case the plugin changed it */
896 #ifdef HAVE_TOUCHSCREEN
897 touchscreen_set_mode(global_settings.touch_mode);
898 #endif
900 #ifdef HAVE_LCD_BITMAP
901 screen_helper_setfont(FONT_UI);
902 #if LCD_DEPTH > 1
903 #ifdef HAVE_LCD_COLOR
904 lcd_set_drawinfo(DRMODE_SOLID, global_settings.fg_color,
905 global_settings.bg_color);
906 #else
907 lcd_set_drawinfo(DRMODE_SOLID, LCD_DEFAULT_FG, LCD_DEFAULT_BG);
908 #endif
909 #else /* LCD_DEPTH == 1 */
910 lcd_set_drawmode(DRMODE_SOLID);
911 #endif /* LCD_DEPTH */
912 #endif /* HAVE_LCD_BITMAP */
915 #ifdef HAVE_REMOTE_LCD
916 #if LCD_REMOTE_DEPTH > 1
917 lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
918 LCD_REMOTE_DEFAULT_BG);
919 #else
920 lcd_remote_set_drawmode(DRMODE_SOLID);
921 #endif
922 #endif
924 lcd_clear_display();
925 #ifdef HAVE_REMOTE_LCD
926 lcd_remote_clear_display();
927 #endif
929 FOR_NB_SCREENS(i)
930 viewportmanager_theme_undo(i, true);
932 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
933 if(open_files != 0 && !current_plugin_handle)
935 int fd;
936 logf("Plugin '%s' leaks file handles", plugin);
938 static const char *lines[] =
939 { ID2P(LANG_PLUGIN_ERROR),
940 "#leak-file-handles" };
941 static const struct text_message message={ lines, 2 };
942 button_clear_queue(); /* Empty the keyboard buffer */
943 gui_syncyesno_run(&message, NULL, NULL);
945 for(fd=0; fd < MAX_OPEN_FILES; fd++)
946 if(open_files & (1<<fd))
947 close_wrapper(fd);
949 #endif
951 if (rc == PLUGIN_ERROR)
952 splash(HZ*2, str(LANG_PLUGIN_ERROR));
954 return rc;
957 /* Returns a pointer to the portion of the plugin buffer that is not already
958 being used. If no plugin is loaded, returns the entire plugin buffer */
959 void* plugin_get_buffer(size_t *buffer_size)
961 int buffer_pos;
963 if (current_plugin_handle)
965 if (plugin_size >= PLUGIN_BUFFER_SIZE)
966 return NULL;
968 *buffer_size = PLUGIN_BUFFER_SIZE-plugin_size;
969 buffer_pos = plugin_size;
971 else
973 *buffer_size = PLUGIN_BUFFER_SIZE;
974 buffer_pos = 0;
977 return &pluginbuf[buffer_pos];
980 /* Returns a pointer to the mp3 buffer.
981 Playback gets stopped, to avoid conflicts.
982 Talk buffer is stolen as well.
984 void* plugin_get_audio_buffer(size_t *buffer_size)
986 audio_stop();
987 return audio_get_buffer(true, buffer_size);
990 /* The plugin wants to stay resident after leaving its main function, e.g.
991 runs from timer or own thread. The callback is registered to later
992 instruct it to free its resources before a new plugin gets loaded. */
993 void plugin_tsr(bool (*exit_callback)(bool))
995 pfn_tsr_exit = exit_callback; /* remember the callback for later */
998 char *plugin_get_current_filename(void)
1000 return current_plugin;
1003 static int open_wrapper(const char* pathname, int flags, ...)
1005 /* we don't have an 'open' function. it's a define. and we need
1006 * the real file_open, hence PREFIX() doesn't work here */
1007 int fd;
1008 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
1009 if (flags & O_CREAT)
1011 va_list ap;
1012 va_start(ap, flags);
1013 fd = open(pathname, flags, va_arg(ap, unsigned int));
1014 va_end(ap);
1016 else
1017 fd = open(pathname, flags);
1018 #else
1019 fd = file_open(pathname,flags);
1020 #endif
1022 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
1023 if(fd >= 0)
1024 open_files |= 1<<fd;
1025 #endif
1026 return fd;
1029 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
1030 static int close_wrapper(int fd)
1032 if((~open_files) & (1<<fd))
1034 logf("double close from plugin");
1036 if(fd >= 0)
1037 open_files &= (~(1<<fd));
1039 return PREFIX(close)(fd);
1042 static int creat_wrapper(const char *pathname, mode_t mode)
1044 (void)mode;
1046 int fd = PREFIX(creat)(pathname, mode);
1048 if(fd >= 0)
1049 open_files |= (1<<fd);
1051 return fd;
1053 #endif /* HAVE_PLUGIN_CHECK_OPEN_CLOSE */