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