diff --git a/common/protob/messages-management.proto b/common/protob/messages-management.proto index cc87c9338..59f6e8bf6 100644 --- a/common/protob/messages-management.proto +++ b/common/protob/messages-management.proto @@ -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 + } /** diff --git a/core/embed/rust/build.rs b/core/embed/rust/build.rs index c348acc28..e24da41b8 100644 --- a/core/embed/rust/build.rs +++ b/core/embed/rust/build.rs @@ -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") diff --git a/core/embed/rust/src/trezorhal/display.rs b/core/embed/rust/src/trezorhal/display.rs index 060fa66b3..0a31a869d 100644 --- a/core/embed/rust/src/trezorhal/display.rs +++ b/core/embed/rust/src/trezorhal/display.rs @@ -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 _, diff --git a/core/embed/rust/src/ui/model_tr/constant.rs b/core/embed/rust/src/ui/model_tr/constant.rs index eadb0f43a..005c6a571 100644 --- a/core/embed/rust/src/ui/model_tr/constant.rs +++ b/core/embed/rust/src/ui/model_tr/constant.rs @@ -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; diff --git a/core/embed/rust/src/ui/model_tt/constant.rs b/core/embed/rust/src/ui/model_tt/constant.rs index 0fc5e7724..f01c9761d 100644 --- a/core/embed/rust/src/ui/model_tt/constant.rs +++ b/core/embed/rust/src/ui/model_tt/constant.rs @@ -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; diff --git a/core/embed/trezorhal/boards/stm32f429i-disc1.h b/core/embed/trezorhal/boards/stm32f429i-disc1.h index ce38057b4..17e291b04 100644 --- a/core/embed/trezorhal/boards/stm32f429i-disc1.h +++ b/core/embed/trezorhal/boards/stm32f429i-disc1.h @@ -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 diff --git a/core/embed/trezorhal/boards/trezor_t.h b/core/embed/trezorhal/boards/trezor_t.h index a2111853d..a5676fea9 100644 --- a/core/embed/trezorhal/boards/trezor_t.h +++ b/core/embed/trezorhal/boards/trezor_t.h @@ -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 diff --git a/core/embed/trezorhal/displays/ltdc.h b/core/embed/trezorhal/displays/ltdc.h index 63848cf1a..7d57c8dcf 100644 --- a/core/embed/trezorhal/displays/ltdc.h +++ b/core/embed/trezorhal/displays/ltdc.h @@ -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; diff --git a/core/embed/trezorhal/displays/st7789v.h b/core/embed/trezorhal/displays/st7789v.h index 5d15c66b6..012638c9b 100644 --- a/core/embed/trezorhal/displays/st7789v.h +++ b/core/embed/trezorhal/displays/st7789v.h @@ -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 diff --git a/core/src/apps/base.py b/core/src/apps/base.py index f26c199fd..0460aca33 100644 --- a/core/src/apps/base.py +++ b/core/src/apps/base.py @@ -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: diff --git a/core/src/apps/management/apply_settings.py b/core/src/apps/management/apply_settings.py index 2f6716e92..bfa31860b 100644 --- a/core/src/apps/management/apply_settings.py +++ b/core/src/apps/management/apply_settings.py @@ -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: diff --git a/core/src/trezor/enums/HomescreenFormat.py b/core/src/trezor/enums/HomescreenFormat.py index 9d72d56d1..3bc89fa97 100644 --- a/core/src/trezor/enums/HomescreenFormat.py +++ b/core/src/trezor/enums/HomescreenFormat.py @@ -2,5 +2,5 @@ # fmt: off # isort:skip_file -Toif144x144 = 1 -Jpeg240x240 = 2 +Toif = 1 +Jpeg = 2 diff --git a/core/src/trezor/enums/__init__.py b/core/src/trezor/enums/__init__.py index 2371f66c3..f7925f233 100644 --- a/core/src/trezor/enums/__init__.py +++ b/core/src/trezor/enums/__init__.py @@ -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 diff --git a/core/src/trezor/messages.py b/core/src/trezor/messages.py index 8c15cf5e3..3c1b4c0ff 100644 --- a/core/src/trezor/messages.py +++ b/core/src/trezor/messages.py @@ -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 diff --git a/python/src/trezorlib/cli/settings.py b/python/src/trezorlib/cli/settings.py index e3021d97c..cc6b5f31f 100644 --- a/python/src/trezorlib/cli/settings.py +++ b/python/src/trezorlib/cli/settings.py @@ -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." diff --git a/python/src/trezorlib/messages.py b/python/src/trezorlib/messages.py index 27f0c0d3b..1b2249bdf 100644 --- a/python/src/trezorlib/messages.py +++ b/python/src/trezorlib/messages.py @@ -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):