1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
//! Interface for text screen and displays.

use crate::ErrorCode;

pub trait TextScreen<'a> {
    fn set_client(&self, client: Option<&'a dyn TextScreenClient>);

    /// Returns a tuple (width, height) with the resolution of the
    /// screen that is being used. This function is synchronous as the
    /// resolution is known by the driver at any moment.
    ///
    /// The resolution is constant.
    fn get_size(&self) -> (usize, usize);

    /// Sends a write command to the driver, and the buffer to write from
    /// and the len are sent as arguments. When the `write` operation is
    /// finished, the driver will call the `write_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The write command is valid and will be sent to the driver.
    /// - `BUSY`: The driver is busy with another command.
    fn print(
        &self,
        buffer: &'static mut [u8],
        len: usize,
    ) -> Result<(), (ErrorCode, &'static mut [u8])>;

    /// Sends to the driver a command to set the cursor at a given position
    /// (x_position, y_position). When finished, the driver will call the
    /// `command_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The command is valid and will be sent to the driver.
    /// - `BUSY`: Another command is in progress.
    fn set_cursor(&self, x_position: usize, y_position: usize) -> Result<(), ErrorCode>;

    /// Sends to the driver a command to hide the cursor. When finished,
    /// the driver will call the `command_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The command is valid and will be sent to the driver.
    /// - `BUSY`: Another command is in progress.
    fn hide_cursor(&self) -> Result<(), ErrorCode>;

    /// Sends to the driver a command to show the cursor. When finished,
    /// the driver will call the `command_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The command is valid and will be sent to the driver.
    /// - `BUSY`: Another command is in progress.
    fn show_cursor(&self) -> Result<(), ErrorCode>;

    /// Sends to the driver a command to turn on the blinking cursor. When finished,
    /// the driver will call the `command_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The command is valid and will be sent to the driver.
    /// - `BUSY`: Another command is in progress.
    fn blink_cursor_on(&self) -> Result<(), ErrorCode>;

    /// Sends to the driver a command to turn off the blinking cursor. When finished,
    /// the driver will call the `command_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The command is valid and will be sent to the driver.
    /// - `BUSY`: Another command is in progress.
    fn blink_cursor_off(&self) -> Result<(), ErrorCode>;

    /// Sends to the driver a command to turn on the display of the screen.
    /// When finished, the driver will call the `command_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The command is valid and will be sent to the driver.
    /// - `BUSY`: Another command is in progress.
    fn display_on(&self) -> Result<(), ErrorCode>;

    /// Sends to the driver a command to turn off the display of the screen.
    /// When finished, the driver will call the `command_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The command is valid and will be sent to the driver.
    /// - `BUSY`: Another command is in progress.
    fn display_off(&self) -> Result<(), ErrorCode>;

    /// Sends to the driver a command to clear the display of the screen.
    /// When finished, the driver will call the `command_complete()` callback.
    ///
    /// Return values:
    /// - `Ok(())`: The command is valid and will be sent to the driver.
    /// - `BUSY`: Another command is in progress.
    fn clear(&self) -> Result<(), ErrorCode>;
}

pub trait TextScreenClient {
    /// The driver calls this function when any command (but a write one)
    /// finishes executing.
    fn command_complete(&self, r: Result<(), ErrorCode>);

    /// The driver calls this function when a write command finishes executing.
    fn write_complete(&self, buffer: &'static mut [u8], len: usize, r: Result<(), ErrorCode>);
}