/* x,y in pixels */ void screen_put_iconxy(struct screen * display, int xpos, int ypos, enum themable_icons icon) { const void *data; const int screen = display->screen_type; const int width = ICON_WIDTH(screen); const int height = ICON_HEIGHT(screen); const int is_rtl = lang_is_rtl(); int stride; const struct bitmap *iconset; screen_bitmap_part_func *draw_func = NULL; if (icon == Icon_NOICON) { if (is_rtl) xpos = display->getwidth() - xpos - width; screen_clear_area(display, xpos, ypos, width, height); return; } else if (icon >= Icon_Last_Themeable) { iconset = &iconsets[Iconset_viewers][screen].bmp; icon -= Icon_Last_Themeable; if (!iconsets[Iconset_viewers][screen].loaded || (global_status.viewer_icon_count * height > iconset->height) || (icon * height + height > iconset->height)) { screen_put_iconxy(display, xpos, ypos, Icon_Questionmark); return; } } else if (iconsets[Iconset_user][screen].loaded) { iconset = &iconsets[Iconset_user][screen].bmp; } else { iconset = &inbuilt_iconset[screen]; } data = iconset->data; stride = STRIDE(display->screen_type, iconset->width, iconset->height); /* add some left padding to the icons if they are on the edge */ if (xpos == 0) xpos++; if (is_rtl) xpos = display->getwidth() - xpos - width; #if (LCD_DEPTH == 16) || defined(LCD_REMOTE_DEPTH) && (LCD_REMOTE_DEPTH == 16) if (display->depth == 16) draw_func = display->transparent_bitmap_part; else #endif draw_func = display->bitmap_part; draw_func(data, 0, height * icon, stride, xpos, ypos, width, height); }
static void init_tagcache(void) { bool clear = false; #if CONFIG_CODEC == SWCODEC long talked_tick = 0; #endif tagcache_init(); while (!tagcache_is_initialized()) { int ret = tagcache_get_commit_step(); if (ret > 0) { #if CONFIG_CODEC == SWCODEC /* hwcodec can't use voice here, as the database commit * uses the audio buffer. */ if(global_settings.talk_menu && (talked_tick == 0 || TIME_AFTER(current_tick, talked_tick+7*HZ))) { talked_tick = current_tick; talk_id(LANG_TAGCACHE_INIT, false); talk_number(ret, true); talk_id(VOICE_OF, true); talk_number(tagcache_get_max_commit_step(), true); } #endif #ifdef HAVE_LCD_BITMAP if (lang_is_rtl()) { splashf(0, "[%d/%d] %s", ret, tagcache_get_max_commit_step(), str(LANG_TAGCACHE_INIT)); } else { splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT), ret, tagcache_get_max_commit_step()); } #else lcd_double_height(false); lcd_putsf(0, 1, " DB [%d/%d]", ret, tagcache_get_max_commit_step()); lcd_update(); #endif clear = true; } sleep(HZ/4); } tagtree_init(); if (clear) { backlight_on(); show_logo(); } }
static void fix_line_alignment(struct skin_draw_info *info, struct skin_element *element) { struct align_pos *align = &info->align; char *cur_pos = info->cur_align_start + strlen(info->cur_align_start); switch (element->tag->type) { case SKIN_TOKEN_ALIGN_LEFT: *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; align->left = cur_pos; info->cur_align_start = cur_pos; break; case SKIN_TOKEN_ALIGN_LEFT_RTL: *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; if (lang_is_rtl()) align->right = cur_pos; else align->left = cur_pos; info->cur_align_start = cur_pos; break; case SKIN_TOKEN_ALIGN_CENTER: *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; align->center = cur_pos; info->cur_align_start = cur_pos; break; case SKIN_TOKEN_ALIGN_RIGHT: *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; align->right = cur_pos; info->cur_align_start = cur_pos; break; case SKIN_TOKEN_ALIGN_RIGHT_RTL: *cur_pos = '\0'; cur_pos++; *cur_pos = '\0'; if (lang_is_rtl()) align->left = cur_pos; else align->right = cur_pos; info->cur_align_start = cur_pos; break; default: break; } }
/* x,y in pixels */ void screen_put_iconxy(struct screen * display, int xpos, int ypos, enum themable_icons icon) { const int screen = display->screen_type; const int width = ICON_WIDTH(screen); const int height = ICON_HEIGHT(screen); const int is_rtl = lang_is_rtl(); const struct bitmap *iconset; if (icon == Icon_NOICON) { if (is_rtl) xpos = display->getwidth() - xpos - width; screen_clear_area(display, xpos, ypos, width, height); return; } else if (icon >= Icon_Last_Themeable) { iconset = &iconsets[Iconset_viewers][screen].bmp; icon -= Icon_Last_Themeable; if (!iconsets[Iconset_viewers][screen].loaded || (global_status.viewer_icon_count * height > iconset->height) || (icon * height + height > iconset->height)) { screen_put_iconxy(display, xpos, ypos, Icon_Questionmark); return; } } else if (iconsets[Iconset_user][screen].loaded) { iconset = &iconsets[Iconset_user][screen].bmp; } else { iconset = inbuilt_iconset[screen]; } /* add some left padding to the icons if they are on the edge */ if (xpos == 0) xpos++; if (is_rtl) xpos = display->getwidth() - xpos - width; display->bmp_part(iconset, 0, height * icon, xpos, ypos, width, height); }
/* * button is horizontally inverted to support RTL language if the given language * and context combination require that */ static int button_flip_horizontally(int context, int button) { int newbutton; if (!(lang_is_rtl() && ((context == CONTEXT_STD) || (context == CONTEXT_TREE) || (context == CONTEXT_LIST) || (context == CONTEXT_MAINMENU)))) { return button; } newbutton = button & ~(BUTTON_LEFT | BUTTON_RIGHT #if defined(BUTTON_SCROLL_BACK) && defined(BUTTON_SCROLL_FWD) && \ !defined(SIMULATOR) | BUTTON_SCROLL_BACK | BUTTON_SCROLL_FWD #endif #if defined(BUTTON_MINUS) && defined(BUTTON_PLUS) && \ !defined(SIMULATOR) | BUTTON_MINUS | BUTTON_PLUS #endif ); if (button & BUTTON_LEFT) newbutton |= BUTTON_RIGHT; if (button & BUTTON_RIGHT) newbutton |= BUTTON_LEFT; #if defined(BUTTON_SCROLL_BACK) && defined(BUTTON_SCROLL_FWD) && \ !defined(SIMULATOR) if (button & BUTTON_SCROLL_BACK) newbutton |= BUTTON_SCROLL_FWD; if (button & BUTTON_SCROLL_FWD) newbutton |= BUTTON_SCROLL_BACK; #endif #if defined(BUTTON_MINUS) && defined(BUTTON_PLUS) && \ !defined(SIMULATOR) if (button & BUTTON_MINUS) newbutton |= BUTTON_PLUS; if (button & BUTTON_PLUS) newbutton |= BUTTON_MINUS; #endif return newbutton; }
static int browser(void* param) { int ret_val; #ifdef HAVE_TAGCACHE struct tree_context* tc = tree_get_context(); #endif int filter = SHOW_SUPPORTED; char folder[MAX_PATH] = "/"; /* stuff needed to remember position in file browser */ static char last_folder[MAX_PATH] = "/"; /* and stuff for the database browser */ #ifdef HAVE_TAGCACHE static int last_db_dirlevel = 0, last_db_selection = 0; #endif switch ((intptr_t)param) { case GO_TO_FILEBROWSER: filter = global_settings.dirfilter; if (global_settings.browse_current && last_screen == GO_TO_WPS && current_track_path[0]) { strcpy(folder, current_track_path); } else if (!strcmp(last_folder, "/")) { strcpy(folder, global_settings.start_directory); } else { #ifdef HAVE_HOTSWAP bool in_hotswap = false; /* handle entering an ejected drive */ int i; for (i = 0; i < NUM_VOLUMES; i++) { char vol_string[VOL_ENUM_POS + 8]; if (!storage_removable(i)) continue; /* VOL_NAMES contains a %d */ snprintf(vol_string, sizeof(vol_string), "/"VOL_NAMES, i); /* test whether we would browse the external card */ if (!storage_present(i) && (strstr(last_folder, vol_string) #ifdef HAVE_HOTSWAP_STORAGE_AS_MAIN || (i == 0) #endif )) { /* leave folder as "/" to avoid crash when trying * to access an ejected drive */ strcpy(folder, "/"); in_hotswap = true; break; } } if (!in_hotswap) #endif strcpy(folder, last_folder); } break; #ifdef HAVE_TAGCACHE case GO_TO_DBBROWSER: if (!tagcache_is_usable()) { bool reinit_attempted = false; /* Now display progress until it's ready or the user exits */ while(!tagcache_is_usable()) { struct tagcache_stat *stat = tagcache_get_stat(); /* Allow user to exit */ if (action_userabort(HZ/2)) break; /* Maybe just needs to reboot due to delayed commit */ if (stat->commit_delayed) { splash(HZ*2, ID2P(LANG_PLEASE_REBOOT)); break; } /* Check if ready status is known */ if (!stat->readyvalid) { splash(0, str(LANG_TAGCACHE_BUSY)); continue; } /* Re-init if required */ if (!reinit_attempted && !stat->ready && stat->processed_entries == 0 && stat->commit_step == 0) { /* Prompt the user */ reinit_attempted = true; static const char *lines[]={ ID2P(LANG_TAGCACHE_BUSY), ID2P(LANG_TAGCACHE_FORCE_UPDATE)}; static const struct text_message message={lines, 2}; if(gui_syncyesno_run(&message, NULL, NULL) == YESNO_NO) break; int i; FOR_NB_SCREENS(i) screens[i].clear_display(); /* Start initialisation */ tagcache_rebuild(); } /* Display building progress */ static long talked_tick = 0; if(global_settings.talk_menu && (talked_tick == 0 || TIME_AFTER(current_tick, talked_tick+7*HZ))) { talked_tick = current_tick; if (stat->commit_step > 0) { talk_id(LANG_TAGCACHE_INIT, false); talk_number(stat->commit_step, true); talk_id(VOICE_OF, true); talk_number(tagcache_get_max_commit_step(), true); } else if(stat->processed_entries) { talk_number(stat->processed_entries, false); talk_id(LANG_BUILDING_DATABASE, true); } } if (stat->commit_step > 0) { if (lang_is_rtl()) { splashf(0, "[%d/%d] %s", stat->commit_step, tagcache_get_max_commit_step(), str(LANG_TAGCACHE_INIT)); } else { splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT), stat->commit_step, tagcache_get_max_commit_step()); } } else { splashf(0, str(LANG_BUILDING_DATABASE), stat->processed_entries); } } } if (!tagcache_is_usable()) return GO_TO_PREVIOUS; filter = SHOW_ID3DB; tc->dirlevel = last_db_dirlevel; tc->selected_item = last_db_selection; break; #endif case GO_TO_BROWSEPLUGINS: filter = SHOW_PLUGINS; strlcpy(folder, PLUGIN_DIR, MAX_PATH); break; } ret_val = rockbox_browse(folder, filter); switch ((intptr_t)param) { case GO_TO_FILEBROWSER: if (!get_current_file(last_folder, MAX_PATH) || (!strchr(&last_folder[1], '/') && global_settings.start_directory[1] != '\0')) { last_folder[0] = '/'; last_folder[1] = '\0'; } break; #ifdef HAVE_TAGCACHE case GO_TO_DBBROWSER: last_db_dirlevel = tc->dirlevel; last_db_selection = tc->selected_item; break; #endif } return ret_val; }
static int parse_albumart_load(struct skin_element* element, struct wps_token *token, struct wps_data *wps_data) { struct dim dimensions; int albumart_slot; bool swap_for_rtl = lang_is_rtl() && follow_lang_direction; struct skin_albumart *aa = (struct skin_albumart *)skin_buffer_alloc(sizeof(struct skin_albumart)); (void)token; /* silence warning */ if (!aa) return -1; /* reset albumart info in wps */ aa->width = -1; aa->height = -1; aa->xalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ aa->yalign = WPS_ALBUMART_ALIGN_CENTER; /* default */ aa->x = element->params[0].data.number; aa->y = element->params[1].data.number; aa->width = element->params[2].data.number; aa->height = element->params[3].data.number; aa->vp = &curr_vp->vp; aa->draw_handle = -1; /* if we got here, we parsed everything ok .. ! */ if (aa->width < 0) aa->width = 0; else if (aa->width > LCD_WIDTH) aa->width = LCD_WIDTH; if (aa->height < 0) aa->height = 0; else if (aa->height > LCD_HEIGHT) aa->height = LCD_HEIGHT; if (swap_for_rtl) aa->x = LCD_WIDTH - (aa->x + aa->width); aa->state = WPS_ALBUMART_LOAD; wps_data->albumart = aa; dimensions.width = aa->width; dimensions.height = aa->height; albumart_slot = playback_claim_aa_slot(&dimensions); if (0 <= albumart_slot) wps_data->playback_aa_slot = albumart_slot; if (element->params_count > 4 && !isdefault(&element->params[4])) { switch (*element->params[4].data.text) { case 'l': case 'L': if (swap_for_rtl) aa->xalign = WPS_ALBUMART_ALIGN_RIGHT; else aa->xalign = WPS_ALBUMART_ALIGN_LEFT; break; case 'c': case 'C': aa->xalign = WPS_ALBUMART_ALIGN_CENTER; break; case 'r': case 'R': if (swap_for_rtl) aa->xalign = WPS_ALBUMART_ALIGN_LEFT; else aa->xalign = WPS_ALBUMART_ALIGN_RIGHT; break; } } if (element->params_count > 5 && !isdefault(&element->params[5])) { switch (*element->params[5].data.text) { case 't': case 'T': aa->yalign = WPS_ALBUMART_ALIGN_TOP; break; case 'c': case 'C': aa->yalign = WPS_ALBUMART_ALIGN_CENTER; break; case 'b': case 'B': aa->yalign = WPS_ALBUMART_ALIGN_BOTTOM; break; } } return 0; }