1
1
use crate :: proto:: unsafe_protocol;
2
- use crate :: { CStr16 , Char16 , Result , ResultExt , Status , StatusExt } ;
2
+ use crate :: { CStr16 , Result , ResultExt , Status , StatusExt } ;
3
3
use core:: fmt;
4
4
use core:: fmt:: { Debug , Formatter } ;
5
- use uefi_raw:: protocol:: console:: SimpleTextOutputMode ;
5
+ use uefi_raw:: protocol:: console:: { SimpleTextOutputMode , SimpleTextOutputProtocol } ;
6
6
7
7
/// Interface for text-based output devices.
8
8
///
@@ -21,44 +21,27 @@ use uefi_raw::protocol::console::SimpleTextOutputMode;
21
21
/// [`SystemTable::stdout`]: crate::table::SystemTable::stdout
22
22
/// [`SystemTable::stderr`]: crate::table::SystemTable::stderr
23
23
/// [`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 ) ;
44
27
45
28
impl Output {
46
29
/// Resets and clears the text output device hardware.
47
30
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 ( )
49
32
}
50
33
51
34
/// Clears the output screen.
52
35
///
53
36
/// The background is set to the current background color.
54
37
/// The cursor is moved to (0, 0).
55
38
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 ( )
57
40
}
58
41
59
42
/// Writes a string to the output device.
60
43
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 ( )
62
45
}
63
46
64
47
/// Writes a string to the output device. If the string contains
@@ -79,7 +62,7 @@ impl Output {
79
62
/// UEFI applications are encouraged to try to print a string even if it contains
80
63
/// some unsupported characters.
81
64
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 ( ) ) } {
83
66
Status :: UNSUPPORTED => Ok ( false ) ,
84
67
other => other. to_result_with_val ( || true ) ,
85
68
}
@@ -108,7 +91,8 @@ impl Output {
108
91
/// alternative to this method.
109
92
fn query_mode ( & self , index : usize ) -> Result < ( usize , usize ) > {
110
93
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) }
112
96
. to_result_with_val ( || ( columns, rows) )
113
97
}
114
98
@@ -127,7 +111,7 @@ impl Output {
127
111
128
112
/// Sets a mode as current.
129
113
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 ( )
131
115
}
132
116
133
117
/// Returns whether the cursor is currently shown or not.
@@ -141,7 +125,7 @@ impl Output {
141
125
/// The output device may not support this operation, in which case an
142
126
/// `Unsupported` error will be returned.
143
127
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 ( )
145
129
}
146
130
147
131
/// Returns the column and row of the cursor.
@@ -156,7 +140,7 @@ impl Output {
156
140
///
157
141
/// This function will fail if the cursor's new position would exceed the screen's bounds.
158
142
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 ( )
160
144
}
161
145
162
146
/// Sets the text and background colors for the console.
@@ -170,13 +154,15 @@ impl Output {
170
154
assert ! ( bgc < 8 , "An invalid background color was requested" ) ;
171
155
172
156
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 ( )
174
158
}
175
159
176
160
/// Get a reference to `OutputData`. The lifetime of the reference is tied
177
161
/// to `self`.
178
162
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 }
180
166
}
181
167
}
182
168
@@ -234,28 +220,31 @@ impl fmt::Write for Output {
234
220
impl Debug for Output {
235
221
fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
236
222
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 ) )
238
224
. field (
239
225
"output_string (fn ptr)" ,
240
- & ( self . output_string as * const u64 ) ,
226
+ & ( self . 0 . output_string as * const u64 ) ,
241
227
)
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 ) )
245
231
. field (
246
232
"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 ) ,
248
238
)
249
- . field ( "clear_screen (fn ptr)" , & ( self . clear_screen as * const u64 ) )
250
239
. field (
251
240
"set_cursor_position (fn ptr)" ,
252
- & ( self . set_cursor_position as * const u64 ) ,
241
+ & ( self . 0 . set_cursor_position as * const u64 ) ,
253
242
)
254
243
. field (
255
244
"enable_cursor (fn ptr)" ,
256
- & ( self . enable_cursor as * const u64 ) ,
245
+ & ( self . 0 . enable_cursor as * const u64 ) ,
257
246
)
258
- . field ( "data" , & self . data )
247
+ . field ( "data" , & self . 0 . mode )
259
248
. finish ( )
260
249
}
261
250
}
0 commit comments