Exemplo n.º 1
0
int plugin_load(const char* plugin, const void* parameter)
{
    struct plugin_header *p_hdr;
    struct lc_header     *hdr;

    if (current_plugin_handle && pfn_tsr_exit)
    {    /* if we have a resident old plugin and a callback */
        if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false )
        {
            /* not allowing another plugin to load */
            return PLUGIN_OK;
        }
        lc_close(current_plugin_handle);
        current_plugin_handle = pfn_tsr_exit = NULL;
        if (plugin_buffer_handle > 0)
            plugin_buffer_handle = core_free(plugin_buffer_handle);
    }

    splash(0, ID2P(LANG_WAIT));
    strcpy(current_plugin, plugin);

    current_plugin_handle = lc_open(plugin, pluginbuf, PLUGIN_BUFFER_SIZE);
    if (current_plugin_handle == NULL) {
        splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
        return -1;
    }

    p_hdr = lc_get_header(current_plugin_handle);

    hdr = p_hdr ? &p_hdr->lc_hdr : NULL;
    

    if (hdr == NULL
        || hdr->magic != PLUGIN_MAGIC
        || hdr->target_id != TARGET_ID
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
        || hdr->load_addr != pluginbuf
        || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE
#endif
        )
    {
        lc_close(current_plugin_handle);
        splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
        return -1;
    }
    if (hdr->api_version > PLUGIN_API_VERSION
        || hdr->api_version < PLUGIN_MIN_API_VERSION)
    {
        lc_close(current_plugin_handle);
        splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
        return -1;
    }
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
    plugin_size = hdr->end_addr - pluginbuf;
#else
    plugin_size = 0;
#endif

    *(p_hdr->api) = &rockbox_api;

    lcd_clear_display();
    lcd_update();

#ifdef HAVE_REMOTE_LCD
    lcd_remote_clear_display();
    lcd_remote_update();
#endif
    push_current_activity(ACTIVITY_PLUGIN);
    /* some plugins assume the entry cache doesn't move and save pointers to it
     * they should be fixed properly instead of this lock */
    tree_lock_cache(tree_get_context());

    FOR_NB_SCREENS(i)
       viewportmanager_theme_enable(i, false, NULL);
    
#ifdef HAVE_TOUCHSCREEN
    touchscreen_set_mode(TOUCHSCREEN_BUTTON);
#endif

    /* allow voice to back off if the plugin needs lots of memory */
    talk_buffer_set_policy(TALK_BUFFER_LOOSE);

    plugin_check_open_close__enter();

    int rc = p_hdr->entry_point(parameter);
    
    tree_unlock_cache(tree_get_context());
    pop_current_activity();

    if (!pfn_tsr_exit)
    {   /* close handle if plugin is no tsr one */
        lc_close(current_plugin_handle);
        current_plugin_handle = NULL;
        if (plugin_buffer_handle > 0)
            plugin_buffer_handle = core_free(plugin_buffer_handle);
    }

    talk_buffer_set_policy(TALK_BUFFER_DEFAULT);

    /* Go back to the global setting in case the plugin changed it */
#ifdef HAVE_TOUCHSCREEN
    touchscreen_set_mode(global_settings.touch_mode);
#endif

#ifdef HAVE_LCD_BITMAP
    screen_helper_setfont(FONT_UI);
#if LCD_DEPTH > 1
#ifdef HAVE_LCD_COLOR
    lcd_set_drawinfo(DRMODE_SOLID, global_settings.fg_color,
                                   global_settings.bg_color);
#else
    lcd_set_drawinfo(DRMODE_SOLID, LCD_DEFAULT_FG, LCD_DEFAULT_BG);
#endif
#else /* LCD_DEPTH == 1 */
    lcd_set_drawmode(DRMODE_SOLID);
#endif /* LCD_DEPTH */
#endif /* HAVE_LCD_BITMAP */


#ifdef HAVE_REMOTE_LCD
#if LCD_REMOTE_DEPTH > 1
    lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
                            LCD_REMOTE_DEFAULT_BG);
#else
    lcd_remote_set_drawmode(DRMODE_SOLID);
#endif
#endif

    lcd_clear_display();
#ifdef HAVE_REMOTE_LCD
    lcd_remote_clear_display();
#endif

    FOR_NB_SCREENS(i)
        viewportmanager_theme_undo(i, true);

    plugin_check_open_close__exit();

    if (rc == PLUGIN_ERROR)
        splash(HZ*2, str(LANG_PLUGIN_ERROR));

    return rc;
}
Exemplo n.º 2
0
static int browser(void* param)
{
    int ret_val;
#ifdef HAVE_TAGCACHE
    struct tree_context* tc = tree_get_context();
#endif
    int filter = SHOW_SUPPORTED;
    char folder[MAX_PATH] = "/";
    /* stuff needed to remember position in file browser */
    static char last_folder[MAX_PATH] = "/";
    /* and stuff for the database browser */
#ifdef HAVE_TAGCACHE
    static int last_db_dirlevel = 0, last_db_selection = 0;
#endif
    
    switch ((intptr_t)param)
    {
        case GO_TO_FILEBROWSER:
            filter = global_settings.dirfilter;
            if (global_settings.browse_current && 
                    last_screen == GO_TO_WPS &&
                    current_track_path[0])
            {
                strcpy(folder, current_track_path);
            }
            else if (!strcmp(last_folder, "/"))
            {
                strcpy(folder, global_settings.start_directory);
            }
            else
            {
#ifdef HAVE_HOTSWAP
                bool in_hotswap = false;
                /* handle entering an ejected drive */
                int i;
                for (i = 0; i < NUM_VOLUMES; i++)
                {
                    char vol_string[VOL_ENUM_POS + 8];
                    if (!storage_removable(i))
                        continue;
                    /* VOL_NAMES contains a %d */
                    snprintf(vol_string, sizeof(vol_string), "/"VOL_NAMES, i);
                    /* test whether we would browse the external card */
                    if (!storage_present(i) &&
                            (strstr(last_folder, vol_string)
#ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN
                                                                || (i == 0)
#endif
                                                                ))
                    {   /* leave folder as "/" to avoid crash when trying
                         * to access an ejected drive */
                        strcpy(folder, "/");
                        in_hotswap = true;
                        break;
                    }
                }
                if (!in_hotswap)
#endif
                    strcpy(folder, last_folder);
            }
        break;
#ifdef HAVE_TAGCACHE
        case GO_TO_DBBROWSER:
            if (!tagcache_is_usable())
            {
                bool reinit_attempted = false;

                /* Now display progress until it's ready or the user exits */
                while(!tagcache_is_usable())
                {
                    struct tagcache_stat *stat = tagcache_get_stat();                
    
                    /* Allow user to exit */
                    if (action_userabort(HZ/2))
                        break;

                    /* Maybe just needs to reboot due to delayed commit */
                    if (stat->commit_delayed)
                    {
                        splash(HZ*2, ID2P(LANG_PLEASE_REBOOT));
                        break;
                    }

                    /* Check if ready status is known */
                    if (!stat->readyvalid)
                    {
                        splash(0, str(LANG_TAGCACHE_BUSY));
                        continue;
                    }
               
                    /* Re-init if required */
                    if (!reinit_attempted && !stat->ready && 
                        stat->processed_entries == 0 && stat->commit_step == 0)
                    {
                        /* Prompt the user */
                        reinit_attempted = true;
                        static const char *lines[]={
                            ID2P(LANG_TAGCACHE_BUSY), ID2P(LANG_TAGCACHE_FORCE_UPDATE)};
                        static const struct text_message message={lines, 2};
                        if(gui_syncyesno_run(&message, NULL, NULL) == YESNO_NO)
                            break;
                        int i;
                        FOR_NB_SCREENS(i)
                            screens[i].clear_display();

                        /* Start initialisation */
                        tagcache_rebuild();
                    }

                    /* Display building progress */
                    static long talked_tick = 0;
                    if(global_settings.talk_menu &&
                       (talked_tick == 0
                        || TIME_AFTER(current_tick, talked_tick+7*HZ)))
                    {
                        talked_tick = current_tick;
                        if (stat->commit_step > 0)
                        {
                            talk_id(LANG_TAGCACHE_INIT, false);
                            talk_number(stat->commit_step, true);
                            talk_id(VOICE_OF, true);
                            talk_number(tagcache_get_max_commit_step(), true);
                        } else if(stat->processed_entries)
                        {
                            talk_number(stat->processed_entries, false);
                            talk_id(LANG_BUILDING_DATABASE, true);
                        }
                    }
                    if (stat->commit_step > 0)
                    {
                        if (lang_is_rtl())
                        {
                            splashf(0, "[%d/%d] %s", stat->commit_step,
                                tagcache_get_max_commit_step(),
                                str(LANG_TAGCACHE_INIT));
                        }
                        else
                        {
                            splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT),
                                stat->commit_step,
                                tagcache_get_max_commit_step());
                        }
                    }
                    else
                    {
                        splashf(0, str(LANG_BUILDING_DATABASE),
                                   stat->processed_entries);
                    }
                }
            }
            if (!tagcache_is_usable())
                return GO_TO_PREVIOUS;
            filter = SHOW_ID3DB;
            tc->dirlevel = last_db_dirlevel;
            tc->selected_item = last_db_selection;
        break;
#endif
        case GO_TO_BROWSEPLUGINS:
            filter = SHOW_PLUGINS;
            strlcpy(folder, PLUGIN_DIR, MAX_PATH);
        break;
    }
    ret_val = rockbox_browse(folder, filter);
    switch ((intptr_t)param)
    {
        case GO_TO_FILEBROWSER:
            if (!get_current_file(last_folder, MAX_PATH) ||
                (!strchr(&last_folder[1], '/') &&
                 global_settings.start_directory[1] != '\0'))
            {
                last_folder[0] = '/';
                last_folder[1] = '\0';
            }
        break;
#ifdef HAVE_TAGCACHE
        case GO_TO_DBBROWSER:
            last_db_dirlevel = tc->dirlevel;
            last_db_selection = tc->selected_item;
        break;
#endif
    }
    return ret_val;
}  
Exemplo n.º 3
0
int plugin_load(const char* plugin, const void* parameter)
{
    struct plugin_header *p_hdr;
    struct lc_header     *hdr;

    if (current_plugin_handle && pfn_tsr_exit)
    {    /* if we have a resident old plugin and a callback */
        if (pfn_tsr_exit(!strcmp(current_plugin, plugin)) == false )
        {
            /* not allowing another plugin to load */
            return PLUGIN_OK;
        }
        lc_close(current_plugin_handle);
        current_plugin_handle = pfn_tsr_exit = NULL;
    }

    splash(0, ID2P(LANG_WAIT));
    strcpy(current_plugin, plugin);

    current_plugin_handle = lc_open(plugin, pluginbuf, PLUGIN_BUFFER_SIZE);
    if (current_plugin_handle == NULL) {
        splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), plugin);
        return -1;
    }

    p_hdr = lc_get_header(current_plugin_handle);

    hdr = p_hdr ? &p_hdr->lc_hdr : NULL;
    

    if (hdr == NULL
        || hdr->magic != PLUGIN_MAGIC
        || hdr->target_id != TARGET_ID
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
        || hdr->load_addr != pluginbuf
        || hdr->end_addr > pluginbuf + PLUGIN_BUFFER_SIZE
#endif
        )
    {
        lc_close(current_plugin_handle);
        splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
        return -1;
    }
    if (hdr->api_version > PLUGIN_API_VERSION
        || hdr->api_version < PLUGIN_MIN_API_VERSION)
    {
        lc_close(current_plugin_handle);
        splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
        return -1;
    }
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
    plugin_size = hdr->end_addr - pluginbuf;
#else
    plugin_size = 0;
#endif

    *(p_hdr->api) = &rockbox_api;

    lcd_clear_display();
    lcd_update();

#ifdef HAVE_REMOTE_LCD
    lcd_remote_clear_display();
    lcd_remote_update();
#endif
    push_current_activity(ACTIVITY_PLUGIN);
    /* some plugins assume the entry cache doesn't move and save pointers to it
     * they should be fixed properly instead of this lock */
    tree_lock_cache(tree_get_context());

    FOR_NB_SCREENS(i)
       viewportmanager_theme_enable(i, false, NULL);
    
#ifdef HAVE_TOUCHSCREEN
    touchscreen_set_mode(TOUCHSCREEN_BUTTON);
#endif

#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
    open_files = 0;
#endif

    int rc = p_hdr->entry_point(parameter);
    
    tree_unlock_cache(tree_get_context());
    pop_current_activity();

    if (!pfn_tsr_exit)
    {   /* close handle if plugin is no tsr one */
        lc_close(current_plugin_handle);
        current_plugin_handle = NULL;
    }

    /* Go back to the global setting in case the plugin changed it */
#ifdef HAVE_TOUCHSCREEN
    touchscreen_set_mode(global_settings.touch_mode);
#endif

#ifdef HAVE_LCD_BITMAP
    screen_helper_setfont(FONT_UI);
#if LCD_DEPTH > 1
#ifdef HAVE_LCD_COLOR
    lcd_set_drawinfo(DRMODE_SOLID, global_settings.fg_color,
                                   global_settings.bg_color);
#else
    lcd_set_drawinfo(DRMODE_SOLID, LCD_DEFAULT_FG, LCD_DEFAULT_BG);
#endif
#else /* LCD_DEPTH == 1 */
    lcd_set_drawmode(DRMODE_SOLID);
#endif /* LCD_DEPTH */
#endif /* HAVE_LCD_BITMAP */


#ifdef HAVE_REMOTE_LCD
#if LCD_REMOTE_DEPTH > 1
    lcd_remote_set_drawinfo(DRMODE_SOLID, LCD_REMOTE_DEFAULT_FG,
                            LCD_REMOTE_DEFAULT_BG);
#else
    lcd_remote_set_drawmode(DRMODE_SOLID);
#endif
#endif

    lcd_clear_display();
#ifdef HAVE_REMOTE_LCD
    lcd_remote_clear_display();
#endif

    FOR_NB_SCREENS(i)
        viewportmanager_theme_undo(i, true);

#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
    if(open_files != 0 && !current_plugin_handle)
    {
        int fd;
        logf("Plugin '%s' leaks file handles", plugin);
        
        static const char *lines[] = 
            { ID2P(LANG_PLUGIN_ERROR),
              "#leak-file-handles" };
        static const struct text_message message={ lines, 2 };
        button_clear_queue(); /* Empty the keyboard buffer */
        gui_syncyesno_run(&message, NULL, NULL);
        
        for(fd=0; fd < MAX_OPEN_FILES; fd++)
            if(open_files & (1<<fd))
                close_wrapper(fd);
    }
#endif

    if (rc == PLUGIN_ERROR)
        splash(HZ*2, str(LANG_PLUGIN_ERROR));

    return rc;
}