keybox: do not leak filehandle when the wrong password is entered.
[maemo-rb.git] / apps / plugin.c
blob9e089518282ef1f2b4b24a035833c901ce271081
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 "buffer.h"
31 #include "backlight.h"
32 #include "sound_menu.h"
33 #include "mp3data.h"
34 #include "powermgmt.h"
35 #include "splash.h"
36 #include "logf.h"
37 #include "option_select.h"
38 #include "talk.h"
39 #include "version.h"
40 #include "storage.h"
41 #include "pcmbuf.h"
42 #include "errno.h"
43 #include "diacritic.h"
44 #include "filefuncs.h"
45 #include "load_code.h"
47 #if CONFIG_CHARGING
48 #include "power.h"
49 #endif
51 #ifdef HAVE_LCD_BITMAP
52 #include "scrollbar.h"
53 #include "peakmeter.h"
54 #include "bmp.h"
55 #include "bidi.h"
56 #endif
58 #ifdef USB_ENABLE_HID
59 #include "usbstack/usb_hid.h"
60 #endif
62 #if (CONFIG_PLATFORM & PLATFORM_SDL)
63 #define PREFIX(_x_) sim_ ## _x_
64 #else
65 #define PREFIX
66 #endif
68 #if defined(HAVE_PLUGIN_CHECK_OPEN_CLOSE) && (MAX_OPEN_FILES>32)
69 #warning "MAX_OPEN_FILES>32, disabling plugin file open/close checking"
70 #undef HAVE_PLUGIN_CHECK_OPEN_CLOSE
71 #endif
73 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
74 static unsigned int open_files;
75 #endif
77 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
78 static unsigned char pluginbuf[PLUGIN_BUFFER_SIZE];
79 void sim_lcd_ex_init(unsigned long (*getpixel)(int, int));
80 void sim_lcd_ex_update_rect(int x, int y, int width, int height);
81 #else
82 extern unsigned char pluginbuf[];
83 #include "bitswap.h"
84 #endif
86 /* for actual plugins only, not for codecs */
87 static int plugin_size = 0;
88 static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */
89 static char current_plugin[MAX_PATH];
90 /* NULL if no plugin is loaded, otherwise the handle that lc_open() returned */
91 static void *current_plugin_handle;
93 char *plugin_get_current_filename(void);
95 /* Some wrappers used to monitor open and close and detect leaks*/
96 static int open_wrapper(const char* pathname, int flags, ...);
97 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
98 static int close_wrapper(int fd);
99 static int creat_wrapper(const char *pathname, mode_t mode);
100 #endif
102 static const struct plugin_api rockbox_api = {
104 /* lcd */
105 #ifdef HAVE_LCD_CONTRAST
106 lcd_set_contrast,
107 #endif
108 lcd_update,
109 lcd_clear_display,
110 lcd_getstringsize,
111 lcd_putsxy,
112 lcd_putsxyf,
113 lcd_puts,
114 lcd_putsf,
115 lcd_puts_scroll,
116 lcd_stop_scroll,
117 #ifdef HAVE_LCD_CHARCELLS
118 lcd_define_pattern,
119 lcd_get_locked_pattern,
120 lcd_unlock_pattern,
121 lcd_putc,
122 lcd_put_cursor,
123 lcd_remove_cursor,
124 lcd_icon,
125 lcd_double_height,
126 #else
127 &lcd_framebuffer[0][0],
128 lcd_update_rect,
129 lcd_set_drawmode,
130 lcd_get_drawmode,
131 lcd_setfont,
132 lcd_drawpixel,
133 lcd_drawline,
134 lcd_hline,
135 lcd_vline,
136 lcd_drawrect,
137 lcd_fillrect,
138 lcd_mono_bitmap_part,
139 lcd_mono_bitmap,
140 #if LCD_DEPTH > 1
141 lcd_set_foreground,
142 lcd_get_foreground,
143 lcd_set_background,
144 lcd_get_background,
145 lcd_bitmap_part,
146 lcd_bitmap,
147 lcd_get_backdrop,
148 lcd_set_backdrop,
149 #endif
150 #if LCD_DEPTH == 16
151 lcd_bitmap_transparent_part,
152 lcd_bitmap_transparent,
153 #if MEMORYSIZE > 2
154 lcd_blit_yuv,
155 #if defined(TOSHIBA_GIGABEAT_F) || defined(SANSA_E200) || defined(SANSA_C200) \
156 || defined(IRIVER_H10) || defined(COWON_D2) || defined(PHILIPS_HDD1630) \
157 || defined(SANSA_FUZE) || defined(SANSA_E200V2) || defined(SANSA_FUZEV2) \
158 || defined(TOSHIBA_GIGABEAT_S)
159 lcd_yuv_set_options,
160 #endif
161 #endif /* MEMORYSIZE > 2 */
162 #elif (LCD_DEPTH < 4) && (CONFIG_PLATFORM & PLATFORM_NATIVE)
163 lcd_blit_mono,
164 lcd_blit_grey_phase,
165 #endif /* LCD_DEPTH */
166 #if defined(HAVE_LCD_MODES) && (HAVE_LCD_MODES & LCD_MODE_PAL256)
167 lcd_blit_pal256,
168 lcd_pal256_update_pal,
169 #endif
170 lcd_puts_style,
171 lcd_puts_scroll_style,
172 #ifdef HAVE_LCD_INVERT
173 lcd_set_invert_display,
174 #endif /* HAVE_LCD_INVERT */
175 #if defined(HAVE_LCD_MODES)
176 lcd_set_mode,
177 #endif
178 #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
179 &button_queue,
180 #endif
181 bidi_l2v,
182 #ifdef HAVE_LCD_BITMAP
183 is_diacritic,
184 #endif
185 font_get_bits,
186 font_load,
187 font_get,
188 font_getstringsize,
189 font_get_width,
190 screen_clear_area,
191 gui_scrollbar_draw,
192 #endif /* HAVE_LCD_BITMAP */
193 get_codepage_name,
195 backlight_on,
196 backlight_off,
197 backlight_set_timeout,
198 #ifdef HAVE_BACKLIGHT_BRIGHTNESS
199 backlight_set_brightness,
200 #endif /* HAVE_BACKLIGHT_BRIGHTNESS */
202 #if CONFIG_CHARGING
203 backlight_set_timeout_plugged,
204 #endif
205 is_backlight_on,
206 splash,
207 splashf,
209 #ifdef HAVE_REMOTE_LCD
210 /* remote lcd */
211 lcd_remote_set_contrast,
212 lcd_remote_clear_display,
213 lcd_remote_puts,
214 lcd_remote_puts_scroll,
215 lcd_remote_stop_scroll,
216 lcd_remote_set_drawmode,
217 lcd_remote_get_drawmode,
218 lcd_remote_setfont,
219 lcd_remote_getstringsize,
220 lcd_remote_drawpixel,
221 lcd_remote_drawline,
222 lcd_remote_hline,
223 lcd_remote_vline,
224 lcd_remote_drawrect,
225 lcd_remote_fillrect,
226 lcd_remote_mono_bitmap_part,
227 lcd_remote_mono_bitmap,
228 lcd_remote_putsxy,
229 lcd_remote_puts_style,
230 lcd_remote_puts_scroll_style,
231 &lcd_remote_framebuffer[0][0],
232 lcd_remote_update,
233 lcd_remote_update_rect,
235 remote_backlight_on,
236 remote_backlight_off,
237 remote_backlight_set_timeout,
238 #if CONFIG_CHARGING
239 remote_backlight_set_timeout_plugged,
240 #endif
241 #endif /* HAVE_REMOTE_LCD */
242 #if NB_SCREENS == 2
243 {&screens[SCREEN_MAIN], &screens[SCREEN_REMOTE]},
244 #else
245 {&screens[SCREEN_MAIN]},
246 #endif
247 #if defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)
248 lcd_remote_set_foreground,
249 lcd_remote_get_foreground,
250 lcd_remote_set_background,
251 lcd_remote_get_background,
252 lcd_remote_bitmap_part,
253 lcd_remote_bitmap,
254 #endif
255 viewport_set_defaults,
256 #ifdef HAVE_LCD_BITMAP
257 viewportmanager_theme_enable,
258 viewportmanager_theme_undo,
259 #endif
261 /* list */
262 gui_synclist_init,
263 gui_synclist_set_nb_items,
264 gui_synclist_set_icon_callback,
265 gui_synclist_get_nb_items,
266 gui_synclist_get_sel_pos,
267 gui_synclist_draw,
268 gui_synclist_select_item,
269 gui_synclist_add_item,
270 gui_synclist_del_item,
271 gui_synclist_limit_scroll,
272 gui_synclist_do_button,
273 gui_synclist_set_title,
274 gui_syncyesno_run,
275 simplelist_info_init,
276 simplelist_show_list,
278 /* button */
279 button_get,
280 button_get_w_tmo,
281 button_status,
282 #ifdef HAVE_BUTTON_DATA
283 button_get_data,
284 button_status_wdata,
285 #endif
286 button_clear_queue,
287 button_queue_count,
288 #ifdef HAS_BUTTON_HOLD
289 button_hold,
290 #endif
291 #ifdef HAVE_TOUCHSCREEN
292 touchscreen_set_mode,
293 #endif
295 #ifdef HAVE_BUTTON_LIGHT
296 buttonlight_set_timeout,
297 buttonlight_off,
298 buttonlight_on,
299 #ifdef HAVE_BUTTONLIGHT_BRIGHTNESS
300 buttonlight_set_brightness,
301 #endif /* HAVE_BUTTONLIGHT_BRIGHTNESS */
302 #endif /* HAVE_BUTTON_LIGHT */
304 /* file */
305 open_utf8,
306 (open_func)open_wrapper,
307 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
308 close_wrapper,
309 #else
310 PREFIX(close),
311 #endif
312 (read_func)PREFIX(read),
313 PREFIX(lseek),
314 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
315 (creat_func)creat_wrapper,
316 #else
317 (creat_func)PREFIX(creat),
318 #endif
319 (write_func)PREFIX(write),
320 PREFIX(remove),
321 PREFIX(rename),
322 PREFIX(ftruncate),
323 PREFIX(filesize),
324 fdprintf,
325 read_line,
326 settings_parseline,
327 storage_sleep,
328 storage_spin,
329 storage_spindown,
330 #if USING_STORAGE_CALLBACK
331 register_storage_idle_func,
332 unregister_storage_idle_func,
333 #endif /* USING_STORAGE_CALLBACK */
334 reload_directory,
335 create_numbered_filename,
336 file_exists,
337 strip_extension,
338 crc_32,
340 /* dir */
341 opendir,
342 closedir,
343 readdir,
344 mkdir,
345 rmdir,
346 dir_exists,
348 /* kernel/ system */
349 #if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE
350 __div0,
351 #endif
352 sleep,
353 yield,
354 &current_tick,
355 default_event_handler,
356 default_event_handler_ex,
357 create_thread,
358 thread_exit,
359 thread_wait,
360 #if (CONFIG_CODEC == SWCODEC)
361 thread_thaw,
362 #ifdef HAVE_PRIORITY_SCHEDULING
363 thread_set_priority,
364 #endif
365 mutex_init,
366 mutex_lock,
367 mutex_unlock,
368 #endif
370 reset_poweroff_timer,
371 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
372 system_memory_guard,
373 &cpu_frequency,
375 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
376 #ifdef CPU_BOOST_LOGGING
377 cpu_boost_,
378 #else
379 cpu_boost,
380 #endif
381 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
382 #endif /* PLATFORM_NATIVE */
383 #ifdef HAVE_SCHEDULER_BOOSTCTRL
384 trigger_cpu_boost,
385 cancel_cpu_boost,
386 #endif
387 #ifdef HAVE_CPUCACHE_FLUSH
388 cpucache_flush,
389 #endif
390 #ifdef HAVE_CPUCACHE_INVALIDATE
391 cpucache_invalidate,
392 #endif
393 timer_register,
394 timer_unregister,
395 timer_set_period,
397 queue_init,
398 queue_delete,
399 queue_post,
400 queue_wait_w_tmo,
401 #if CONFIG_CODEC == SWCODEC
402 queue_enable_queue_send,
403 queue_empty,
404 queue_wait,
405 queue_send,
406 queue_reply,
407 #endif
408 usb_acknowledge,
409 #ifdef USB_ENABLE_HID
410 usb_hid_send,
411 #endif
412 #ifdef RB_PROFILE
413 profile_thread,
414 profstop,
415 __cyg_profile_func_enter,
416 __cyg_profile_func_exit,
417 #endif
418 add_event,
419 remove_event,
420 send_event,
422 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
423 /* special simulator hooks */
424 #if defined(HAVE_LCD_BITMAP) && LCD_DEPTH < 8
425 sim_lcd_ex_init,
426 sim_lcd_ex_update_rect,
427 #endif
428 #endif
430 /* strings and memory */
431 snprintf,
432 vsnprintf,
433 strcpy,
434 strlcpy,
435 strlen,
436 strrchr,
437 strcmp,
438 strncmp,
439 strcasecmp,
440 strncasecmp,
441 memset,
442 memcpy,
443 memmove,
444 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
445 _ctype_,
446 #endif
447 atoi,
448 strchr,
449 strcat,
450 strlcat,
451 memchr,
452 memcmp,
453 strcasestr,
454 strtok_r,
455 /* unicode stuff */
456 utf8decode,
457 iso_decode,
458 utf16LEdecode,
459 utf16BEdecode,
460 utf8encode,
461 utf8length,
462 utf8seek,
464 /* sound */
465 sound_set,
466 sound_default,
467 sound_min,
468 sound_max,
469 sound_unit,
470 sound_val2phys,
471 #ifdef AUDIOHW_HAVE_EQ
472 sound_enum_hw_eq_band_setting,
473 #endif
474 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
475 mp3_play_data,
476 mp3_play_pause,
477 mp3_play_stop,
478 mp3_is_playing,
479 #if CONFIG_CODEC != SWCODEC
480 bitswap,
481 #endif
482 #endif
483 #if CONFIG_CODEC == SWCODEC
484 &audio_master_sampr_list[0],
485 &hw_freq_sampr[0],
486 pcm_apply_settings,
487 pcm_play_data,
488 pcm_play_stop,
489 pcm_set_frequency,
490 pcm_is_playing,
491 pcm_is_paused,
492 pcm_play_pause,
493 pcm_get_bytes_waiting,
494 pcm_calculate_peaks,
495 pcm_get_peak_buffer,
496 pcm_play_lock,
497 pcm_play_unlock,
498 pcmbuf_beep,
499 #ifdef HAVE_RECORDING
500 &rec_freq_sampr[0],
501 pcm_init_recording,
502 pcm_close_recording,
503 pcm_record_data,
504 pcm_stop_recording,
505 pcm_calculate_rec_peaks,
506 audio_set_recording_gain,
507 #endif /* HAVE_RECORDING */
508 #if INPUT_SRC_CAPS != 0
509 audio_set_output_source,
510 audio_set_input_source,
511 #endif
512 dsp_set_crossfeed,
513 dsp_set_eq,
514 dsp_dither_enable,
515 dsp_configure,
516 dsp_process,
517 dsp_input_count,
518 dsp_output_count,
519 #endif /* CONFIG_CODEC == SWCODEC */
521 /* playback control */
522 playlist_amount,
523 playlist_resume,
524 playlist_start,
525 playlist_add,
526 playlist_sync,
527 playlist_remove_all_tracks,
528 playlist_create,
529 playlist_insert_track,
530 playlist_insert_directory,
531 playlist_shuffle,
532 audio_play,
533 audio_stop,
534 audio_pause,
535 audio_resume,
536 audio_next,
537 audio_prev,
538 audio_ff_rewind,
539 audio_next_track,
540 audio_status,
541 audio_current_track,
542 audio_flush_and_reload_tracks,
543 audio_get_file_pos,
544 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
545 mpeg_get_last_header,
546 #endif
547 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) || \
548 (CONFIG_CODEC == SWCODEC)
549 sound_set_pitch,
550 #endif
552 #if !defined(SIMULATOR) && (CONFIG_CODEC != SWCODEC)
553 /* MAS communication */
554 mas_readmem,
555 mas_writemem,
556 mas_readreg,
557 mas_writereg,
558 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
559 mas_codec_writereg,
560 mas_codec_readreg,
561 i2c_begin,
562 i2c_end,
563 i2c_write,
564 #endif
565 #endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
567 /* menu */
568 do_menu,
569 /* statusbars */
570 &statusbars,
571 gui_syncstatusbar_draw,
573 /* options */
574 get_settings_list,
575 find_setting,
576 option_screen,
577 set_option,
578 set_bool_options,
579 set_int,
580 set_bool,
581 #ifdef HAVE_LCD_COLOR
582 set_color,
583 #endif
585 /* action handling */
586 get_custom_action,
587 get_action,
588 #ifdef HAVE_TOUCHSCREEN
589 action_get_touchscreen_press,
590 #endif
591 action_userabort,
593 /* power */
594 battery_level,
595 battery_level_safe,
596 battery_time,
597 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
598 battery_voltage,
599 #endif
600 #if CONFIG_CHARGING
601 charger_inserted,
602 # if CONFIG_CHARGING >= CHARGING_MONITOR
603 charging_state,
604 # endif
605 #endif
606 #ifdef HAVE_USB_POWER
607 usb_powered,
608 #endif
610 /* misc */
611 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
612 &errno,
613 #endif
614 srand,
615 rand,
616 (qsort_func)qsort,
617 kbd_input,
618 get_time,
619 set_time,
620 #if CONFIG_RTC
621 mktime,
622 #endif
623 plugin_get_buffer,
624 plugin_get_audio_buffer,
625 plugin_tsr,
626 plugin_get_current_filename,
627 #if defined(DEBUG) || defined(SIMULATOR)
628 debugf,
629 #endif
630 #ifdef ROCKBOX_HAS_LOGF
631 _logf,
632 #endif
633 &global_settings,
634 &global_status,
635 talk_disable,
636 #if CONFIG_CODEC == SWCODEC
637 codec_thread_do_callback,
638 codec_load_file,
639 get_codec_filename,
640 find_array_ptr,
641 remove_array_ptr,
642 round_value_to_list32,
643 #endif /* CONFIG_CODEC == SWCODEC */
644 get_metadata,
645 mp3info,
646 count_mp3_frames,
647 create_xing_header,
648 find_next_frame,
649 #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F)
650 peak_meter_scale_value,
651 peak_meter_set_use_dbfs,
652 peak_meter_get_use_dbfs,
653 #endif
654 #ifdef HAVE_LCD_BITMAP
655 read_bmp_file,
656 read_bmp_fd,
657 #ifdef HAVE_JPEG
658 read_jpeg_file,
659 read_jpeg_fd,
660 #endif
661 screen_dump_set_hook,
662 #endif
663 show_logo,
664 tree_get_context,
665 set_current_file,
666 set_dirfilter,
668 #ifdef HAVE_WHEEL_POSITION
669 wheel_status,
670 wheel_send_events,
671 #endif
673 #ifdef IRIVER_H100_SERIES
674 /* Routines for the iriver_flash -plugin. */
675 detect_original_firmware,
676 detect_flashed_ramimage,
677 detect_flashed_romimage,
678 #endif
679 led,
680 #if (CONFIG_CODEC == SWCODEC)
681 bufopen,
682 bufalloc,
683 bufclose,
684 bufseek,
685 bufadvance,
686 bufread,
687 bufgetdata,
688 bufgettail,
689 bufcuttail,
691 buf_get_offset,
692 buf_handle_offset,
693 buf_request_buffer_handle,
694 buf_set_base_handle,
695 buf_used,
696 #endif
698 #ifdef HAVE_TAGCACHE
699 tagcache_search,
700 tagcache_search_set_uniqbuf,
701 tagcache_search_add_filter,
702 tagcache_get_next,
703 tagcache_retrieve,
704 tagcache_search_finish,
705 tagcache_get_numeric,
706 #ifdef HAVE_TC_RAMCACHE
707 tagcache_fill_tags,
708 #endif
709 #endif
711 #ifdef HAVE_ALBUMART
712 search_albumart_files,
713 #endif
715 #ifdef HAVE_SEMAPHORE_OBJECTS
716 semaphore_init,
717 semaphore_wait,
718 semaphore_release,
719 #endif
721 rbversion,
723 /* new stuff at the end, sort into place next time
724 the API gets incompatible */
725 dir_get_info,
728 int plugin_load(const char* plugin, const void* parameter)
730 int rc, i;
731 struct plugin_header *hdr;
733 #if LCD_DEPTH > 1
734 fb_data* old_backdrop;
735 #endif
737 if (current_plugin_handle && pfn_tsr_exit)
738 { /* if we have a resident old plugin and a callback */
739 if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false )
741 /* not allowing another plugin to load */
742 return PLUGIN_OK;
744 lc_close(current_plugin_handle);
745 current_plugin_handle = pfn_tsr_exit = NULL;
748 splash(0, ID2P(LANG_WAIT));
749 strcpy(current_plugin, plugin);
751 current_plugin_handle = lc_open(plugin, pluginbuf, PLUGIN_BUFFER_SIZE);
752 if (current_plugin_handle == NULL) {
753 splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
754 return -1;
757 hdr = lc_get_header(current_plugin_handle);
759 if (hdr == NULL
760 || hdr->magic != PLUGIN_MAGIC
761 || hdr->target_id != TARGET_ID
762 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
763 || hdr->load_addr != pluginbuf
764 || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE
765 #endif
768 lc_close(current_plugin_handle);
769 splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
770 return -1;
772 if (hdr->api_version > PLUGIN_API_VERSION
773 || hdr->api_version < PLUGIN_MIN_API_VERSION)
775 lc_close(current_plugin_handle);
776 splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
777 return -1;
779 #if (CONFIG_PLATFORM & PLATFORM_NATIVE)
780 plugin_size = hdr->end_addr - pluginbuf;
781 #else
782 plugin_size = 0;
783 #endif
785 *(hdr->api) = &rockbox_api;
787 #if defined HAVE_LCD_BITMAP && LCD_DEPTH > 1
788 old_backdrop = lcd_get_backdrop();
789 #endif
790 lcd_clear_display();
791 lcd_update();
793 #ifdef HAVE_REMOTE_LCD
794 lcd_remote_clear_display();
795 lcd_remote_update();
796 #endif
798 FOR_NB_SCREENS(i)
799 viewportmanager_theme_enable(i, false, NULL);
801 #ifdef HAVE_TOUCHSCREEN
802 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
803 #endif
805 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
806 open_files = 0;
807 #endif
809 rc = hdr->entry_point(parameter);
811 if (!pfn_tsr_exit)
812 { /* close handle if plugin is no tsr one */
813 lc_close(current_plugin_handle);
814 current_plugin_handle = NULL;
817 /* Go back to the global setting in case the plugin changed it */
818 #ifdef HAVE_TOUCHSCREEN
819 touchscreen_set_mode(global_settings.touch_mode);
820 #endif
822 button_clear_queue();
824 #ifdef HAVE_LCD_BITMAP
825 lcd_setfont(FONT_UI);
826 #if LCD_DEPTH > 1
827 lcd_set_backdrop(old_backdrop);
828 #ifdef HAVE_LCD_COLOR
829 lcd_set_drawinfo(DRMODE_SOLID, global_settings.fg_color,
830 global_settings.bg_color);
831 #else
832 lcd_set_drawinfo(DRMODE_SOLID, LCD_DEFAULT_FG, LCD_DEFAULT_BG);
833 #endif
834 #else /* LCD_DEPTH == 1 */
835 lcd_set_drawmode(DRMODE_SOLID);
836 #endif /* LCD_DEPTH */
837 #endif /* HAVE_LCD_BITMAP */
840 #ifdef HAVE_REMOTE_LCD
841 #if LCD_REMOTE_DEPTH > 1
842 lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
843 LCD_REMOTE_DEFAULT_BG);
844 #else
845 lcd_remote_set_drawmode(DRMODE_SOLID);
846 #endif
847 #endif
849 lcd_clear_display();
850 #ifdef HAVE_REMOTE_LCD
851 lcd_remote_clear_display();
852 #endif
854 FOR_NB_SCREENS(i)
855 viewportmanager_theme_undo(i, false);
857 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
858 if(open_files != 0 && !current_plugin_handle)
860 int fd;
861 logf("Plugin '%s' leaks file handles", plugin);
863 static const char *lines[] =
864 { ID2P(LANG_PLUGIN_ERROR),
865 "#leak-file-handles" };
866 static const struct text_message message={ lines, 2 };
867 button_clear_queue(); /* Empty the keyboard buffer */
868 gui_syncyesno_run(&message, NULL, NULL);
870 for(fd=0; fd < MAX_OPEN_FILES; fd++)
871 if(open_files & (1<<fd))
872 close_wrapper(fd);
874 #endif
876 if (rc == PLUGIN_ERROR)
877 splash(HZ*2, str(LANG_PLUGIN_ERROR));
879 return rc;
882 /* Returns a pointer to the portion of the plugin buffer that is not already
883 being used. If no plugin is loaded, returns the entire plugin buffer */
884 void* plugin_get_buffer(size_t *buffer_size)
886 int buffer_pos;
888 if (current_plugin_handle)
890 if (plugin_size >= PLUGIN_BUFFER_SIZE)
891 return NULL;
893 *buffer_size = PLUGIN_BUFFER_SIZE-plugin_size;
894 buffer_pos = plugin_size;
896 else
898 *buffer_size = PLUGIN_BUFFER_SIZE;
899 buffer_pos = 0;
902 return &pluginbuf[buffer_pos];
905 /* Returns a pointer to the mp3 buffer.
906 Playback gets stopped, to avoid conflicts.
907 Talk buffer is stolen as well.
909 void* plugin_get_audio_buffer(size_t *buffer_size)
911 #if CONFIG_CODEC == SWCODEC
912 return audio_get_buffer(true, buffer_size);
913 #else
914 audio_stop();
915 talk_buffer_steal(); /* we use the mp3 buffer, need to tell */
916 *buffer_size = audiobufend - audiobuf;
917 return audiobuf;
918 #endif
921 /* The plugin wants to stay resident after leaving its main function, e.g.
922 runs from timer or own thread. The callback is registered to later
923 instruct it to free its resources before a new plugin gets loaded. */
924 void plugin_tsr(bool (*exit_callback)(bool))
926 pfn_tsr_exit = exit_callback; /* remember the callback for later */
929 char *plugin_get_current_filename(void)
931 return current_plugin;
934 static int open_wrapper(const char* pathname, int flags, ...)
936 /* we don't have an 'open' function. it's a define. and we need
937 * the real file_open, hence PREFIX() doesn't work here */
938 int fd;
939 #if (CONFIG_PLATFORM & PLATFORM_HOSTED)
940 if (flags & O_CREAT)
942 va_list ap;
943 va_start(ap, flags);
944 fd = open(pathname, flags, va_arg(ap, unsigned int));
945 va_end(ap);
947 else
948 fd = open(pathname, flags);
949 #else
950 fd = file_open(pathname,flags);
951 #endif
953 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
954 if(fd >= 0)
955 open_files |= 1<<fd;
956 #endif
957 return fd;
960 #ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
961 static int close_wrapper(int fd)
963 if((~open_files) & (1<<fd))
965 logf("double close from plugin");
967 if(fd >= 0)
968 open_files &= (~(1<<fd));
970 return PREFIX(close)(fd);
973 static int creat_wrapper(const char *pathname, mode_t mode)
975 int fd = PREFIX(creat)(pathname, mode);
977 if(fd >= 0)
978 open_files |= (1<<fd);
980 return fd;
982 #endif /* HAVE_PLUGIN_CHECK_OPEN_CLOSE */