void skin_statusbar_changed(struct gui_wps *skin) { if (!skin) return; struct wps_data *data = skin->data; const struct screen *display = skin->display; const int screen = display->screen_type; struct skin_viewport *svp = skin_find_item(VP_DEFAULT_LABEL, SKIN_FIND_VP, data); struct viewport *vp = &svp->vp; viewport_set_defaults(vp, screen); if (data->wps_sb_tag) { /* fix up the default viewport */ if (data->show_sb_on_wps) { if (statusbar_position(screen) != STATUSBAR_OFF) return; /* vp is fixed already */ vp->y = STATUSBAR_HEIGHT; vp->height = display->lcdheight - STATUSBAR_HEIGHT; } else { if (statusbar_position(screen) == STATUSBAR_OFF) return; /* vp is fixed already */ vp->y = vp->x = 0; vp->height = display->lcdheight; vp->width = display->lcdwidth; } } }
static int parse_statusbar_tags(struct skin_element* element, struct wps_token *token, struct wps_data *wps_data) { (void)element; if (token->type == SKIN_TOKEN_DRAW_INBUILTBAR) { token->value.data = (void*)&curr_vp->vp; } else { struct skin_element *def_vp = wps_data->tree; struct skin_viewport *default_vp = def_vp->data; if (def_vp->params_count == 0) { wps_data->wps_sb_tag = true; wps_data->show_sb_on_wps = (token->type == SKIN_TOKEN_ENABLE_THEME); } if (wps_data->show_sb_on_wps) { viewport_set_defaults(&default_vp->vp, curr_screen); } else { viewport_set_fullscreen(&default_vp->vp, curr_screen); } #ifdef HAVE_REMOTE_LCD /* viewport_set_defaults() sets the font to FONT_UI+curr_screen. * This parser requires font 1 to always be the UI font, * so force it back to FONT_UI and handle the screen number at the end */ default_vp->vp.font = FONT_UI; #endif } return 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; }
void gui_buttonbar_init(struct gui_buttonbar * buttonbar) { int i; gui_buttonbar_unset(buttonbar); FOR_NB_SCREENS(i) { viewport_set_defaults(&bb_vp[i], i); bb_vp[i].font = FONT_SYSFIXED; bb_vp[i].y = screens[i].lcdheight - BUTTONBAR_HEIGHT; bb_vp[i].height = BUTTONBAR_HEIGHT; bb_vp[i].drawmode = DRMODE_COMPLEMENT; } }
static void draw_slider(void) { int i; FOR_NB_SCREENS(i) { struct viewport vp; int slider_height = 2*screens[i].getcharheight(); viewport_set_defaults(&vp, i); screens[i].set_viewport(&vp); show_busy_slider(&screens[i], 1, vp.height - slider_height, vp.width-2, slider_height-1); screens[i].update_viewport(); screens[i].set_viewport(NULL); } }
static void usb_screen_fix_viewports(struct screen *screen, struct usb_screen_vps_t *usb_screen_vps) { bool disable = true; int logo_width, logo_height; struct viewport *parent = &usb_screen_vps->parent; struct viewport *logo = &usb_screen_vps->logo; #ifdef HAVE_REMOTE_LCD if (screen->screen_type == SCREEN_REMOTE) { logo_width = BMPWIDTH_remote_usblogo; logo_height = BMPHEIGHT_remote_usblogo; } else #endif { logo_width = BMPWIDTH_usblogo; logo_height = BMPHEIGHT_usblogo; } viewport_set_defaults(parent, screen->screen_type); disable = (parent->width < logo_width || parent->height < logo_height); viewportmanager_theme_enable(screen->screen_type, !disable, parent); *logo = *parent; logo->x = parent->x + parent->width - logo_width; logo->y = parent->y + (parent->height - logo_height) / 2; logo->width = logo_width; logo->height = logo_height; #ifdef USB_ENABLE_HID if (usb_hid) { struct viewport *title = &usb_screen_vps->title; int char_height = font_get(parent->font)->height; *title = *parent; title->y = logo->y + logo->height + char_height; title->height = char_height; /* try to fit logo and title to parent */ if (parent->y + parent->height < title->y + title->height) { logo->y = parent->y; title->y = parent->y + logo->height; } } #endif }
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; }
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(); }
bool alarm_screen(void) { int h, m; bool done = false; struct tm *tm; int togo; int button; bool update = true; bool hour_wrapped = false; struct viewport vp[NB_SCREENS]; rtc_get_alarm(&h, &m); /* After a battery change the RTC values are out of range */ if (m > 60 || h > 24) { m = 0; h = 12; } else { m = m / 5 * 5; /* 5 min accuracy should be enough */ } FOR_NB_SCREENS(i) { viewport_set_defaults(&vp[i], i); } while(!done) { if(update) { FOR_NB_SCREENS(i) { screens[i].set_viewport(&vp[i]); screens[i].clear_viewport(); screens[i].puts(0, 4, str(LANG_ALARM_MOD_KEYS)); } /* Talk when entering the wakeup screen */ speak_time(h, m, true, true); update = false; } FOR_NB_SCREENS(i) { screens[i].set_viewport(&vp[i]); screens[i].putsf(0, 1, str(LANG_ALARM_MOD_TIME)); screens[i].putsf(0, 2, "%02d:%02d", h, m); screens[i].update_viewport(); screens[i].set_viewport(NULL); } button = get_action(CONTEXT_SETTINGS,HZ); switch(button) { case ACTION_STD_OK: /* prevent that an alarm occurs in the shutdown procedure */ /* accept alarms only if they are in 2 minutes or more */ tm = get_time(); togo = (m + h * 60 - tm->tm_min - tm->tm_hour * 60 + 1440) % 1440; if (togo > 1) { rtc_init(); rtc_set_alarm(h,m); rtc_enable_alarm(true); if (global_settings.talk_menu) { talk_id(LANG_ALARM_MOD_TIME_TO_GO, true); talk_value(togo / 60, UNIT_HOUR, true); talk_value(togo % 60, UNIT_MIN, true); talk_force_enqueue_next(); } splashf(HZ*2, str(LANG_ALARM_MOD_TIME_TO_GO), togo / 60, togo % 60); done = true; } else { splash(HZ, ID2P(LANG_ALARM_MOD_ERROR)); update = true; } break; /* inc(m) */ case ACTION_SETTINGS_INC: case ACTION_SETTINGS_INCREPEAT: m += 5; if (m == 60) { h += 1; m = 0; hour_wrapped = true; } if (h == 24) h = 0; speak_time(h, m, hour_wrapped, false); break; /* dec(m) */ case ACTION_SETTINGS_DEC: case ACTION_SETTINGS_DECREPEAT: m -= 5; if (m == -5) { h -= 1; m = 55; hour_wrapped = true; } if (h == -1) h = 23; speak_time(h, m, hour_wrapped, false); break; /* inc(h) */ case ACTION_STD_NEXT: case ACTION_STD_NEXTREPEAT: h = (h+1) % 24; if (global_settings.talk_menu) talk_value(h, UNIT_HOUR, false); break; /* dec(h) */ case ACTION_STD_PREV: case ACTION_STD_PREVREPEAT: h = (h+23) % 24; if (global_settings.talk_menu) talk_value(h, UNIT_HOUR, false); break; case ACTION_STD_CANCEL: rtc_enable_alarm(false); splash(HZ*2, ID2P(LANG_ALARM_MOD_DISABLE)); done = true; break; case ACTION_NONE: hour_wrapped = false; break; default: if(default_event_handler(button) == SYS_USB_CONNECTED) { rtc_enable_alarm(false); return true; } break; } } return false; }
enum yesno_res gui_syncyesno_run(const struct text_message * main_message, const struct text_message * yes_message, const struct text_message * no_message) { int button; int result=-1; bool result_displayed; struct gui_yesno yn[NB_SCREENS]; struct viewport vp[NB_SCREENS]; long talked_tick = 0; FOR_NB_SCREENS(i) { yn[i].main_message=main_message; yn[i].result_message[YESNO_YES]=yes_message; yn[i].result_message[YESNO_NO]=no_message; yn[i].display=&screens[i]; yn[i].vp = &vp[i]; #ifdef HAVE_LCD_CHARCELLS /* Quick fix. Viewports should really be enabled proper for charcell */ viewport_set_defaults(yn[i].vp, i); #else viewportmanager_theme_enable(i, true, yn[i].vp); #endif screens[i].stop_scroll(); gui_yesno_draw(&(yn[i])); } /* make sure to eat any extranous keypresses */ while (get_action(CONTEXT_STD+99, TIMEOUT_NOBLOCK)) action_wait_for_release(); while (result==-1) { /* Repeat the question every 5secs (more or less) */ if (global_settings.talk_menu && (talked_tick==0 || TIME_AFTER(current_tick, talked_tick+HZ*5))) { talked_tick = current_tick; talk_text_message(main_message, false); } button = get_action(CONTEXT_YESNOSCREEN, HZ*5); switch (button) { #ifdef HAVE_TOUCHSCREEN case ACTION_TOUCHSCREEN: { short int x, y; if (action_get_touchscreen_press_in_vp(&x, &y, yn[0].vp) == BUTTON_TOUCHSCREEN) { if (y > yn[0].vp->height/2) { if (x <= yn[0].vp->width/2) result = YESNO_YES; else result = YESNO_NO; } } } break; #endif case ACTION_YESNO_ACCEPT: result=YESNO_YES; break; case ACTION_NONE: case SYS_CHARGER_DISCONNECTED: case SYS_BATTERY_UPDATE: /* ignore some SYS events that can happen */ continue; default: if(default_event_handler(button) == SYS_USB_CONNECTED) return(YESNO_USB); result = YESNO_NO; } } FOR_NB_SCREENS(i) result_displayed=gui_yesno_draw_result(&(yn[i]), result); if (global_settings.talk_menu) { talk_text_message((result == YESNO_YES) ? yes_message : no_message, false); talk_force_enqueue_next(); } if(result_displayed) sleep(HZ); FOR_NB_SCREENS(i) { screens[i].scroll_stop(yn[i].vp); viewportmanager_theme_undo(i, true); } return(result); }
static bool gui_syncquickscreen_run(struct gui_quickscreen * qs, int button_enter) { int button, i, j; 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; FOR_NB_SCREENS(i) { screens[i].set_viewport(NULL); screens[i].stop_scroll(); viewport_set_defaults(&parent[i], 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 (j = 0; j < QUICKSCREEN_ITEM_COUNT; j++) screens[i].scroll_stop(&vps[i][j]); } return changed; }
static int touchscreen_slider(struct screen *display, struct rgb_pick *rgb, int *selected_slider) { short x, y; int char_height, line_height; int max_label_width; int text_top, slider_x, slider_width; bool display_three_rows; int button; int pressed_slider; struct viewport vp; viewport_set_defaults(&vp, display->screen_type); display->set_viewport(&vp); button = action_get_touchscreen_press_in_vp(&x, &y, &vp); if (button == ACTION_UNKNOWN || button == BUTTON_NONE) return ACTION_NONE; /* Get slider positions and top starting position * need vp.y here, because of the statusbar, since touchscreen * coordinates are absolute */ max_label_width = label_get_max_width(display); char_height = display->getcharheight(); text_top = MARGIN_TOP + char_height + TITLE_MARGIN_BOTTOM + SELECTOR_TB_MARGIN; slider_x = SELECTOR_WIDTH + max_label_width + SLIDER_TEXT_MARGIN; slider_width = vp.width - slider_x*2 - max_label_width; line_height = char_height + 2*SELECTOR_TB_MARGIN; /* same logic as in draw_screen */ /* Find out if there's enough room for three sliders or just enough to display the selected slider - calculate total height of display with three sliders present */ display_three_rows = vp.height >= text_top + line_height*3 + /* Title + 3 sliders */ SWATCH_TOP_MARGIN + /* at least 2 lines */ char_height*2 + /* + margins for bottom */ MARGIN_BOTTOM; /* colored rectangle */ display->set_viewport(NULL); if (y < text_top) { if (button == BUTTON_REL) return ACTION_STD_CANCEL; else return ACTION_NONE; } if (y >= text_top + line_height * (display_three_rows ? 3:1)) { /* touching the color area means accept */ if (button == BUTTON_REL) return ACTION_STD_OK; else return ACTION_NONE; } /* y is relative to the original viewport */ pressed_slider = (y - text_top)/line_height; if (pressed_slider != *selected_slider) *selected_slider = pressed_slider; /* add max_label_width to overcome integer division limits, * cap value later since that may lead to an overflow */ if (x < slider_x + (slider_width+max_label_width) && x > slider_x) { char computed_val; x -= slider_x; computed_val = (x*rgb_max[pressed_slider]/(slider_width)); rgb->rgb_val[pressed_slider] = MIN(computed_val,rgb_max[pressed_slider]); pack_rgb(rgb); } return ACTION_NONE; }
static void draw_screen(struct screen *display, char *title, struct rgb_pick *rgb, int row) { unsigned text_color = LCD_BLACK; unsigned background_color = LCD_WHITE; char buf[32]; int i, char_height, line_height; int max_label_width; int text_x, text_top; int slider_x, slider_width; bool display_three_rows; struct viewport vp; viewport_set_defaults(&vp, display->screen_type); display->set_viewport(&vp); display->clear_viewport(); if (display->depth > 1) { text_color = display->get_foreground(); background_color = display->get_background(); } /* Draw title string */ set_drawinfo(display, DRMODE_SOLID, text_color, background_color); vp.flags |= VP_FLAG_ALIGN_CENTER; display->putsxy(0, MARGIN_TOP, title); /* Get slider positions and top starting position */ max_label_width = label_get_max_width(display); char_height = display->getcharheight(); text_top = MARGIN_TOP + char_height + TITLE_MARGIN_BOTTOM + SELECTOR_TB_MARGIN; text_x = SELECTOR_WIDTH; slider_x = text_x + max_label_width + SLIDER_TEXT_MARGIN; slider_width = vp.width - slider_x*2 - max_label_width; line_height = char_height + 2*SELECTOR_TB_MARGIN; /* Find out if there's enough room for three sliders or just enough to display the selected slider - calculate total height of display with three sliders present */ display_three_rows = vp.height >= text_top + line_height*3 + /* Title + 3 sliders */ SWATCH_TOP_MARGIN + /* at least 2 lines */ char_height*2 + /* + margins for bottom */ MARGIN_BOTTOM; /* colored rectangle */ for (i = 0; i < 3; i++) { unsigned sb_flags = HORIZONTAL; int mode = DRMODE_SOLID; unsigned fg = text_color; unsigned bg = background_color; if (i == row) { set_drawinfo(display, DRMODE_SOLID, text_color, background_color); if (global_settings.cursor_style != 0) { /* Draw solid bar selection bar */ display->fillrect(0, text_top - SELECTOR_TB_MARGIN, vp.width, char_height + SELECTOR_TB_MARGIN*2); if (display->depth < 16) { sb_flags |= FOREGROUND | INNER_FILL; mode |= DRMODE_INVERSEVID; } } else if (display_three_rows) { /* Draw "> <" around sliders */ int top = text_top + (char_height - SELECTOR_HEIGHT) / 2; screen_put_iconxy(display, 0, top, Icon_Cursor); screen_put_iconxy(display, vp.width - SELECTOR_WIDTH, top, Icon_Cursor); } if (display->depth >= 16) { sb_flags |= FOREGROUND | INNER_BGFILL; mode = DRMODE_FG; fg = prim_rgb[SB_PRIM][i]; bg = prim_rgb[SB_FILL][i]; } } else if (!display_three_rows) continue; set_drawinfo(display, mode, fg, bg); /* Draw label */ buf[0] = str(LANG_COLOR_RGB_LABELS)[i]; buf[1] = '\0'; vp.flags &= ~VP_FLAG_ALIGNMENT_MASK; display->putsxy(text_x, text_top, buf); /* Draw color value */ snprintf(buf, 3, "%02d", rgb->rgb_val[i]); vp.flags |= VP_FLAG_ALIGN_RIGHT; display->putsxy(text_x, text_top, buf); /* Draw scrollbar */ gui_scrollbar_draw(display, /* screen */ slider_x, /* x */ text_top + char_height / 4, /* y */ slider_width, /* width */ char_height / 2, /* height */ rgb_max[i], /* items */ 0, /* min_shown */ rgb->rgb_val[i], /* max_shown */ sb_flags); /* flags */ /* Advance to next line */ text_top += line_height; } /* end for */ /* Format RGB: #rrggbb */ snprintf(buf, sizeof(buf), str(LANG_COLOR_RGB_VALUE), rgb->red, rgb->green, rgb->blue); vp.flags |= VP_FLAG_ALIGN_CENTER; if (display->depth >= 16) { /* Display color swatch on color screens only */ int top = text_top + SWATCH_TOP_MARGIN; int width = vp.width - text_x*2; int height = vp.height - top - MARGIN_BOTTOM; /* Only draw if room */ if (height >= char_height + 2) { /* draw the big rectangle */ display->set_foreground(rgb->color); display->fillrect(text_x, top, width, height); /* Draw RGB: #rrggbb in middle of swatch */ set_drawinfo(display, DRMODE_FG, get_black_or_white(rgb), background_color); display->putsxy(0, top + (height - char_height) / 2, buf); /* Draw border around the rect */ set_drawinfo(display, DRMODE_SOLID, text_color, background_color); display->drawrect(text_x, top, width, height); } } else { /* Display RGB value only centered on remaining display if room */ int top = text_top + SWATCH_TOP_MARGIN; int height = vp.height - top - MARGIN_BOTTOM; if (height >= char_height) { set_drawinfo(display, DRMODE_SOLID, text_color, background_color); display->putsxy(0, top + (height - char_height) / 2, buf); } } display->update_viewport(); display->set_viewport(NULL); }
void gui_usb_screen_run(void) { int i; 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 #ifndef SIMULATOR usb_acknowledge(SYS_USB_CONNECTED_ACK); #endif #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 } 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(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 */ FOR_NB_SCREENS(i) { screens[i].backlight_on(); viewportmanager_theme_undo(i, false); } }
enum yesno_res gui_syncyesno_run(const struct text_message * main_message, const struct text_message * yes_message, const struct text_message * no_message) { int i; int button; int result=-1; bool result_displayed; struct gui_yesno yn[NB_SCREENS]; struct viewport vp[NB_SCREENS]; long talked_tick = 0; FOR_NB_SCREENS(i) { yn[i].main_message=main_message; yn[i].result_message[YESNO_YES]=yes_message; yn[i].result_message[YESNO_NO]=no_message; yn[i].display=&screens[i]; yn[i].vp = &vp[i]; viewport_set_defaults(yn[i].vp, i); screens[i].stop_scroll(); gui_yesno_draw(&(yn[i])); } while (result==-1) { /* Repeat the question every 5secs (more or less) */ if (global_settings.talk_menu && (talked_tick==0 || TIME_AFTER(current_tick, talked_tick+HZ*5))) { talked_tick = current_tick; talk_text_message(main_message, false); } button = get_action(CONTEXT_YESNOSCREEN, HZ*5); switch (button) { case ACTION_YESNO_ACCEPT: result=YESNO_YES; break; case ACTION_NONE: case SYS_CHARGER_DISCONNECTED: /* ignore some SYS events that can happen */ continue; default: if(default_event_handler(button) == SYS_USB_CONNECTED) return(YESNO_USB); result = YESNO_NO; } } FOR_NB_SCREENS(i) result_displayed=gui_yesno_draw_result(&(yn[i]), result); if (global_settings.talk_menu) { talk_text_message((result == YESNO_YES) ? yes_message : no_message, false); talk_force_enqueue_next(); } if(result_displayed) sleep(HZ); FOR_NB_SCREENS(i) /* stop scrolling before getting out */ screens[i].scroll_stop(yn[i].vp); return(result); }
static void splash_internal(struct screen * screen, const char *fmt, va_list ap) { char splash_buf[MAXBUFFER]; char *lines[MAXLINES]; char *next; char *lastbreak = NULL; char *store = NULL; int line = 0; int x = 0; int y, i; int space_w, w, h; struct viewport vp; #ifdef HAVE_LCD_BITMAP int width, height; int maxw = 0; viewport_set_defaults(&vp, screen->screen_type); screen->set_viewport(&vp); screen->getstringsize(" ", &space_w, &h); #else /* HAVE_LCD_CHARCELLS */ vp.width = screen->lcdwidth; vp.height = screen->lcdheight; space_w = h = 1; screen->double_height (false); #endif y = h; vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap); va_end(ap); /* break splash string into display lines, doing proper word wrap */ next = strtok_r(splash_buf, " ", &store); if (!next) goto end; /* nothing to display */ lines[0] = next; while (true) { #ifdef HAVE_LCD_BITMAP screen->getstringsize(next, &w, NULL); #else w = utf8length(next); #endif if (lastbreak) { if (x + (next - lastbreak) * space_w + w > vp.width - RECT_SPACING*2) { /* too wide, wrap */ #ifdef HAVE_LCD_BITMAP if (x > maxw) maxw = x; #endif if ((y + h > vp.height) || (line >= (MAXLINES-1))) break; /* screen full or out of lines */ x = 0; y += h; lines[++line] = next; } else { /* restore & calculate spacing */ *lastbreak = ' '; x += (next - lastbreak) * space_w; } } x += w; lastbreak = next + strlen(next); next = strtok_r(NULL, " ", &store); if (!next) { /* no more words */ #ifdef HAVE_LCD_BITMAP if (x > maxw) maxw = x; #endif break; } } /* prepare viewport * First boundaries, then the grey filling, then the black border and finally * the text*/ screen->scroll_stop(); #ifdef HAVE_LCD_BITMAP width = maxw + 2*RECT_SPACING; height = y + 2*RECT_SPACING; if (width > vp.width) width = vp.width; if (height > vp.height) height = vp.height; vp.x += (vp.width - width) / 2; vp.y += (vp.height - height) / 2; vp.width = width; vp.height = height; vp.flags |= VP_FLAG_ALIGN_CENTER; #if LCD_DEPTH > 1 if (screen->depth > 1) { vp.drawmode = DRMODE_FG; /* can't do vp.fg_pattern here, since set_foreground does a bit more on * greyscale */ screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY)); } else #endif vp.drawmode = (DRMODE_SOLID|DRMODE_INVERSEVID); screen->fill_viewport(); #if LCD_DEPTH > 1 if (screen->depth > 1) /* can't do vp.fg_pattern here, since set_foreground does a bit more on * greyscale */ screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK)); else #endif vp.drawmode = DRMODE_SOLID; screen->draw_border_viewport(); /* prepare putting the text */ y = RECT_SPACING; #else /* HAVE_LCD_CHARCELLS */ y = 0; /* vertical centering on 2 lines would be silly */ screen->clear_display(); #endif /* print the message to screen */ for (i = 0; i <= line; i++, y+=h) { #ifdef HAVE_LCD_BITMAP screen->putsxy(0, y, lines[i]); #else screen->puts(0, y, lines[i]); #endif } screen->update_viewport(); end: screen->set_viewport(NULL); }
int gui_syncpitchscreen_run(void) { int button, i; 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]; #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 return 0; }
/* finally, assign the font_id to the viewport */ vp->font = font->id; } return success; } #endif /* HAVE_LCD_BITMAP */ static int convert_viewport(struct wps_data *data, struct skin_element* element) { struct skin_viewport *skin_vp = (struct skin_viewport *)skin_buffer_alloc(sizeof(struct skin_viewport)); struct screen *display = &screens[curr_screen]; if (!skin_vp) return CALLBACK_ERROR; skin_vp->hidden_flags = 0; skin_vp->label = NULL; skin_vp->is_infovp = false; element->data = skin_vp; curr_vp = skin_vp; curr_viewport_element = element; viewport_set_defaults(&skin_vp->vp, curr_screen); #ifdef HAVE_REMOTE_LCD /* viewport_set_defaults() sets the font to FONT_UI+curr_screen. * This parser requires font 1 to always be the UI font, * so force it back to FONT_UI and handle the screen number at the end */ skin_vp->vp.font = FONT_UI; #endif #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) skin_vp->start_fgcolour = skin_vp->vp.fg_pattern; skin_vp->start_bgcolour = skin_vp->vp.bg_pattern; #endif struct skin_tag_parameter *param = element->params; if (element->params_count == 0) /* default viewport */ { if (!data->tree) /* first viewport in the skin */ data->tree = element; skin_vp->label = VP_DEFAULT_LABEL; return CALLBACK_OK; } if (element->params_count == 6) { if (element->tag->type == SKIN_TOKEN_UIVIEWPORT_LOAD) { skin_vp->is_infovp = true; if (isdefault(param)) { skin_vp->hidden_flags = VP_NEVER_VISIBLE; skin_vp->label = VP_DEFAULT_LABEL; } else { skin_vp->hidden_flags = VP_NEVER_VISIBLE; skin_vp->label = param->data.text; } } else { skin_vp->hidden_flags = VP_DRAW_HIDEABLE|VP_DRAW_HIDDEN; skin_vp->label = param->data.text; } param++; } /* x */ if (!isdefault(param)) { skin_vp->vp.x = param->data.number; if (param->data.number < 0) skin_vp->vp.x += display->lcdwidth; } param++; /* y */ if (!isdefault(param)) { skin_vp->vp.y = param->data.number; if (param->data.number < 0) skin_vp->vp.y += display->lcdheight; } param++; /* width */ if (!isdefault(param)) { skin_vp->vp.width = param->data.number; if (param->data.number < 0) skin_vp->vp.width = (skin_vp->vp.width + display->lcdwidth) - skin_vp->vp.x; } else { skin_vp->vp.width = display->lcdwidth - skin_vp->vp.x; } param++; /* height */ if (!isdefault(param)) { skin_vp->vp.height = param->data.number; if (param->data.number < 0) skin_vp->vp.height = (skin_vp->vp.height + display->lcdheight) - skin_vp->vp.y; } else { skin_vp->vp.height = display->lcdheight - skin_vp->vp.y; } param++; #ifdef HAVE_LCD_BITMAP /* font */ if (!isdefault(param)) { skin_vp->vp.font = param->data.number; } #endif if ((unsigned) skin_vp->vp.x >= (unsigned) display->lcdwidth || skin_vp->vp.width + skin_vp->vp.x > display->lcdwidth || (unsigned) skin_vp->vp.y >= (unsigned) display->lcdheight || skin_vp->vp.height + skin_vp->vp.y > display->lcdheight) return CALLBACK_ERROR; return CALLBACK_OK; }