Skip to content

Commit 3e643f1

Browse files
uefi: Use uefi_raw's SimpleTextOutputProtocol in Output
1 parent d0d6300 commit 3e643f1

File tree

1 file changed

+31
-42
lines changed

1 file changed

+31
-42
lines changed

uefi/src/proto/console/text/output.rs

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::proto::unsafe_protocol;
2-
use crate::{CStr16, Char16, Result, ResultExt, Status, StatusExt};
2+
use crate::{CStr16, Result, ResultExt, Status, StatusExt};
33
use core::fmt;
44
use core::fmt::{Debug, Formatter};
5-
use uefi_raw::protocol::console::SimpleTextOutputMode;
5+
use uefi_raw::protocol::console::{SimpleTextOutputMode, SimpleTextOutputProtocol};
66

77
/// Interface for text-based output devices.
88
///
@@ -21,44 +21,27 @@ use uefi_raw::protocol::console::SimpleTextOutputMode;
2121
/// [`SystemTable::stdout`]: crate::table::SystemTable::stdout
2222
/// [`SystemTable::stderr`]: crate::table::SystemTable::stderr
2323
/// [`BootServices`]: crate::table::boot::BootServices#accessing-protocols
24-
#[repr(C)]
25-
#[unsafe_protocol("387477c2-69c7-11d2-8e39-00a0c969723b")]
26-
pub struct Output {
27-
reset: unsafe extern "efiapi" fn(this: &Output, extended: bool) -> Status,
28-
output_string: unsafe extern "efiapi" fn(this: &Output, string: *const Char16) -> Status,
29-
test_string: unsafe extern "efiapi" fn(this: &Output, string: *const Char16) -> Status,
30-
query_mode: unsafe extern "efiapi" fn(
31-
this: &Output,
32-
mode: usize,
33-
columns: &mut usize,
34-
rows: &mut usize,
35-
) -> Status,
36-
set_mode: unsafe extern "efiapi" fn(this: &mut Output, mode: usize) -> Status,
37-
set_attribute: unsafe extern "efiapi" fn(this: &mut Output, attribute: usize) -> Status,
38-
clear_screen: unsafe extern "efiapi" fn(this: &mut Output) -> Status,
39-
set_cursor_position:
40-
unsafe extern "efiapi" fn(this: &mut Output, column: usize, row: usize) -> Status,
41-
enable_cursor: unsafe extern "efiapi" fn(this: &mut Output, visible: bool) -> Status,
42-
data: *const SimpleTextOutputMode,
43-
}
24+
#[repr(transparent)]
25+
#[unsafe_protocol(SimpleTextOutputProtocol::GUID)]
26+
pub struct Output(SimpleTextOutputProtocol);
4427

4528
impl Output {
4629
/// Resets and clears the text output device hardware.
4730
pub fn reset(&mut self, extended: bool) -> Result {
48-
unsafe { (self.reset)(self, extended) }.to_result()
31+
unsafe { (self.0.reset)(&mut self.0, extended) }.to_result()
4932
}
5033

5134
/// Clears the output screen.
5235
///
5336
/// The background is set to the current background color.
5437
/// The cursor is moved to (0, 0).
5538
pub fn clear(&mut self) -> Result {
56-
unsafe { (self.clear_screen)(self) }.to_result()
39+
unsafe { (self.0.clear_screen)(&mut self.0) }.to_result()
5740
}
5841

5942
/// Writes a string to the output device.
6043
pub fn output_string(&mut self, string: &CStr16) -> Result {
61-
unsafe { (self.output_string)(self, string.as_ptr()) }.to_result()
44+
unsafe { (self.0.output_string)(&mut self.0, string.as_ptr().cast()) }.to_result()
6245
}
6346

6447
/// Writes a string to the output device. If the string contains
@@ -79,7 +62,7 @@ impl Output {
7962
/// UEFI applications are encouraged to try to print a string even if it contains
8063
/// some unsupported characters.
8164
pub fn test_string(&mut self, string: &CStr16) -> Result<bool> {
82-
match unsafe { (self.test_string)(self, string.as_ptr()) } {
65+
match unsafe { (self.0.test_string)(&mut self.0, string.as_ptr().cast()) } {
8366
Status::UNSUPPORTED => Ok(false),
8467
other => other.to_result_with_val(|| true),
8568
}
@@ -108,7 +91,8 @@ impl Output {
10891
/// alternative to this method.
10992
fn query_mode(&self, index: usize) -> Result<(usize, usize)> {
11093
let (mut columns, mut rows) = (0, 0);
111-
unsafe { (self.query_mode)(self, index, &mut columns, &mut rows) }
94+
let this: *const _ = &self.0;
95+
unsafe { (self.0.query_mode)(this.cast_mut(), index, &mut columns, &mut rows) }
11296
.to_result_with_val(|| (columns, rows))
11397
}
11498

@@ -127,7 +111,7 @@ impl Output {
127111

128112
/// Sets a mode as current.
129113
pub fn set_mode(&mut self, mode: OutputMode) -> Result {
130-
unsafe { (self.set_mode)(self, mode.index) }.to_result()
114+
unsafe { (self.0.set_mode)(&mut self.0, mode.index) }.to_result()
131115
}
132116

133117
/// Returns whether the cursor is currently shown or not.
@@ -141,7 +125,7 @@ impl Output {
141125
/// The output device may not support this operation, in which case an
142126
/// `Unsupported` error will be returned.
143127
pub fn enable_cursor(&mut self, visible: bool) -> Result {
144-
unsafe { (self.enable_cursor)(self, visible) }.to_result()
128+
unsafe { (self.0.enable_cursor)(&mut self.0, visible) }.to_result()
145129
}
146130

147131
/// Returns the column and row of the cursor.
@@ -156,7 +140,7 @@ impl Output {
156140
///
157141
/// This function will fail if the cursor's new position would exceed the screen's bounds.
158142
pub fn set_cursor_position(&mut self, column: usize, row: usize) -> Result {
159-
unsafe { (self.set_cursor_position)(self, column, row) }.to_result()
143+
unsafe { (self.0.set_cursor_position)(&mut self.0, column, row) }.to_result()
160144
}
161145

162146
/// Sets the text and background colors for the console.
@@ -170,13 +154,15 @@ impl Output {
170154
assert!(bgc < 8, "An invalid background color was requested");
171155

172156
let attr = ((bgc & 0x7) << 4) | (fgc & 0xF);
173-
unsafe { (self.set_attribute)(self, attr) }.to_result()
157+
unsafe { (self.0.set_attribute)(&mut self.0, attr) }.to_result()
174158
}
175159

176160
/// Get a reference to `OutputData`. The lifetime of the reference is tied
177161
/// to `self`.
178162
const fn data(&self) -> &SimpleTextOutputMode {
179-
unsafe { &*self.data }
163+
// Can't dereference mut pointers in a const function, so cast to const.
164+
let mode = self.0.mode.cast_const();
165+
unsafe { &*mode }
180166
}
181167
}
182168

@@ -234,28 +220,31 @@ impl fmt::Write for Output {
234220
impl Debug for Output {
235221
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
236222
f.debug_struct("Output")
237-
.field("reset (fn ptr)", &(self.reset as *const u64))
223+
.field("reset (fn ptr)", &(self.0.reset as *const u64))
238224
.field(
239225
"output_string (fn ptr)",
240-
&(self.output_string as *const u64),
226+
&(self.0.output_string as *const u64),
241227
)
242-
.field("test_string (fn ptr)", &(self.test_string as *const u64))
243-
.field("query_mode (fn ptr)", &(self.query_mode as *const u64))
244-
.field("set_mode (fn ptr)", &(self.set_mode as *const u64))
228+
.field("test_string (fn ptr)", &(self.0.test_string as *const u64))
229+
.field("query_mode (fn ptr)", &(self.0.query_mode as *const u64))
230+
.field("set_mode (fn ptr)", &(self.0.set_mode as *const u64))
245231
.field(
246232
"set_attribute (fn ptr)",
247-
&(self.set_attribute as *const u64),
233+
&(self.0.set_attribute as *const u64),
234+
)
235+
.field(
236+
"clear_screen (fn ptr)",
237+
&(self.0.clear_screen as *const u64),
248238
)
249-
.field("clear_screen (fn ptr)", &(self.clear_screen as *const u64))
250239
.field(
251240
"set_cursor_position (fn ptr)",
252-
&(self.set_cursor_position as *const u64),
241+
&(self.0.set_cursor_position as *const u64),
253242
)
254243
.field(
255244
"enable_cursor (fn ptr)",
256-
&(self.enable_cursor as *const u64),
245+
&(self.0.enable_cursor as *const u64),
257246
)
258-
.field("data", &self.data)
247+
.field("data", &self.0.mode)
259248
.finish()
260249
}
261250
}

0 commit comments

Comments
 (0)