feat(core): allow different screens sizes for TT UI

[no changelog]
tychovrahe/bluetooth/master
tychovrahe 1 year ago
parent 2cb681f334
commit 357c2c6313

@ -32,8 +32,8 @@ enum SafetyCheckLevel {
* Format of the homescreen image
*/
enum HomescreenFormat {
Toif144x144 = 1;
Jpeg240x240 = 2;
Toif = 1;
Jpeg = 2;
}
/**
@ -121,8 +121,11 @@ message Features {
optional uint32 display_rotation = 39; // in degrees from North
optional bool experimental_features = 40; // are experimental message types enabled?
optional bool busy = 41; // is the device busy, showing "Do not disconnect"?
optional HomescreenFormat homescreen_format = 42; // format of the homescreen, 1 = TOIf 144x144, 2 = jpg 240x240
optional HomescreenFormat homescreen_format = 42; // format of the homescreen, 1 = TOIf, 2 = jpg
optional bool hide_passphrase_from_host = 43; // should we hide the passphrase when it comes from host?
optional uint32 homescreen_width = 44; // homescreen width in pixels
optional uint32 homescreen_height = 45; // homescreen height in pixels
}
/**

@ -295,6 +295,8 @@ fn generate_trezorhal_bindings() {
.allowlist_function("display_sync")
.allowlist_var("DISPLAY_CMD_ADDRESS")
.allowlist_var("DISPLAY_DATA_ADDRESS")
.allowlist_var("DISPLAY_RESX")
.allowlist_var("DISPLAY_RESY")
.allowlist_type("toif_format_t")
// fonts
.allowlist_function("font_height")

@ -4,6 +4,8 @@ use cty::c_int;
use crate::trezorhal::buffers::BufferText;
pub use ffi::{DISPLAY_RESX, DISPLAY_RESY};
#[derive(PartialEq, Debug, Eq, FromPrimitive, Clone, Copy)]
pub enum ToifFormat {
FullColorBE = ffi::toif_format_t_TOIF_FULL_COLOR_BE as _,

@ -1,7 +1,9 @@
use crate::ui::geometry::{Offset, Point, Rect};
pub const WIDTH: i16 = 128;
pub const HEIGHT: i16 = 128;
use crate::trezorhal::display::{DISPLAY_RESX, DISPLAY_RESY};
pub const WIDTH: i16 = DISPLAY_RESX as _;
pub const HEIGHT: i16 = DISPLAY_RESY as _;
pub const LINE_SPACE: i16 = 1;
pub const FONT_BPP: i16 = 1;

@ -1,7 +1,9 @@
use crate::ui::geometry::{Offset, Point, Rect};
pub const WIDTH: i16 = 240;
pub const HEIGHT: i16 = 240;
use crate::trezorhal::display::{DISPLAY_RESX, DISPLAY_RESY};
pub const WIDTH: i16 = DISPLAY_RESX as _;
pub const HEIGHT: i16 = DISPLAY_RESY as _;
pub const LINE_SPACE: i16 = 4;
pub const FONT_BPP: i16 = 4;

@ -1,6 +1,11 @@
#ifndef _STM32F429I_DISC1_H
#define _STM32F429I_DISC1_H
#define MAX_DISPLAY_RESX 240
#define MAX_DISPLAY_RESY 320
#define DISPLAY_RESX 240
#define DISPLAY_RESY 320
#define USE_I2C 1
#define USE_TOUCH 1
#define USE_BLE 1

@ -1,6 +1,9 @@
#ifndef _TREZOR_T_H
#define _TREZOR_T_H
#define DISPLAY_RESX 240
#define DISPLAY_RESY 240
#define USE_SD_CARD 1
#define USE_I2C 1
#define USE_TOUCH 1

@ -4,10 +4,6 @@
#include STM32_HAL_H
#define MAX_DISPLAY_RESX 240
#define MAX_DISPLAY_RESY 320
#define DISPLAY_RESX 240
#define DISPLAY_RESY 240
#define TREZOR_FONT_BPP 4
extern uint8_t *const DISPLAY_DATA_ADDRESS;

@ -6,8 +6,6 @@
// ILI9341V, GC9307 and ST7789V drivers support 240px x 320px display resolution
#define MAX_DISPLAY_RESX 240
#define MAX_DISPLAY_RESY 320
#define DISPLAY_RESX 240
#define DISPLAY_RESY 240
#define TREZOR_FONT_BPP 4
#ifdef USE_DISP_I8080_16BIT_DW

@ -46,6 +46,7 @@ def get_features() -> Features:
from trezor import sdcard
from trezor.enums import Capability
from trezor.messages import Features
from trezor.ui import WIDTH, HEIGHT
from apps.common import mnemonic, safety_checks
@ -63,7 +64,9 @@ def get_features() -> Features:
pin_protection=config.has_pin(),
unlocked=config.is_unlocked(),
busy=busy_expiry_ms() > 0,
homescreen_format=HomescreenFormat.Jpeg240x240,
homescreen_format=HomescreenFormat.Jpeg,
homescreen_width=WIDTH,
homescreen_height=HEIGHT,
)
if utils.BITCOIN_ONLY:

@ -16,6 +16,7 @@ BRT_PROTECT_CALL = ButtonRequestType.ProtectCall # CACHE
def _validate_homescreen(homescreen: bytes) -> None:
import trezorui2
import storage.device as storage_device
from trezor.ui import WIDTH, HEIGHT
if homescreen == b"":
return
@ -29,8 +30,8 @@ def _validate_homescreen(homescreen: bytes) -> None:
w, h, mcu_height = trezorui2.jpeg_info(homescreen)
except ValueError:
raise DataError("Invalid homescreen")
if w != 240 or h != 240:
raise DataError("Homescreen must be 240x240 pixel large")
if w != WIDTH or h != HEIGHT:
raise DataError(f"Homescreen must be {WIDTH}x{HEIGHT} pixel large")
if mcu_height > 16:
raise DataError("Unsupported jpeg type")
try:

@ -2,5 +2,5 @@
# fmt: off
# isort:skip_file
Toif144x144 = 1
Jpeg240x240 = 2
Toif = 1
Jpeg = 2

@ -415,8 +415,8 @@ if TYPE_CHECKING:
PromptTemporarily = 2
class HomescreenFormat(IntEnum):
Toif144x144 = 1
Jpeg240x240 = 2
Toif = 1
Jpeg = 2
class Capability(IntEnum):
Bitcoin = 1

@ -2178,6 +2178,8 @@ if TYPE_CHECKING:
busy: "bool | None"
homescreen_format: "HomescreenFormat | None"
hide_passphrase_from_host: "bool | None"
homescreen_width: "int | None"
homescreen_height: "int | None"
def __init__(
self,
@ -2222,6 +2224,8 @@ if TYPE_CHECKING:
busy: "bool | None" = None,
homescreen_format: "HomescreenFormat | None" = None,
hide_passphrase_from_host: "bool | None" = None,
homescreen_width: "int | None" = None,
homescreen_height: "int | None" = None,
) -> None:
pass

@ -61,7 +61,7 @@ def image_to_t1(filename: Path) -> bytes:
return image.tobytes("raw", "1")
def image_to_toif_144x144(filename: Path) -> bytes:
def image_to_toif(filename: Path, width: int, height: int) -> bytes:
if filename.suffix == ".toif":
try:
toif_image = toif.from_bytes(filename.read_bytes())
@ -82,8 +82,8 @@ def image_to_toif_144x144(filename: Path) -> bytes:
"Failed to convert image to Trezor format"
) from e
if toif_image.size != (144, 144):
raise click.ClickException("Wrong size of image - should be 144x144")
if toif_image.size != (width, height):
raise click.ClickException(f"Wrong size of image - should be {width}x{height}")
if toif_image.mode != toif.ToifMode.full_color:
raise click.ClickException("Wrong image mode - should be full_color")
@ -91,7 +91,7 @@ def image_to_toif_144x144(filename: Path) -> bytes:
return toif_image.to_bytes()
def image_to_jpeg_240x240(filename: Path) -> bytes:
def image_to_jpeg(filename: Path, width: int, height: int) -> bytes:
if filename.suffix in (".jpg", ".jpeg") and not PIL_AVAILABLE:
click.echo("Warning: Image library is missing, skipping image validation.")
return filename.read_bytes()
@ -106,7 +106,7 @@ def image_to_jpeg_240x240(filename: Path) -> bytes:
except Exception as e:
raise click.ClickException("Failed to open image") from e
if image.size != (240, 240):
if image.size != (width, height):
raise click.ClickException("Wrong size of image - should be 240x240")
if image.mode != "RGB":
@ -237,17 +237,33 @@ def homescreen(client: "TrezorClient", filename: str) -> str:
if client.features.model == "1":
img = image_to_t1(path)
else:
if (
client.features.homescreen_format
== messages.HomescreenFormat.Jpeg240x240
):
img = image_to_jpeg_240x240(path)
if client.features.homescreen_format == messages.HomescreenFormat.Jpeg:
width = (
client.features.homescreen_width
if client.features.homescreen_width is not None
else 240
)
height = (
client.features.homescreen_height
if client.features.homescreen_height is not None
else 240
)
img = image_to_jpeg(path, width, height)
elif (
client.features.homescreen_format
== messages.HomescreenFormat.Toif144x144
client.features.homescreen_format == messages.HomescreenFormat.Toif
or client.features.homescreen_format is None
):
img = image_to_toif_144x144(path)
width = (
client.features.homescreen_width
if client.features.homescreen_width is not None
else 144
)
height = (
client.features.homescreen_height
if client.features.homescreen_height is not None
else 144
)
img = image_to_toif(path, width, height)
else:
raise click.ClickException(
"Unknown image format requested by the device."

@ -445,8 +445,8 @@ class SafetyCheckLevel(IntEnum):
class HomescreenFormat(IntEnum):
Toif144x144 = 1
Jpeg240x240 = 2
Toif = 1
Jpeg = 2
class Capability(IntEnum):
@ -3226,6 +3226,8 @@ class Features(protobuf.MessageType):
41: protobuf.Field("busy", "bool", repeated=False, required=False, default=None),
42: protobuf.Field("homescreen_format", "HomescreenFormat", repeated=False, required=False, default=None),
43: protobuf.Field("hide_passphrase_from_host", "bool", repeated=False, required=False, default=None),
44: protobuf.Field("homescreen_width", "uint32", repeated=False, required=False, default=None),
45: protobuf.Field("homescreen_height", "uint32", repeated=False, required=False, default=None),
}
def __init__(
@ -3272,6 +3274,8 @@ class Features(protobuf.MessageType):
busy: Optional["bool"] = None,
homescreen_format: Optional["HomescreenFormat"] = None,
hide_passphrase_from_host: Optional["bool"] = None,
homescreen_width: Optional["int"] = None,
homescreen_height: Optional["int"] = None,
) -> None:
self.capabilities: Sequence["Capability"] = capabilities if capabilities is not None else []
self.major_version = major_version
@ -3314,6 +3318,8 @@ class Features(protobuf.MessageType):
self.busy = busy
self.homescreen_format = homescreen_format
self.hide_passphrase_from_host = hide_passphrase_from_host
self.homescreen_width = homescreen_width
self.homescreen_height = homescreen_height
class LockDevice(protobuf.MessageType):

Loading…
Cancel
Save