master
  1const std = @import("std");
  2const uefi = std.os.uefi;
  3const Guid = uefi.Guid;
  4const Status = uefi.Status;
  5const cc = uefi.cc;
  6const Error = Status.Error;
  7
  8/// Character output devices
  9pub const SimpleTextOutput = extern struct {
 10    _reset: *const fn (*SimpleTextOutput, bool) callconv(cc) Status,
 11    _output_string: *const fn (*SimpleTextOutput, [*:0]const u16) callconv(cc) Status,
 12    _test_string: *const fn (*const SimpleTextOutput, [*:0]const u16) callconv(cc) Status,
 13    _query_mode: *const fn (*const SimpleTextOutput, usize, *usize, *usize) callconv(cc) Status,
 14    _set_mode: *const fn (*SimpleTextOutput, usize) callconv(cc) Status,
 15    _set_attribute: *const fn (*SimpleTextOutput, usize) callconv(cc) Status,
 16    _clear_screen: *const fn (*SimpleTextOutput) callconv(cc) Status,
 17    _set_cursor_position: *const fn (*SimpleTextOutput, usize, usize) callconv(cc) Status,
 18    _enable_cursor: *const fn (*SimpleTextOutput, bool) callconv(cc) Status,
 19    mode: *Mode,
 20
 21    pub const ResetError = uefi.UnexpectedError || error{DeviceError};
 22    pub const OutputStringError = uefi.UnexpectedError || error{
 23        DeviceError,
 24        Unsupported,
 25    };
 26    pub const QueryModeError = uefi.UnexpectedError || error{
 27        DeviceError,
 28        Unsupported,
 29    };
 30    pub const SetModeError = uefi.UnexpectedError || error{
 31        DeviceError,
 32        Unsupported,
 33    };
 34    pub const SetAttributeError = uefi.UnexpectedError || error{DeviceError};
 35    pub const ClearScreenError = uefi.UnexpectedError || error{
 36        DeviceError,
 37        Unsupported,
 38    };
 39    pub const SetCursorPositionError = uefi.UnexpectedError || error{
 40        DeviceError,
 41        Unsupported,
 42    };
 43    pub const EnableCursorError = uefi.UnexpectedError || error{
 44        DeviceError,
 45        Unsupported,
 46    };
 47
 48    /// Resets the text output device hardware.
 49    pub fn reset(self: *SimpleTextOutput, verify: bool) ResetError!void {
 50        switch (self._reset(self, verify)) {
 51            .success => {},
 52            .device_error => return Error.DeviceError,
 53            else => |status| return uefi.unexpectedStatus(status),
 54        }
 55    }
 56
 57    /// Writes a string to the output device.
 58    ///
 59    /// Returns `true` if the string was successfully written, `false` if an unknown glyph was encountered.
 60    pub fn outputString(self: *SimpleTextOutput, msg: [*:0]const u16) OutputStringError!bool {
 61        switch (self._output_string(self, msg)) {
 62            .success => return true,
 63            .warn_unknown_glyph => return false,
 64            .device_error => return Error.DeviceError,
 65            .unsupported => return Error.Unsupported,
 66            else => |status| return uefi.unexpectedStatus(status),
 67        }
 68    }
 69
 70    /// Verifies that all characters in a string can be output to the target device.
 71    pub fn testString(self: *const SimpleTextOutput, msg: [*:0]const u16) uefi.UnexpectedError!bool {
 72        switch (self._test_string(self, msg)) {
 73            .success => return true,
 74            .unsupported => return false,
 75            else => |status| return uefi.unexpectedStatus(status),
 76        }
 77    }
 78
 79    /// Returns information for an available text mode that the output device(s) supports.
 80    pub fn queryMode(self: *const SimpleTextOutput, mode_number: usize) QueryModeError!Geometry {
 81        var geo: Geometry = undefined;
 82        switch (self._query_mode(self, mode_number, &geo.columns, &geo.rows)) {
 83            .success => return geo,
 84            .device_error => return Error.DeviceError,
 85            .unsupported => return Error.Unsupported,
 86            else => |status| return uefi.unexpectedStatus(status),
 87        }
 88    }
 89
 90    /// Sets the output device(s) to a specified mode.
 91    pub fn setMode(self: *SimpleTextOutput, mode_number: usize) SetModeError!void {
 92        switch (self._set_mode(self, mode_number)) {
 93            .success => {},
 94            .device_error => return Error.DeviceError,
 95            .unsupported => return Error.Unsupported,
 96            else => |status| return uefi.unexpectedStatus(status),
 97        }
 98    }
 99
100    /// Sets the background and foreground colors for the outputString() and clearScreen() functions.
101    pub fn setAttribute(self: *SimpleTextOutput, attribute: Attribute) SetAttributeError!void {
102        const attr_as_num: u8 = @bitCast(attribute);
103        switch (self._set_attribute(self, @intCast(attr_as_num))) {
104            .success => {},
105            .device_error => return Error.DeviceError,
106            else => |status| return uefi.unexpectedStatus(status),
107        }
108    }
109
110    /// Clears the output device(s) display to the currently selected background color.
111    pub fn clearScreen(self: *SimpleTextOutput) ClearScreenError!void {
112        switch (self._clear_screen(self)) {
113            .success => {},
114            .device_error => return Error.DeviceError,
115            .unsupported => return Error.Unsupported,
116            else => |status| return uefi.unexpectedStatus(status),
117        }
118    }
119
120    /// Sets the current coordinates of the cursor position.
121    pub fn setCursorPosition(
122        self: *SimpleTextOutput,
123        column: usize,
124        row: usize,
125    ) SetCursorPositionError!void {
126        switch (self._set_cursor_position(self, column, row)) {
127            .success => {},
128            .device_error => return Error.DeviceError,
129            .unsupported => return Error.Unsupported,
130            else => |status| return uefi.unexpectedStatus(status),
131        }
132    }
133
134    /// Makes the cursor visible or invisible.
135    pub fn enableCursor(self: *SimpleTextOutput, visible: bool) EnableCursorError!void {
136        switch (self._enable_cursor(self, visible)) {
137            .success => {},
138            .device_error => return Error.DeviceError,
139            .unsupported => return Error.Unsupported,
140            else => |status| return uefi.unexpectedStatus(status),
141        }
142    }
143
144    pub const guid align(8) = Guid{
145        .time_low = 0x387477c2,
146        .time_mid = 0x69c7,
147        .time_high_and_version = 0x11d2,
148        .clock_seq_high_and_reserved = 0x8e,
149        .clock_seq_low = 0x39,
150        .node = [_]u8{ 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b },
151    };
152    pub const boxdraw_horizontal: u16 = 0x2500;
153    pub const boxdraw_vertical: u16 = 0x2502;
154    pub const boxdraw_down_right: u16 = 0x250c;
155    pub const boxdraw_down_left: u16 = 0x2510;
156    pub const boxdraw_up_right: u16 = 0x2514;
157    pub const boxdraw_up_left: u16 = 0x2518;
158    pub const boxdraw_vertical_right: u16 = 0x251c;
159    pub const boxdraw_vertical_left: u16 = 0x2524;
160    pub const boxdraw_down_horizontal: u16 = 0x252c;
161    pub const boxdraw_up_horizontal: u16 = 0x2534;
162    pub const boxdraw_vertical_horizontal: u16 = 0x253c;
163    pub const boxdraw_double_horizontal: u16 = 0x2550;
164    pub const boxdraw_double_vertical: u16 = 0x2551;
165    pub const boxdraw_down_right_double: u16 = 0x2552;
166    pub const boxdraw_down_double_right: u16 = 0x2553;
167    pub const boxdraw_double_down_right: u16 = 0x2554;
168    pub const boxdraw_down_left_double: u16 = 0x2555;
169    pub const boxdraw_down_double_left: u16 = 0x2556;
170    pub const boxdraw_double_down_left: u16 = 0x2557;
171    pub const boxdraw_up_right_double: u16 = 0x2558;
172    pub const boxdraw_up_double_right: u16 = 0x2559;
173    pub const boxdraw_double_up_right: u16 = 0x255a;
174    pub const boxdraw_up_left_double: u16 = 0x255b;
175    pub const boxdraw_up_double_left: u16 = 0x255c;
176    pub const boxdraw_double_up_left: u16 = 0x255d;
177    pub const boxdraw_vertical_right_double: u16 = 0x255e;
178    pub const boxdraw_vertical_double_right: u16 = 0x255f;
179    pub const boxdraw_double_vertical_right: u16 = 0x2560;
180    pub const boxdraw_vertical_left_double: u16 = 0x2561;
181    pub const boxdraw_vertical_double_left: u16 = 0x2562;
182    pub const boxdraw_double_vertical_left: u16 = 0x2563;
183    pub const boxdraw_down_horizontal_double: u16 = 0x2564;
184    pub const boxdraw_down_double_horizontal: u16 = 0x2565;
185    pub const boxdraw_double_down_horizontal: u16 = 0x2566;
186    pub const boxdraw_up_horizontal_double: u16 = 0x2567;
187    pub const boxdraw_up_double_horizontal: u16 = 0x2568;
188    pub const boxdraw_double_up_horizontal: u16 = 0x2569;
189    pub const boxdraw_vertical_horizontal_double: u16 = 0x256a;
190    pub const boxdraw_vertical_double_horizontal: u16 = 0x256b;
191    pub const boxdraw_double_vertical_horizontal: u16 = 0x256c;
192    pub const blockelement_full_block: u16 = 0x2588;
193    pub const blockelement_light_shade: u16 = 0x2591;
194    pub const geometricshape_up_triangle: u16 = 0x25b2;
195    pub const geometricshape_right_triangle: u16 = 0x25ba;
196    pub const geometricshape_down_triangle: u16 = 0x25bc;
197    pub const geometricshape_left_triangle: u16 = 0x25c4;
198    pub const arrow_up: u16 = 0x2591;
199    pub const arrow_down: u16 = 0x2593;
200
201    pub const Attribute = packed struct(u8) {
202        foreground: ForegroundColor = .white,
203        background: BackgroundColor = .black,
204
205        pub const ForegroundColor = enum(u4) {
206            black,
207            blue,
208            green,
209            cyan,
210            red,
211            magenta,
212            brown,
213            lightgray,
214            darkgray,
215            lightblue,
216            lightgreen,
217            lightcyan,
218            lightred,
219            lightmagenta,
220            yellow,
221            white,
222        };
223
224        pub const BackgroundColor = enum(u4) {
225            black,
226            blue,
227            green,
228            cyan,
229            red,
230            magenta,
231            brown,
232            lightgray,
233        };
234    };
235
236    pub const Mode = extern struct {
237        max_mode: u32, // specified as signed
238        mode: u32, // specified as signed
239        attribute: i32,
240        cursor_column: i32,
241        cursor_row: i32,
242        cursor_visible: bool,
243    };
244
245    pub const Geometry = struct {
246        columns: usize,
247        rows: usize,
248    };
249};