50
50
//! You will have to implement your own double buffering if you want to
51
51
//! avoid tearing with animations.
52
52
53
+ use crate :: prelude:: BootServices ;
53
54
use crate :: proto:: unsafe_protocol;
54
55
use crate :: util:: usize_from_u32;
55
56
use crate :: { Result , StatusExt } ;
56
57
use core:: fmt:: { Debug , Formatter } ;
57
58
use core:: marker:: PhantomData ;
58
59
use core:: { mem, ptr} ;
60
+ pub use uefi_raw:: protocol:: console:: PixelBitmask ;
59
61
use uefi_raw:: protocol:: console:: {
60
62
GraphicsOutputBltOperation , GraphicsOutputModeInformation , GraphicsOutputProtocol ,
61
63
GraphicsOutputProtocolMode ,
62
64
} ;
63
65
64
- pub use uefi_raw:: protocol:: console:: PixelBitmask ;
65
-
66
66
/// Provides access to the video hardware's frame buffer.
67
67
///
68
68
/// The GOP can be used to set the properties of the frame buffer,
@@ -75,27 +75,37 @@ pub struct GraphicsOutput(GraphicsOutputProtocol);
75
75
impl GraphicsOutput {
76
76
/// Returns information for an available graphics mode that the graphics
77
77
/// device and the set of active video output devices supports.
78
- pub fn query_mode ( & self , index : u32 ) -> Result < Mode > {
78
+ pub fn query_mode ( & self , index : u32 , bs : & BootServices ) -> Result < Mode > {
79
79
let mut info_sz = 0 ;
80
- let mut info = ptr:: null ( ) ;
80
+ let mut info_heap_ptr = ptr:: null ( ) ;
81
+ // query_mode allocates a buffer and stores the heap ptr in the provided
82
+ // variable. In this buffer, the queried data can be found.
83
+ unsafe { ( self . 0 . query_mode ) ( & self . 0 , index, & mut info_sz, & mut info_heap_ptr) }
84
+ . to_result_with_val ( || {
85
+ // Transform to owned info on the stack.
86
+ let info = unsafe { * info_heap_ptr } ;
87
+
88
+ let info_heap_ptr = info_heap_ptr. cast :: < u8 > ( ) . cast_mut ( ) ;
89
+
90
+ // User has no benefit from propagating this error. If this
91
+ // fails, it is an error of the UEFI implementation.
92
+ bs. free_pool ( info_heap_ptr)
93
+ . expect ( "buffer should be deallocatable" ) ;
81
94
82
- unsafe { ( self . 0 . query_mode ) ( & self . 0 , index, & mut info_sz, & mut info) } . to_result_with_val (
83
- || {
84
- let info = unsafe { * info } ;
85
95
Mode {
86
96
index,
87
97
info_sz,
88
98
info : ModeInfo ( info) ,
89
99
}
90
- } ,
91
- )
100
+ } )
92
101
}
93
102
94
103
/// Returns information about all available graphics modes.
95
104
#[ must_use]
96
- pub fn modes ( & self ) -> ModeIter {
105
+ pub fn modes < ' a > ( & ' a self , bs : & ' a BootServices ) -> ModeIter {
97
106
ModeIter {
98
107
gop : self ,
108
+ bs,
99
109
current : 0 ,
100
110
max : self . mode ( ) . max_mode ,
101
111
}
@@ -400,6 +410,7 @@ impl ModeInfo {
400
410
/// Iterator for [`Mode`]s of the [`GraphicsOutput`] protocol.
401
411
pub struct ModeIter < ' gop > {
402
412
gop : & ' gop GraphicsOutput ,
413
+ bs : & ' gop BootServices ,
403
414
current : u32 ,
404
415
max : u32 ,
405
416
}
@@ -410,7 +421,7 @@ impl<'gop> Iterator for ModeIter<'gop> {
410
421
fn next ( & mut self ) -> Option < Self :: Item > {
411
422
let index = self . current ;
412
423
if index < self . max {
413
- let m = self . gop . query_mode ( index) ;
424
+ let m = self . gop . query_mode ( index, self . bs ) ;
414
425
self . current += 1 ;
415
426
416
427
m. ok ( ) . or_else ( || self . next ( ) )
0 commit comments