__fatal_error(const char *expr, const char *msg, const char *file, int line_num, const char *func) { const BITMAP *icon = &bmp_icon_error; char line[128] = {0}; int y = icon->height + 3; oledClear(); oledDrawBitmap(0, 0, icon); oledDrawStringCenter(OLED_WIDTH / 2, (icon->height - FONT_HEIGHT) / 2 + 1, "FATAL ERROR", FONT_STANDARD); snprintf(line, sizeof(line), "Expr: %s", expr ? expr : "(null)"); oledDrawString(0, y, line, FONT_STANDARD); y += FONT_HEIGHT + 1; snprintf(line, sizeof(line), "Msg: %s", msg ? msg : "(null)"); oledDrawString(0, y, line, FONT_STANDARD); y += FONT_HEIGHT + 1; const char *label = "File: "; snprintf(line, sizeof(line), "%s:%d", file ? file : "(null)", line_num); oledDrawStringRight(OLED_WIDTH - 1, y, line, FONT_STANDARD); oledBox(0, y, oledStringWidth(label, FONT_STANDARD), y + FONT_HEIGHT, false); oledDrawString(0, y, label, FONT_STANDARD); y += FONT_HEIGHT + 1; snprintf(line, sizeof(line), "Func: %s", func ? func : "(null)"); oledDrawString(0, y, line, FONT_STANDARD); y += FONT_HEIGHT + 1; oledDrawString(0, y, "Contact TREZOR support.", FONT_STANDARD); oledRefresh(); shutdown(); }
void oledDrawChar(int x, int y, char c, int font) { if (x >= OLED_WIDTH || y >= OLED_HEIGHT || y <= -FONT_HEIGHT) { return; } int zoom = (font & FONT_DOUBLE ? 2 : 1); int char_width = fontCharWidth(font & 0x7f, c); const uint8_t *char_data = fontCharData(font & 0x7f, c); if (x <= -char_width * zoom) { return; } for (int xo = 0; xo < char_width; xo++) { for (int yo = 0; yo < FONT_HEIGHT; yo++) { if (char_data[xo] & (1 << (FONT_HEIGHT - 1 - yo))) { if (zoom <= 1) { oledDrawPixel(x + xo, y + yo); } else { oledBox(x + xo * zoom, y + yo * zoom, x + (xo + 1) * zoom - 1, y + (yo + 1) * zoom - 1, true); } } } } }
void layoutHome(void) { if (layoutLast == layoutHome || layoutLast == layoutScreensaver) { oledClear(); } else { layoutSwipe(); } layoutLast = layoutHome; const char *label = storage_isInitialized() ? storage_getLabel() : _("Go to trezor.io/start"); const uint8_t *homescreen = storage_getHomescreen(); if (homescreen) { BITMAP b; b.width = 128; b.height = 64; b.data = homescreen; oledDrawBitmap(0, 0, &b); } else { if (label && strlen(label) > 0) { oledDrawBitmap(44, 4, &bmp_logo48); oledDrawStringCenter(OLED_HEIGHT - 8, label, FONT_STANDARD); } else { oledDrawBitmap(40, 0, &bmp_logo64); } } if (storage_noBackup()) { oledBox(0, 0, 127, 8, false); oledDrawStringCenter(0, "SEEDLESS", FONT_STANDARD); } else if (storage_unfinishedBackup()) { oledBox(0, 0, 127, 8, false); oledDrawStringCenter(0, "BACKUP FAILED!", FONT_STANDARD); } else if (storage_needsBackup()) { oledBox(0, 0, 127, 8, false); oledDrawStringCenter(0, "NEEDS BACKUP!", FONT_STANDARD); } oledRefresh(); // Reset lock screen timeout system_millis_lock_start = timer_ms(); }
void layoutProgress(const char *desc, int permil) { oledClear(); layoutProgressUpdate(false); // progressbar oledFrame(0, OLED_HEIGHT - 8, OLED_WIDTH - 1, OLED_HEIGHT - 1); oledBox(1, OLED_HEIGHT - 7, OLED_WIDTH - 2, OLED_HEIGHT - 2, 0); permil = permil * (OLED_WIDTH - 4) / 1000; if (permil < 0) { permil = 0; } if (permil > OLED_WIDTH - 4) { permil = OLED_WIDTH - 4; } oledBox(2, OLED_HEIGHT - 6, 1 + permil, OLED_HEIGHT - 3, 1); // text oledBox(0, OLED_HEIGHT - 16, OLED_WIDTH - 1, OLED_HEIGHT - 16 + 7, 0); if (desc) { oledDrawStringCenter(OLED_HEIGHT - 16, desc); } oledRefresh(); }
void oledDrawChar(int x, int y, char c, int zoom) { int char_width; const uint8_t *char_data; if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return; char_width = fontCharWidth(c); char_data = fontCharData(c); int xo, yo; for (xo = 0; xo < char_width; xo++) { for (yo = 0; yo < FONT_HEIGHT; yo++) { if (char_data[xo] & (1 << (FONT_HEIGHT - 1 - yo))) { if (zoom <= 1) { oledDrawPixel(x + xo, y + yo); } else { oledBox(x + xo * zoom, y + yo * zoom, x + (xo + 1) * zoom - 1, y + (yo + 1) * zoom - 1, true); } } } } }
void layoutAddress(const char *address, const char *desc, bool qrcode, bool ignorecase, const uint32_t *address_n, size_t address_n_count, bool address_is_account) { if (layoutLast != layoutAddress) { layoutSwipe(); } else { oledClear(); } layoutLast = layoutAddress; uint32_t addrlen = strlen(address); if (qrcode) { static unsigned char bitdata[QR_MAX_BITDATA]; char address_upcase[addrlen + 1]; if (ignorecase) { for (uint32_t i = 0; i < addrlen + 1; i++) { address_upcase[i] = address[i] >= 'a' && address[i] <= 'z' ? address[i] + 'A' - 'a' : address[i]; } } int side = qr_encode(addrlen <= (ignorecase ? 60 : 40) ? QR_LEVEL_M : QR_LEVEL_L, 0, ignorecase ? address_upcase : address, 0, bitdata); oledInvert(0, 0, 63, 63); if (side > 0 && side <= 29) { int offset = 32 - side; for (int i = 0; i < side; i++) { for (int j = 0; j< side; j++) { int a = j * side + i; if (bitdata[a / 8] & (1 << (7 - a % 8))) { oledBox(offset + i * 2, offset + j * 2, offset + 1 + i * 2, offset + 1 + j * 2, false); } } } } else if (side > 0 && side <= 60) { int offset = 32 - (side / 2); for (int i = 0; i < side; i++) { for (int j = 0; j< side; j++) { int a = j * side + i; if (bitdata[a / 8] & (1 << (7 - a % 8))) { oledClearPixel(offset + i, offset + j); } } } } } else { if (desc) { oledDrawString(0, 0 * 9, desc, FONT_STANDARD); } if (addrlen > 10) { // don't split short addresses uint32_t rowlen = (addrlen - 1) / (addrlen <= 42 ? 2 : addrlen <= 63 ? 3 : 4) + 1; const char **str = split_message((const uint8_t *)address, addrlen, rowlen); for (int i = 0; i < 4; i++) { oledDrawString(0, (i + 1) * 9 + 4, str[i], FONT_FIXED); } } else { oledDrawString(0, (0 + 1) * 9 + 4, address, FONT_FIXED); } oledDrawString(0, 42, address_n_str(address_n, address_n_count, address_is_account), FONT_STANDARD); } if (!qrcode) { layoutButtonNo(_("QR Code")); } layoutButtonYes(_("Continue")); oledRefresh(); }