/** * Show an image on the screen at the given location */ static int show_image(ImageInfo *image, int x, int y) { uint32_t inoutsize; void *rawimg; int err; inoutsize = image->original_size; if (COMPRESS_NONE == image->compression) { rawimg = NULL; } else { rawimg = VbExMalloc(inoutsize); if (VbExDecompress(image + 1, image->compressed_size, image->compression, rawimg, &inoutsize)) { return -1; } } err = VbExDisplayImage(x, y, rawimg ? rawimg : image + 1, inoutsize); if (rawimg) VbExFree(rawimg); return err ? -1 : 0; }
void VbRenderTextAtPos(const char *text, int right_to_left, uint32_t x, uint32_t y, VbFont_t *font) { int i; ImageInfo *image_info = 0; void *buffer; uint32_t buffersize; uint32_t cur_x = x, cur_y = y; if (!text || !font) { VBDEBUG((" VbRenderTextAtPos: invalid args\n")); return; } for (i=0; text[i]; i++) { if (text[i] == '\n') { if (!image_info) image_info = VbFindFontGlyph(font, text[i], &buffer, &buffersize); cur_x = x; cur_y += image_info->height; continue; } image_info = VbFindFontGlyph(font, text[i], &buffer, &buffersize); if (right_to_left) cur_x -= image_info->width; if (VBERROR_SUCCESS != VbExDisplayImage(cur_x, cur_y, buffer, buffersize)) { VBDEBUG((" VbRenderTextAtPos: " "can't display ascii 0x%x\n", text[i])); } if (!right_to_left) cur_x += image_info->width; } }
VbError_t VbDisplayScreenFromGBB(VbCommonParams *cparams, uint32_t screen, VbNvContext *vncptr) { char *fullimage = NULL; BmpBlockHeader hdr; uint32_t screen_index; uint32_t localization = 0; VbError_t retval = VBERROR_UNKNOWN; /* Assume error until proven ok */ uint32_t inoutsize; uint32_t i; VbFont_t *font; const char *text_to_show; int rtol = 0; VbError_t ret; ret = VbGbbReadBmpHeader(cparams, &hdr); if (ret) return ret; /* * Translate screen ID into index. Note that not all screens are in * the GBB. * * TODO: ensure screen IDs match indices? Having this translation here * is awful. */ switch (screen) { case VB_SCREEN_DEVELOPER_WARNING: screen_index = SCREEN_DEVELOPER_WARNING; break; case VB_SCREEN_RECOVERY_REMOVE: screen_index = SCREEN_RECOVERY_REMOVE; break; case VB_SCREEN_RECOVERY_NO_GOOD: screen_index = SCREEN_RECOVERY_NO_GOOD; break; case VB_SCREEN_RECOVERY_INSERT: screen_index = SCREEN_RECOVERY_INSERT; break; case VB_SCREEN_RECOVERY_TO_DEV: screen_index = SCREEN_RECOVERY_TO_DEV; break; case VB_SCREEN_DEVELOPER_TO_NORM: screen_index = SCREEN_DEVELOPER_TO_NORM; break; case VB_SCREEN_WAIT: screen_index = SCREEN_WAIT; break; case VB_SCREEN_TO_NORM_CONFIRMED: screen_index = SCREEN_TO_NORM_CONFIRMED; break; case VB_SCREEN_BLANK: case VB_SCREEN_DEVELOPER_EGG: default: /* Screens which aren't in the GBB */ VBDEBUG(("VbDisplayScreenFromGBB(): screen %d not in the GBB\n", (int)screen)); retval = VBERROR_INVALID_SCREEN_INDEX; goto VbDisplayScreenFromGBB_exit; } if (screen_index >= hdr.number_of_screenlayouts) { VBDEBUG(("VbDisplayScreenFromGBB(): " "screen %d index %d not in the GBB\n", (int)screen, (int)screen_index)); retval = VBERROR_INVALID_SCREEN_INDEX; goto VbDisplayScreenFromGBB_exit; } /* Clip localization to number of localizations present in the GBB */ VbNvGet(vncptr, VBNV_LOCALIZATION_INDEX, &localization); if (localization >= hdr.number_of_localizations) { localization = 0; VbNvSet(vncptr, VBNV_LOCALIZATION_INDEX, localization); } /* Display all bitmaps for the image */ for (i = 0; i < MAX_IMAGE_IN_LAYOUT; i++) { ScreenLayout layout; ImageInfo image_info; char hwid[256]; ret = VbGbbReadImage(cparams, localization, screen_index, i, &layout, &image_info, &fullimage, &inoutsize); if (ret == VBERROR_NO_IMAGE_PRESENT) { continue; } else if (ret) { retval = ret; goto VbDisplayScreenFromGBB_exit; } switch(image_info.format) { case FORMAT_BMP: if (i == 0) { /** * In current version GBB bitmaps, first image * is always the background. */ ret = VbExDisplaySetDimension( image_info.width, image_info.height); if (ret) { VBDEBUG(("VbExDisplaySetDimension" "(%d,%d): failed (%#x).\n", image_info.width, image_info.height, ret)); } } retval = VbExDisplayImage(layout.images[i].x, layout.images[i].y, fullimage, inoutsize); break; case FORMAT_FONT: /* * The uncompressed blob is our font structure. Cache * it as needed. */ font = VbInternalizeFontData( (FontArrayHeader *)fullimage); /* TODO: handle text in general here */ if (TAG_HWID == image_info.tag || TAG_HWID_RTOL == image_info.tag) { VbRegionReadHWID(cparams, hwid, sizeof(hwid)); text_to_show = hwid; rtol = (TAG_HWID_RTOL == image_info.tag); } else { text_to_show = ""; rtol = 0; } VbRenderTextAtPos(text_to_show, rtol, layout.images[i].x, layout.images[i].y, font); VbDoneWithFontForNow(font); break; default: VBDEBUG(("VbDisplayScreenFromGBB(): " "unsupported ImageFormat %d\n", image_info.format)); retval = VBERROR_INVALID_GBB; } VbExFree(fullimage); if (VBERROR_SUCCESS != retval) goto VbDisplayScreenFromGBB_exit; } /* Successful if all bitmaps displayed */ retval = VBERROR_SUCCESS; VbRegionCheckVersion(cparams); VbDisplayScreenFromGBB_exit: VBDEBUG(("leaving VbDisplayScreenFromGBB() with %d\n",retval)); return retval; }