Example #1
0
static inline int load_screen(int screen)
{
    /* set the global_status.last_screen before entering,
        if we dont we will always return to the wrong screen on boot */
    int old_previous = last_screen;
    int ret_val;
    enum current_activity activity = ACTIVITY_UNKNOWN;
    if (screen <= GO_TO_ROOT)
        return screen;
    if (screen == old_previous)
        old_previous = GO_TO_ROOT;
    global_status.last_screen = (char)screen;
    status_save();

    if (screen == GO_TO_BROWSEPLUGINS)
        activity = ACTIVITY_PLUGINBROWSER;
    else if (screen == GO_TO_MAINMENU)
        activity = ACTIVITY_SETTINGS;
    else if (screen == GO_TO_SYSTEM_SCREEN)
        activity =  ACTIVITY_SYSTEMSCREEN;

    if (activity != ACTIVITY_UNKNOWN)
        push_current_activity(activity);

    ret_val = items[screen].function(items[screen].param);

    if (activity != ACTIVITY_UNKNOWN)
        pop_current_activity();

    last_screen = screen;
    if (ret_val == GO_TO_PREVIOUS)
        last_screen = old_previous;
    return ret_val;
}
Example #2
0
static int wpsscrn(void* param)
{
    int ret_val = GO_TO_PREVIOUS;
    (void)param;
    push_current_activity(ACTIVITY_WPS);
    if (audio_status())
    {
        talk_shutup();
        ret_val = gui_wps_show();
    }
    else if ( global_status.resume_index != -1 )
    {
        DEBUGF("Resume index %X offset %lX\n",
               global_status.resume_index,
               (unsigned long)global_status.resume_offset);
        if (playlist_resume() != -1)
        {
            playlist_start(global_status.resume_index,
                global_status.resume_offset);
            ret_val = gui_wps_show();
        }
    }
    else
    {
        splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME));
    }
    pop_current_activity();
    return ret_val;
}
Example #3
0
int time_screen(void* ignored)
{
    (void)ignored;
    int nb_lines, font_h, ret;
    menu_was_pressed = false;

    push_current_activity(ACTIVITY_TIMEDATESCREEN);

    FOR_NB_SCREENS(i)
    {
        viewport_set_defaults(&clock_vps[i], i);
#ifdef HAVE_BUTTONBAR
        if (global_settings.buttonbar)
        {
            clock_vps[i].height -= BUTTONBAR_HEIGHT;
        }
#endif
        nb_lines = viewport_get_nb_lines(&clock_vps[i]);

        gui_synclist_set_viewport_defaults(&menu[i], i);
        /* force time to be drawn centered */
        clock_vps[i].flags |= VP_FLAG_ALIGN_CENTER;

        font_h = font_get(clock_vps[i].font)->height;
        nb_lines -= 2; /* at least 2 lines for menu */
        if (nb_lines > 4)
            nb_lines = 4;
        if (nb_lines >= 2)
            clock_vps[i].height = nb_lines*font_h;
        else /* disable the clock_vps drawing */
            clock_vps[i].height = 0;
        menu[i].y += clock_vps[i].height;
        menu[i].height -= clock_vps[i].height;
        draw_timedate(&clock_vps[i], &screens[i]);
    }

#ifdef SAMSUNG_YH820
    /* some hardware revisions of the yh820 have a rtc problem: if you try to set
       the time/date it will leave the player in an absolute unresponsive state
       which can only be reverted by removing the battery. Setting time/date
       should be prohibited on this targets. Fortunately we can autodetect these,
       because they always report "02:02:02" as time.
    */
    struct tm *tm = get_time();
    if (tm->tm_year==102 && tm->tm_hour==2 && tm->tm_min==2 && tm->tm_sec==2) {
        splash(4*HZ, "Can't set time/date due to hardware issues!");
        return 0;
    }
#endif

    ret = do_menu(&time_menu, NULL, menu, false);
    pop_current_activity();
    /* see comments above in the button callback */
    if (!menu_was_pressed && ret == GO_TO_PREVIOUS)
        return 0;
    return ret;
}
Example #4
0
static int playlist_view_catalog(void * param)
{
    /* kludge untill catalog_view_playlists() returns something useful */
    int old_playstatus = audio_status();
    (void)param;
    push_current_activity(ACTIVITY_PLAYLISTBROWSER);
    catalog_view_playlists();
    pop_current_activity();
    if (!old_playstatus && audio_status())
        return GO_TO_WPS;
    return GO_TO_PREVIOUS;
}
Example #5
0
/* ----------------------------------------------------------------------- */
bool bookmark_mrb_load()
{
    char* bookmark;
    bool ret = false;

    push_current_activity(ACTIVITY_BOOKMARKSLIST);
    select_bookmark(RECENT_BOOKMARK_FILE, false, &bookmark);
    if (bookmark != NULL)
    {
        ret = play_bookmark(bookmark);
    }

    pop_current_activity();
    return ret;
}
Example #6
0
static int playlist_view(void * param)
{
    (void)param;
    int val;

    push_current_activity(ACTIVITY_PLAYLISTVIEWER);
    val = playlist_viewer();
    pop_current_activity();
    switch (val)
    {
        case PLAYLIST_VIEWER_MAINMENU:
        case PLAYLIST_VIEWER_USB:
            return GO_TO_ROOT;
        case PLAYLIST_VIEWER_OK:
            return GO_TO_PREVIOUS;
    }
    return GO_TO_PREVIOUS;
}
Example #7
0
int time_screen(void* ignored)
{
    (void)ignored;
    int nb_lines, font_h, ret;
    menu_was_pressed = false;

    push_current_activity(ACTIVITY_TIMEDATESCREEN);

    FOR_NB_SCREENS(i)
    {
        viewport_set_defaults(&clock_vps[i], i);
#ifdef HAVE_BUTTONBAR
        if (global_settings.buttonbar)
        {
            clock_vps[i].height -= BUTTONBAR_HEIGHT;
        }
#endif
        nb_lines = viewport_get_nb_lines(&clock_vps[i]);

        gui_synclist_set_viewport_defaults(&menu[i], i);
        /* force time to be drawn centered */
        clock_vps[i].flags |= VP_FLAG_ALIGN_CENTER;

        font_h = font_get(clock_vps[i].font)->height;
        nb_lines -= 2; /* at least 2 lines for menu */
        if (nb_lines > 4)
            nb_lines = 4;
        if (nb_lines >= 2)
            clock_vps[i].height = nb_lines*font_h;
        else /* disable the clock_vps drawing */
            clock_vps[i].height = 0;
        menu[i].y += clock_vps[i].height;
        menu[i].height -= clock_vps[i].height;
        draw_timedate(&clock_vps[i], &screens[i]);
    }

    ret = do_menu(&time_menu, NULL, menu, false);
    pop_current_activity();
    /* see comments above in the button callback */
    if (!menu_was_pressed && ret == GO_TO_PREVIOUS)
        return 0;
    return ret;
}
Example #8
0
/* ----------------------------------------------------------------------- */
int bookmark_load_menu(void)
{
    char* bookmark;
    int ret = BOOKMARK_FAIL;

    push_current_activity(ACTIVITY_BOOKMARKSLIST);

    char* name = playlist_get_name(NULL, global_temp_buffer,
                                       sizeof(global_temp_buffer));
    if (generate_bookmark_file_name(name))
    {
        ret = select_bookmark(global_bookmark_file_name, false, &bookmark);
        if (bookmark != NULL)
        {
            ret = play_bookmark(bookmark) ? BOOKMARK_SUCCESS : BOOKMARK_FAIL;
        }
    }

    pop_current_activity();
    return ret;
}
Example #9
0
static int load_context_screen(int selection)
{
    const struct menu_item_ex *context_menu = NULL;
    int retval = GO_TO_PREVIOUS;
    push_current_activity(ACTIVITY_CONTEXTMENU);
    if ((root_menu__[selection]->flags&MENU_TYPE_MASK) == MT_RETURN_VALUE)
    {
        int item = root_menu__[selection]->value;
        context_menu = items[item].context_menu;
    }
    /* special cases */
    else if (root_menu__[selection] == &info_menu)
    {
        context_menu = &system_menu;
    }
    
    if (context_menu)
        retval = do_menu(context_menu, NULL, NULL, false);
    pop_current_activity();
    return retval;
}
Example #10
0
int onplay(char* file, int attr, int from, bool hotkey)
{
    const struct menu_item_ex *menu;
    onplay_result = ONPLAY_OK;
    context = from;
    selected_file = file;
    selected_file_attr = attr;
    int menu_selection;
#ifdef HAVE_HOTKEY
    if (hotkey)
        return execute_hotkey(context == CONTEXT_WPS);
#else
    (void)hotkey;
#endif

    push_current_activity(ACTIVITY_CONTEXTMENU);
    if (context == CONTEXT_WPS)
        menu = &wps_onplay_menu;
    else
        menu = &tree_onplay_menu;
    menu_selection = do_menu(menu, NULL, NULL, false);
    pop_current_activity();

    switch (menu_selection)
    {
        case GO_TO_WPS:
            return ONPLAY_START_PLAY;
        case GO_TO_ROOT:
        case GO_TO_MAINMENU:
            return ONPLAY_MAINMENU;
        case GO_TO_PLAYLIST_VIEWER:
            return ONPLAY_PLAYLIST;
#ifdef HAVE_PICTUREFLOW_INTEGRATION
        case GO_TO_PICTUREFLOW:
            return ONPLAY_PICTUREFLOW;
#endif
        default:
            return onplay_result;
    }
}
Example #11
0
void radio_screen(void)
{
    bool done = false;
    int button;
    bool stereo = false, last_stereo = false;
    int update_type = 0;
    bool screen_freeze = false;
    bool keep_playing = false;
    bool talk = false;
#ifdef FM_RECORD_DBLPRE
    int lastbutton = BUTTON_NONE;
    unsigned long rec_lastclick = 0;
#endif
#if CONFIG_CODEC != SWCODEC
    int timeout = current_tick + HZ/10;
#if !defined(SIMULATOR)
    unsigned int last_seconds = 0;
    unsigned int seconds = 0;
    struct audio_recording_options rec_options;
#endif /* SIMULATOR */
#endif /* CONFIG_CODEC != SWCODEC */
#ifndef HAVE_NOISY_IDLE_MODE
    int button_timeout = current_tick + (2*HZ);
#endif

    /* change status to "in screen" */
    push_current_activity(ACTIVITY_FM);
    in_screen = true;

    if(radio_preset_count() <= 0)
    {
        radio_load_presets(global_settings.fmr_file);
    }
    skin_get_global_state()->id3 = NULL;
#ifdef HAVE_ALBUMART
    radioart_init(true);
#endif    

    if(radio_status == FMRADIO_OFF)
        audio_stop();

    fms_fix_displays(FMS_ENTER);

#ifndef SIMULATOR

#if CONFIG_CODEC != SWCODEC
    rec_create_directory();
    audio_init_recording();

    sound_settings_apply();
    /* Yes, we use the D/A for monitoring */
    peak_meter_playback(true);

    peak_meter_enable(true);

    rec_init_recording_options(&rec_options);
    rec_options.rec_source = AUDIO_SRC_LINEIN;
    rec_set_recording_options(&rec_options);

    audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
            sound_default(SOUND_RIGHT_GAIN), AUDIO_GAIN_LINEIN);

#endif /* CONFIG_CODEC != SWCODEC */
#endif /* ndef SIMULATOR */
    /* turn on radio */
#if CONFIG_CODEC == SWCODEC
    /* This should be done before touching audio settings */
    while (!pcm_is_initialized())
       sleep(0);

    audio_set_input_source(AUDIO_SRC_FMRADIO,
                           (radio_status == FMRADIO_PAUSED) ?
                               SRCF_FMRADIO_PAUSED : SRCF_FMRADIO_PLAYING);
#else
    if (radio_status == FMRADIO_OFF)
        radio_start();
#endif

    if(radio_preset_count() < 1 && yesno_pop(ID2P(LANG_FM_FIRST_AUTOSCAN)))
        presets_scan(NULL);

    preset_set_current(preset_find(curr_freq));
    if(radio_current_preset() != -1)
         radio_mode = RADIO_PRESET_MODE;

    /* Load/update the skin at last, when fully initialzed, so that it can
     * display the right content from the beginning */
    FOR_NB_SCREENS(i)
        skin_update(FM_SCREEN, i, SKIN_REFRESH_ALL);

#ifndef HAVE_NOISY_IDLE_MODE
    cpu_idle_mode(true);
#endif

    while(!done)
    {
        if(search_dir != 0)
        {
            curr_freq = step_freq(curr_freq, search_dir);
            update_type = SKIN_REFRESH_ALL;

            if(tuner_set(RADIO_SCAN_FREQUENCY, curr_freq))
            {
                preset_set_current(preset_find(curr_freq));
                remember_frequency();
                end_search();
                talk = true;
            }
            trigger_cpu_boost();
        }

        if (!update_type)
        {
            cancel_cpu_boost();
        }

        button = fms_do_button_loop(update_type>0);

#ifndef HAVE_NOISY_IDLE_MODE
        if (button != ACTION_NONE)
        {
            cpu_idle_mode(false);
            button_timeout = current_tick + (2*HZ);
        }
#endif
        switch(button)
        {
             case ACTION_FM_STOP:
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
                if(audio_status() == AUDIO_STATUS_RECORD)
                {
                    audio_stop();
                }
                else
#endif
                {
                    done = true;
                    if(presets_have_changed())
                    {
                        if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
                        {
                            presets_save();
                        }
                    }
                }
                update_type = SKIN_REFRESH_NON_STATIC;
                break;

#ifdef FM_RECORD
            case ACTION_FM_RECORD:
#ifdef FM_RECORD_DBLPRE
                if (lastbutton != ACTION_FM_RECORD_DBLPRE)
                {
                    rec_lastclick = 0;
                    break;
                }
                if (current_tick - rec_lastclick > HZ/2)
                {
                    rec_lastclick = current_tick;
                    break;
                }
#endif /* FM_RECORD_DBLPRE */
#ifndef SIMULATOR
                if(audio_status() == AUDIO_STATUS_RECORD)
                {
                    rec_command(RECORDING_CMD_START_NEWFILE);
                    update_type = SKIN_REFRESH_ALL;
                }
                else
                {
                    rec_command(RECORDING_CMD_START);
                    update_type = SKIN_REFRESH_ALL;
                }
#if CONFIG_CODEC != SWCODEC
                last_seconds = 0;
#endif
#endif /* SIMULATOR */
                break;
#endif /* #ifdef FM_RECORD */

            case ACTION_FM_EXIT:
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
                if(audio_status() == AUDIO_STATUS_RECORD)
                    audio_stop();
#endif
                keep_playing = true;
                done = true;
                if(presets_have_changed())
                {
                    if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
                    {
                        presets_save();
                    }
                }

                break;

            case ACTION_STD_PREV:
            case ACTION_STD_NEXT:
                next_station(button == ACTION_STD_PREV ? -1 : 1);
                end_search();
                update_type = SKIN_REFRESH_ALL;
                talk = true;
                break;

            case ACTION_STD_PREVREPEAT:
            case ACTION_STD_NEXTREPEAT:
            {
                int dir = search_dir;
                search_dir = button == ACTION_STD_PREVREPEAT ? -1 : 1;
                if (radio_mode != RADIO_SCAN_MODE)
                {
                    preset_next(search_dir);
                    end_search();
                    talk = true;
                }
                else if (dir == 0)
                {
                    /* Starting auto scan */
                    tuner_set(RADIO_MUTE, 1);
                }
                update_type = SKIN_REFRESH_ALL;
                break;
            }

            case ACTION_SETTINGS_INC:
            case ACTION_SETTINGS_INCREPEAT:
                global_settings.volume++;
                setvol();
                update_type = SKIN_REFRESH_NON_STATIC;
                break;

            case ACTION_SETTINGS_DEC:
            case ACTION_SETTINGS_DECREPEAT:
                global_settings.volume--;
                setvol();
                update_type = SKIN_REFRESH_NON_STATIC;
                break;

            case ACTION_FM_PLAY:
                if (radio_status == FMRADIO_PLAYING)
                    radio_pause();
                else
                    radio_start();

                update_type = SKIN_REFRESH_NON_STATIC;
                talk = false;
                talk_shutup();
                break;

            case ACTION_FM_MENU:
                fms_fix_displays(FMS_EXIT);
                do_menu(&radio_settings_menu, NULL, NULL, false);
                preset_set_current(preset_find(curr_freq));
                fms_fix_displays(FMS_ENTER);
                update_type = SKIN_REFRESH_ALL;
                break;

#ifdef FM_PRESET
            case ACTION_FM_PRESET:
                if(radio_preset_count() < 1)
                {
                    splash(HZ, ID2P(LANG_FM_NO_PRESETS));
                    update_type = SKIN_REFRESH_ALL;
                    break;
                }
                fms_fix_displays(FMS_EXIT);
                handle_radio_presets();
                fms_fix_displays(FMS_ENTER);
                update_type = SKIN_REFRESH_ALL;
                break;
#endif /* FM_PRESET */

#ifdef FM_FREEZE
            case ACTION_FM_FREEZE:
                if(!screen_freeze)
                {
                    splash(HZ, str(LANG_FM_FREEZE));
                    screen_freeze = true;
                }
                else
                {
                    update_type = SKIN_REFRESH_ALL;
                    screen_freeze = false;
                }
                break;
#endif /* FM_FREEZE */

            case SYS_USB_CONNECTED:
#if CONFIG_CODEC != SWCODEC
                /* Only accept USB connection when not recording */
                if(audio_status() != AUDIO_STATUS_RECORD)
#endif
                {
                    default_event_handler(SYS_USB_CONNECTED);
                    screen_freeze = true; /* Cosmetic: makes sure the
                                             radio screen doesn't redraw */
                    done = true;
                }
                break;

#ifdef FM_MODE
           case ACTION_FM_MODE:
                if(radio_mode == RADIO_SCAN_MODE)
                {
                    /* Force scan mode if there are no presets. */
                    if(radio_preset_count() > 0)
                        radio_mode = RADIO_PRESET_MODE;
                }
                else
                    radio_mode = RADIO_SCAN_MODE;
                update_type = SKIN_REFRESH_ALL;
                cond_talk_ids_fq(radio_mode ?
                                 LANG_PRESET : LANG_RADIO_SCAN_MODE);
                talk = true;
                break;
#endif /* FM_MODE */

#ifdef FM_NEXT_PRESET
            case ACTION_FM_NEXT_PRESET:
                preset_next(1);
                end_search();
                update_type = SKIN_REFRESH_ALL;
                talk = true;
                break;
#endif

#ifdef FM_PREV_PRESET
            case ACTION_FM_PREV_PRESET:
                preset_next(-1);
                end_search();
                update_type = SKIN_REFRESH_ALL;
                talk = true;
                break;
#endif
            case ACTION_NONE:
                update_type = SKIN_REFRESH_NON_STATIC;
                break;
             /* this case is used by the softlock feature
              * it requests a full update here */
            case ACTION_REDRAW:
                skin_request_full_update(FM_SCREEN);
                break;

            default:
                default_event_handler(button);
#ifdef HAVE_RDS_CAP
                if (tuner_get(RADIO_EVENT))
                    update_type = SKIN_REFRESH_ALL;
#endif
                if (!tuner_get(RADIO_PRESENT))
                {
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
                    if(audio_status() == AUDIO_STATUS_RECORD)
                        audio_stop();
#endif
                    keep_playing = false;
                    done = true;
                    if(presets_have_changed())
                    {
                        if(yesno_pop(ID2P(LANG_SAVE_CHANGES)))
                        {
                            radio_save_presets();
                        }
                    }

                    /* Clear the preset list on exit. */
                    preset_list_clear();
                }
                break;
        } /*switch(button)*/

#ifdef FM_RECORD_DBLPRE
        if (button != ACTION_NONE)
            lastbutton = button;
#endif

#if CONFIG_CODEC != SWCODEC
        peak_meter_peek();
#endif

        if(!screen_freeze)
        {
            /* Only display the peak meter when not recording */
#if CONFIG_CODEC != SWCODEC
            if(TIME_AFTER(current_tick, timeout))
            {
                timeout = current_tick + HZ;
#else  /* SWCODEC */
            {
#endif /* CONFIG_CODEC == SWCODEC */

                /* keep "mono" from always being displayed when paused */
                if (radio_status != FMRADIO_PAUSED)
                {
                    stereo = tuner_get(RADIO_STEREO) &&
                        !global_settings.fm_force_mono;

                    if(stereo != last_stereo)
                    {
                        update_type = SKIN_REFRESH_ALL;
                        last_stereo = stereo;
                    }
                }
            }

#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
            seconds = audio_recorded_time() / HZ;
            if (update_type || seconds > last_seconds)
            {
                last_seconds = seconds;
#else
            if (update_type)
            {
#endif
                FOR_NB_SCREENS(i)
                    skin_update(FM_SCREEN, i, update_type);
                if (update_type == (int)SKIN_REFRESH_ALL)
                    skin_request_full_update(CUSTOM_STATUSBAR);
            }
        }
        update_type = 0;

        if (global_settings.talk_file && talk
            && radio_status == FMRADIO_PAUSED)
        {
            talk = false;
            bool enqueue = false;
            if (radio_mode == RADIO_SCAN_MODE)
            {
                talk_value_decimal(curr_freq, UNIT_INT, 6, enqueue);
                enqueue = true;
            }
            if (radio_current_preset() >= 0)
                preset_talk(radio_current_preset(), radio_mode == RADIO_PRESET_MODE,
                            enqueue);
        }

#if CONFIG_CODEC != SWCODEC
        if(audio_status() & AUDIO_STATUS_ERROR)
        {
            done = true;
        }
#endif

#ifndef HAVE_NOISY_IDLE_MODE
        if (TIME_AFTER(current_tick, button_timeout))
        {
            cpu_idle_mode(true);
        }
#endif
    } /*while(!done)*/

#ifndef SIMULATOR
#if CONFIG_CODEC != SWCODEC
    if(audio_status() & AUDIO_STATUS_ERROR)
    {
        splash(0, str(LANG_DISK_FULL));
        audio_error_clear();

        while(1)
        {
            button = get_action(CONTEXT_FM|ALLOW_SOFTLOCK, TIMEOUT_BLOCK);
            if(button == ACTION_FM_STOP)
                break;
        }
    }

    audio_init_playback();
#endif /* CONFIG_CODEC != SWCODEC */

    sound_settings_apply();
#endif /* SIMULATOR */

    if(keep_playing)
    {
/* Catch FMRADIO_PLAYING status for the sim. */
#ifndef SIMULATOR
#if CONFIG_CODEC != SWCODEC
        /* Enable the Left and right A/D Converter */
        audio_set_recording_gain(sound_default(SOUND_LEFT_GAIN),
                                 sound_default(SOUND_RIGHT_GAIN),
                                 AUDIO_GAIN_LINEIN);
        mas_codec_writereg(6, 0x4000);
#endif
        end_search();
#endif /* SIMULATOR */
    }
    else
    {
#if CONFIG_CODEC == SWCODEC
        audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
#else
        radio_stop();
#endif
    }

#ifndef HAVE_NOISY_IDLE_MODE
    cpu_idle_mode(false);
#endif
    fms_fix_displays(FMS_EXIT);
    pop_current_activity();
    in_screen = false;
} /* radio_screen */

void toggle_mono_mode(bool mono)
{
    tuner_set(RADIO_FORCE_MONO, mono);
}

void set_radio_region(int region)
{
#ifdef HAVE_RADIO_REGION
    tuner_set(RADIO_REGION, region);
#endif
    next_station(0);
    remember_frequency();
    (void)region;
}
Example #12
0
void gui_usb_screen_run(bool early_usb)
{
    (void) early_usb;
    struct usb_screen_vps_t usb_screen_vps_ar[NB_SCREENS];
#if defined HAVE_TOUCHSCREEN
    enum touchscreen_mode old_mode = touchscreen_get_mode();

    /* TODO: Paint buttons on screens OR switch to point mode and use
     * touchscreen as a touchpad to move the host's mouse cursor */
    touchscreen_set_mode(TOUCHSCREEN_BUTTON);
#endif

    push_current_activity(ACTIVITY_USBSCREEN);

#ifdef USB_ENABLE_HID
    usb_hid = global_settings.usb_hid;
    usb_keypad_mode = global_settings.usb_keypad_mode;
#endif

    FOR_NB_SCREENS(i)
    {
        struct screen *screen = &screens[i];

        screen->set_viewport(NULL);
#ifdef HAVE_LCD_CHARCELLS
        /* Quick fix. Viewports should really be enabled proper for charcell */
        viewport_set_defaults(&usb_screen_vps_ar[i].parent, i);
#else
        usb_screen_fix_viewports(screen, &usb_screen_vps_ar[i]);
#endif
    }

    /* update the UI before disabling fonts, this maximizes the propability
     * that font cache lookups succeed during USB */
    send_event(GUI_EVENT_ACTIONUPDATE, NULL);
#ifdef HAVE_LCD_BITMAP
    if(!early_usb)
    {
        /* The font system leaves the .fnt fd's open, so we need for force close them all */
        font_disable_all();
    }
#endif

    usb_acknowledge(SYS_USB_CONNECTED_ACK);

    while (1)
    {
        usb_screens_draw(usb_screen_vps_ar);
#ifdef SIMULATOR
        if (button_get_w_tmo(HZ/2))
            break;
        send_event(GUI_EVENT_ACTIONUPDATE, NULL);
#else
        if (handle_usb_events())
            break;
#endif /* SIMULATOR */
    }

    FOR_NB_SCREENS(i)
    {
        const struct viewport* vp = NULL;

#if defined(HAVE_LCD_BITMAP) && defined(USB_ENABLE_HID)
        vp = usb_hid ? &usb_screen_vps_ar[i].title : NULL;
#elif !defined(HAVE_LCD_BITMAP)
        vp = &usb_screen_vps_ar[i].parent;
#endif
        if (vp)
            screens[i].scroll_stop_viewport(vp);
    }
#ifdef USB_ENABLE_HID
    if (global_settings.usb_keypad_mode != usb_keypad_mode)
    {
        global_settings.usb_keypad_mode = usb_keypad_mode;
        settings_save();
    }
#endif

#ifdef HAVE_TOUCHSCREEN
    touchscreen_set_mode(old_mode);
#endif

#ifdef HAVE_LCD_CHARCELLS
    status_set_usb(false);
#endif /* HAVE_LCD_CHARCELLS */

#ifdef HAVE_LCD_BITMAP
    if(!early_usb)
    {
        font_enable_all();
        /* Not pretty, reload all settings so fonts are loaded again correctly */
        settings_apply(true);
        /* Reload playlist */
        playlist_resume();
    }
#endif

    FOR_NB_SCREENS(i)
    {
        screens[i].backlight_on();
        viewportmanager_theme_undo(i, false);
    }

    pop_current_activity();
}
Example #13
0
int gui_syncpitchscreen_run(void)
{
    int button;
    int32_t pitch = sound_get_pitch();
    int32_t semitone;

    int32_t new_pitch;
    int32_t pitch_delta;
    bool nudged = false;
    bool exit = false;
    /* should maybe be passed per parameter later, not needed for now */
    struct viewport parent[NB_SCREENS];
    struct viewport pitch_viewports[NB_SCREENS][PITCH_ITEM_COUNT];
    int max_lines[NB_SCREENS];

    push_current_activity(ACTIVITY_PITCHSCREEN);

#if CONFIG_CODEC == SWCODEC
    int32_t new_speed = 0, new_stretch;

    /* the speed variable holds the apparent speed of the playback */
    int32_t speed;
    if (dsp_timestretch_available())
    {
        speed = GET_SPEED(pitch, dsp_get_timestretch());
    }
    else
    {
        speed = pitch;
    }

    /* Figure out whether to be in timestretch mode */
    if (global_settings.pitch_mode_timestretch && !dsp_timestretch_available())
    {
        global_settings.pitch_mode_timestretch = false;
        settings_save();
    }
#endif

    /* set the semitone index based on the current pitch */
    semitone = get_semitone_from_pitch(pitch);

    /* initialize pitchscreen vps */
    FOR_NB_SCREENS(i)
    {
        viewport_set_defaults(&parent[i], i);
        max_lines[i] = viewport_get_nb_lines(&parent[i]);
        pitchscreen_fix_viewports(&parent[i], pitch_viewports[i]);
        screens[i].set_viewport(&parent[i]);
        screens[i].clear_viewport();

        /* also, draw the icons now, it's only needed once */
        pitchscreen_draw_icons(&screens[i], &parent[i]);
    }
#if CONFIG_CODEC == SWCODEC
    pcmbuf_set_low_latency(true);
#endif

    while (!exit)
    {
        FOR_NB_SCREENS(i)
            pitchscreen_draw(&screens[i], max_lines[i],
                              pitch_viewports[i], pitch, semitone
#if CONFIG_CODEC == SWCODEC
                              , speed
#endif
                              );
        pitch_delta = 0;
#if CONFIG_CODEC == SWCODEC
        new_speed = 0;
#endif
        button = get_action(CONTEXT_PITCHSCREEN, HZ);
        
#ifdef HAVE_TOUCHSCREEN
        if (button == ACTION_TOUCHSCREEN)
        {
            FOR_NB_SCREENS(i)
                button = pitchscreen_do_touchscreen(pitch_viewports[i]);
        }
#endif
        switch (button)
        {
            case ACTION_PS_INC_SMALL:
                if(global_settings.pitch_mode_semitone)
                    pitch_delta = SEMITONE_SMALL_DELTA;
                else 
                    pitch_delta = PITCH_SMALL_DELTA;
                break;

            case ACTION_PS_INC_BIG:
                if(global_settings.pitch_mode_semitone)
                    pitch_delta = SEMITONE_BIG_DELTA;
                else 
                    pitch_delta = PITCH_BIG_DELTA;
                break;

            case ACTION_PS_DEC_SMALL:
                if(global_settings.pitch_mode_semitone)
                    pitch_delta = -SEMITONE_SMALL_DELTA;
                else 
                    pitch_delta = -PITCH_SMALL_DELTA;
                break;

            case ACTION_PS_DEC_BIG:
                if(global_settings.pitch_mode_semitone)
                    pitch_delta = -SEMITONE_BIG_DELTA;
                else 
                    pitch_delta = -PITCH_BIG_DELTA;
                break;

            case ACTION_PS_NUDGE_RIGHT:
#if CONFIG_CODEC == SWCODEC
                if (!global_settings.pitch_mode_timestretch)
                {
#endif
                    new_pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false
#if CONFIG_CODEC == SWCODEC
                                               , speed
#endif                            
                        );
                    nudged = (new_pitch != pitch);
                    pitch = new_pitch;
                    semitone = get_semitone_from_pitch(pitch);
#if CONFIG_CODEC == SWCODEC
                    speed = pitch;
#endif
                    break;
#if CONFIG_CODEC == SWCODEC
                }
                else
                {
                    new_speed = speed + SPEED_SMALL_DELTA;
                    at_limit = false;
                }
                break;

            case ACTION_PS_FASTER:
                if (global_settings.pitch_mode_timestretch)
                {
                    new_speed = speed + SPEED_BIG_DELTA;
                    /* snap to whole numbers */
                    if(new_speed % PITCH_SPEED_PRECISION != 0)
                        new_speed -= new_speed % PITCH_SPEED_PRECISION;
                    at_limit = false;
                }
                break;
#endif

            case ACTION_PS_NUDGE_RIGHTOFF:
                if (nudged)
                {
                    pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false
#if CONFIG_CODEC == SWCODEC
                                           , speed
#endif                            
                        );
#if CONFIG_CODEC == SWCODEC
                    speed = pitch;
#endif
                    semitone = get_semitone_from_pitch(pitch);
                    nudged = false;
                }
                break;

            case ACTION_PS_NUDGE_LEFT:
#if CONFIG_CODEC == SWCODEC
                if (!global_settings.pitch_mode_timestretch)
                {
#endif
                    new_pitch = pitch_increase(pitch, -PITCH_NUDGE_DELTA, false
#if CONFIG_CODEC == SWCODEC
                                               , speed
#endif                            
                        );
                    nudged = (new_pitch != pitch);
                    pitch = new_pitch;
                    semitone = get_semitone_from_pitch(pitch);
#if CONFIG_CODEC == SWCODEC
                    speed = pitch;
#endif
                    break;
#if CONFIG_CODEC == SWCODEC
                }
                else
                {
                    new_speed = speed - SPEED_SMALL_DELTA;
                    at_limit = false;
                }
                break;

            case ACTION_PS_SLOWER:
                if (global_settings.pitch_mode_timestretch)
                {
                    new_speed = speed - SPEED_BIG_DELTA;
                    /* snap to whole numbers */
                    if(new_speed % PITCH_SPEED_PRECISION != 0)
                        new_speed += PITCH_SPEED_PRECISION - speed % PITCH_SPEED_PRECISION;
                    at_limit = false;
                }
                break;
#endif

            case ACTION_PS_NUDGE_LEFTOFF:
                if (nudged)
                {
                    pitch = pitch_increase(pitch, PITCH_NUDGE_DELTA, false
#if CONFIG_CODEC == SWCODEC
                                           , speed
#endif                            
                        );
#if CONFIG_CODEC == SWCODEC
                    speed = pitch;
#endif
                    semitone = get_semitone_from_pitch(pitch);
                    nudged = false;
                }
                break;

            case ACTION_PS_RESET:
                pitch = PITCH_SPEED_100;
                sound_set_pitch(pitch);
#if CONFIG_CODEC == SWCODEC
                speed = PITCH_SPEED_100;
                if (dsp_timestretch_available())
                {
                    dsp_set_timestretch(PITCH_SPEED_100);
                    at_limit = false;
                }
#endif
                semitone = get_semitone_from_pitch(pitch);
                break;

            case ACTION_PS_TOGGLE_MODE:
                global_settings.pitch_mode_semitone = !global_settings.pitch_mode_semitone;
#if CONFIG_CODEC == SWCODEC

                if (dsp_timestretch_available() && !global_settings.pitch_mode_semitone)
                {
                    global_settings.pitch_mode_timestretch = !global_settings.pitch_mode_timestretch;
                    if(!global_settings.pitch_mode_timestretch)
                    {
                        /* no longer in timestretch mode.  Reset speed */
                        speed = pitch;
                        dsp_set_timestretch(PITCH_SPEED_100);
                    }
                }
                settings_save();
#endif
                break;

            case ACTION_PS_EXIT:
                exit = true;
                break;

            default:
                if (default_event_handler(button) == SYS_USB_CONNECTED)
                    return 1;
                break;
        }
        if (pitch_delta)
        {
            if (global_settings.pitch_mode_semitone)
            {
                semitone = pitch_increase_semitone(pitch, semitone, pitch_delta
#if CONFIG_CODEC == SWCODEC
                                                , speed
#endif                            
                );
                pitch = get_pitch_from_semitone(semitone);
            }
            else
            {
                pitch = pitch_increase(pitch, pitch_delta, true
#if CONFIG_CODEC == SWCODEC
                                       , speed
#endif                            
                );
                semitone = get_semitone_from_pitch(pitch);
            }
#if CONFIG_CODEC == SWCODEC
            if (global_settings.pitch_mode_timestretch)
            {
                /* do this to make sure we properly obey the stretch limits */
                new_speed = speed;
            }
            else
            {
                speed = pitch;
            }
#endif
        }

#if CONFIG_CODEC == SWCODEC
        if(new_speed)
        {
            new_stretch = GET_STRETCH(pitch, new_speed);

            /* limit the amount of stretch */
            if(new_stretch > STRETCH_MAX)
            {
                new_stretch = STRETCH_MAX;
                new_speed = GET_SPEED(pitch, new_stretch);
            }
            else if(new_stretch < STRETCH_MIN)
            {
                new_stretch = STRETCH_MIN;
                new_speed = GET_SPEED(pitch, new_stretch);
            }

            new_stretch = GET_STRETCH(pitch, new_speed);
            if(new_stretch >= STRETCH_MAX || 
               new_stretch <= STRETCH_MIN)
            {
                at_limit = true;
            }

            /* set the amount of stretch */
            dsp_set_timestretch(new_stretch);

            /* update the speed variable with the new speed */
            speed = new_speed;

            /* Reset new_speed so we only call dsp_set_timestretch */
            /* when needed                                         */
            new_speed = 0;
        }
#endif
    }
#if CONFIG_CODEC == SWCODEC
    pcmbuf_set_low_latency(false);
#endif
    pop_current_activity();
    return 0;
}
Example #14
0
static int browser(void* param)
{
    int ret_val;
#ifdef HAVE_TAGCACHE
    struct tree_context* tc = tree_get_context();
#endif
    struct browse_context browse;
    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);
            }
            push_current_activity(ACTIVITY_FILEBROWSER);
        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;
                        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;
            push_current_activity(ACTIVITY_DATABASEBROWSER);
        break;
#endif
    }

    browse_context_init(&browse, filter, 0, NULL, NOICON, folder, NULL);
    ret_val = rockbox_browse(&browse);
    pop_current_activity();
    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;
}
/* Main viewer function.  Filename identifies playlist to be viewed.  If NULL,
   view current playlist. */
enum playlist_viewer_result playlist_viewer_ex(const char* filename)
{
    enum playlist_viewer_result ret = PLAYLIST_VIEWER_OK;
    bool exit = false;        /* exit viewer */
    int button;
    bool dirty = false;
    struct gui_synclist playlist_lists;
    if (!playlist_viewer_init(&viewer, filename, false))
        goto exit;

    push_current_activity(ACTIVITY_PLAYLISTVIEWER);
    gui_synclist_init(&playlist_lists, playlist_callback_name,
                      &viewer, false, 1, NULL);
    gui_synclist_set_voice_callback(&playlist_lists, playlist_callback_voice);
    gui_synclist_set_icon_callback(&playlist_lists,
                  global_settings.playlist_viewer_icons?
                  &playlist_callback_icons:NULL);
    gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks);
    gui_synclist_set_title(&playlist_lists, str(LANG_PLAYLIST), Icon_Playlist);
    gui_synclist_select_item(&playlist_lists, viewer.selected_track);
    gui_synclist_draw(&playlist_lists);
    gui_synclist_speak_item(&playlist_lists);
    while (!exit)
    {
        int track;

        if (global_status.resume_index != -1 && !viewer.playlist)
            playlist_get_resume_info(&track);
        else
            track = -1;

        if (track != viewer.current_playing_track ||
            playlist_amount_ex(viewer.playlist) != viewer.num_tracks)
        {
            /* Playlist has changed (new track started?) */
            if (!update_playlist(false))
                goto exit;
            /*Needed because update_playlist gives wrong value when
                                                            playing is stopped*/
            viewer.current_playing_track = track;
            gui_synclist_set_nb_items(&playlist_lists, viewer.num_tracks);

            gui_synclist_draw(&playlist_lists);
        }

        /* Timeout so we can determine if play status has changed */
        bool res = list_do_action(CONTEXT_TREE, HZ/2,
                            &playlist_lists, &button, LIST_WRAP_UNLESS_HELD);
        /* during moving, another redraw is going to be needed,
         * since viewer.selected_track is updated too late (after the first draw)
         * drawing the moving item needs it */
        viewer.selected_track=gui_synclist_get_sel_pos(&playlist_lists);
        if (res)
        {
            bool reload = playlist_buffer_needs_reload(&viewer.buffer,
                    viewer.selected_track);
            if (reload)
                playlist_buffer_load_entries_screen(&viewer.buffer,
                    button == ACTION_STD_NEXT ? FORWARD : BACKWARD);
            if (reload || viewer.moving_track >= 0)
                gui_synclist_draw(&playlist_lists);
        }
        switch (button)
        {
            case ACTION_TREE_WPS:
            case ACTION_STD_CANCEL:
            {
                if (viewer.moving_track >= 0)
                {
                    viewer.selected_track = viewer.moving_track;
                    gui_synclist_select_item(&playlist_lists, viewer.moving_track);
                    viewer.moving_track = -1;
                    viewer.moving_playlist_index = -1;
                    gui_synclist_draw(&playlist_lists);
                }
                else
                {
                    exit = true;
                    ret = PLAYLIST_VIEWER_CANCEL;
                }
                break;
            }
            case ACTION_STD_OK:
            {
                struct playlist_entry * current_track =
                            playlist_buffer_get_track(&viewer.buffer,
                                                      viewer.selected_track);

                if (viewer.moving_track >= 0)
                {
                    /* Move track */
                    int ret_val;

                    ret_val = playlist_move(viewer.playlist,
                                            viewer.moving_playlist_index,
                                            current_track->index);
                    if (ret_val < 0)
                         splashf(HZ, (unsigned char *)"%s %s", str(LANG_MOVE),
                                                               str(LANG_FAILED));
                    update_playlist(true);
                    viewer.moving_track = -1;
                    viewer.moving_playlist_index = -1;
                    dirty = true;
                }
                else if (!viewer.playlist)
                {
                    /* play new track */
                    if (!global_settings.party_mode)
                    {
                        playlist_start(current_track->index, 0);
                        update_playlist(false);
                    }
                }
                else if (!global_settings.party_mode)
                {
                    int start_index = current_track->index;
                    if (!warn_on_pl_erase())
                    {
                        gui_synclist_draw(&playlist_lists);
                        break;
                    }
                    /* New playlist */
                    if (playlist_set_current(viewer.playlist) < 0)
                        goto exit;
                    if (global_settings.playlist_shuffle)
                        start_index = playlist_shuffle(current_tick, start_index);
                    playlist_start(start_index, 0);

                    /* Our playlist is now the current list */
                    if (!playlist_viewer_init(&viewer, NULL, true))
                        goto exit;
                    exit = true;
                }
                gui_synclist_draw(&playlist_lists);

                break;
            }
            case ACTION_STD_CONTEXT:
            {
                /* ON+PLAY menu */
                int ret_val;

                ret_val = onplay_menu(viewer.selected_track);

                if (ret_val < 0)
                {
                    ret = PLAYLIST_VIEWER_USB;
                    goto exit;
                }
                else if (ret_val > 0)
                {
                    /* Playlist changed */
                    gui_synclist_del_item(&playlist_lists);
                    update_playlist(true);
                    if (viewer.num_tracks <= 0)
                        exit = true;
                    if (viewer.selected_track >= viewer.num_tracks)
                        viewer.selected_track = viewer.num_tracks-1;
                    dirty = true;
                }
                gui_synclist_draw(&playlist_lists);
                break;
            }
            case ACTION_STD_MENU:
                ret = PLAYLIST_VIEWER_MAINMENU;
                goto exit;
            default:
                if(default_event_handler(button) == SYS_USB_CONNECTED)
                {
                    ret = PLAYLIST_VIEWER_USB;
                    goto exit;
                }
                break;
        }
    }

exit:
    pop_current_activity();
    if (viewer.playlist)
    {
        if(dirty && yesno_pop(ID2P(LANG_SAVE_CHANGES)))
            save_playlist_screen(viewer.playlist);
        playlist_close(viewer.playlist);
    }
    return ret;
}
Example #16
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;
}
Example #17
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;
}
static bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter)
{
    int button;
    struct viewport parent[NB_SCREENS];
    struct viewport vps[NB_SCREENS][QUICKSCREEN_ITEM_COUNT];
    struct viewport vp_icons[NB_SCREENS];
    bool changed = false;
    /* To quit we need either :
     *  - a second press on the button that made us enter
     *  - an action taken while pressing the enter button,
     *    then release the enter button*/
    bool can_quit = false;
    
    push_current_activity(ACTIVITY_QUICKSCREEN);
    
    FOR_NB_SCREENS(i)
    {
        screens[i].set_viewport(NULL);
        screens[i].stop_scroll();
        viewportmanager_theme_enable(i, true, &parent[i]);
        quickscreen_fix_viewports(qs, &screens[i], &parent[i], vps[i], &vp_icons[i]);
        gui_quickscreen_draw(qs, &screens[i], &parent[i], vps[i], &vp_icons[i]);
    }
    /* Announce current selection on entering this screen. This is all
       queued up, but can be interrupted as soon as a setting is
       changed. */
    cond_talk_ids(VOICE_QUICKSCREEN);
    talk_qs_option(qs->items[QUICKSCREEN_TOP], true);
    talk_qs_option(qs->items[QUICKSCREEN_LEFT], true);
    talk_qs_option(qs->items[QUICKSCREEN_BOTTOM], true);
    talk_qs_option(qs->items[QUICKSCREEN_RIGHT], true);
    while (true) {
        button = get_action(CONTEXT_QUICKSCREEN, HZ/5);
#ifdef HAVE_TOUCHSCREEN
        if (button == ACTION_TOUCHSCREEN)
            button = quickscreen_touchscreen_button(vps[SCREEN_MAIN]);
#endif
        if (default_event_handler(button) == SYS_USB_CONNECTED)
            return(true);
        if (gui_quickscreen_do_button(qs, button))
        {
            changed = true;
            can_quit = true;
            FOR_NB_SCREENS(i)
                gui_quickscreen_draw(qs, &screens[i], &parent[i],
                                     vps[i], &vp_icons[i]);
            if (qs->callback)
                qs->callback(qs);
        }
        else if (button == button_enter)
            can_quit = true;

        if ((button == button_enter) && can_quit)
            break;

        if (button == ACTION_STD_CANCEL)
            break;
    }
    /* Notify that we're exiting this screen */
    cond_talk_ids_fq(VOICE_OK);
    FOR_NB_SCREENS(i)
    {   /* stop scrolling before exiting */
        for (int j = 0; j < QUICKSCREEN_ITEM_COUNT; j++)
            screens[i].scroll_stop(&vps[i][j]);
        viewportmanager_theme_undo(i, true);
    }

    pop_current_activity();
    return changed;
}
int do_shortcut_menu(void *ignored)
{
    (void)ignored;
    struct simplelist_info list;
    struct shortcut *sc;
    int done = GO_TO_PREVIOUS;
    if (first_handle == 0)
        shortcuts_init();
    simplelist_info_init(&list, P2STR(ID2P(LANG_SHORTCUTS)), shortcut_count, NULL);
    list.get_name = shortcut_menu_get_name;
    list.action_callback = shortcut_menu_get_action;
    if (global_settings.show_icons)
        list.get_icon = shortcut_menu_get_icon;
    list.title_icon = Icon_Bookmark;
    if (global_settings.talk_menu)
        list.get_talk = shortcut_menu_speak_item;

    push_current_activity(ACTIVITY_SHORTCUTSMENU);

    while (done == GO_TO_PREVIOUS)
    {
        if (simplelist_show_list(&list))
            break; /* some error happened?! */
        if (list.selection == -1)
            break;
        else
        {
            sc = get_shortcut(list.selection);
            if (!sc)
                continue;
            switch (sc->type)
            {
                case SHORTCUT_PLAYLISTMENU:
                    if (!file_exists(sc->u.path))
                    {
                        splash(HZ, ID2P(LANG_NO_FILES));
                        break;
                    }
                    else
                    {
                        onplay_show_playlist_menu(sc->u.path);
                    }
                    break;
                case SHORTCUT_FILE:
                    if (!file_exists(sc->u.path))
                    {
                        splash(HZ, ID2P(LANG_NO_FILES));
                        break;
                    }
                    /* else fall through */
                case SHORTCUT_BROWSER:
                {
                    struct browse_context browse;
                    browse_context_init(&browse, global_settings.dirfilter, 0,
                            NULL, NOICON, sc->u.path, NULL);
                    if (sc->type == SHORTCUT_FILE)
                        browse.flags |= BROWSE_RUNFILE;
                    done = rockbox_browse(&browse);
                }
                break;
                case SHORTCUT_SETTING:
                    do_setting_screen(sc->u.setting,
                            sc->name[0] ? sc->name : P2STR(ID2P(sc->u.setting->lang_id)),NULL);
                    break;
                case SHORTCUT_DEBUGITEM:
                    run_debug_screen(sc->u.path);
                    break;
                case SHORTCUT_SHUTDOWN:
#if CONFIG_CHARGING
                    if (charger_inserted())
                        charging_splash();
                    else
#endif
                        sys_poweroff();
                    break;
                case SHORTCUT_TIME:
#if CONFIG_RTC
                  if (sc->u.timedata.talktime) {
                        talk_timedate();
                        talk_force_enqueue_next();
                  } else
#endif
                    {
                        char timer_buf[10];
                        set_sleep_timer(sc->u.timedata.sleep_timeout * 60);
                        splashf(HZ, "%s (%s)", str(LANG_SLEEP_TIMER), 
                                sleep_timer_formatter(timer_buf, sizeof(timer_buf),
                                                      sc->u.timedata.sleep_timeout, NULL));
                    }
                    break;
                case SHORTCUT_UNDEFINED:
                default:
                    break;
            }
        }
    }
    pop_current_activity();
    return done;
}