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 } ;
@@ -75,27 +76,37 @@ pub struct GraphicsOutput(GraphicsOutputProtocol);
75
76
impl GraphicsOutput {
76
77
/// Returns information for an available graphics mode that the graphics
77
78
/// device and the set of active video output devices supports.
78
- pub fn query_mode ( & self , index : u32 ) -> Result < Mode > {
79
+ pub fn query_mode ( & self , index : u32 , bs : & BootServices ) -> Result < Mode > {
79
80
let mut info_sz = 0 ;
80
- let mut info = ptr:: null ( ) ;
81
+ let mut info_heap_ptr = ptr:: null ( ) ;
82
+ // query_mode allocates a buffer and stores the heap ptr in the provided
83
+ // variable. In this buffer, the queried data can be found.
84
+ unsafe { ( self . 0 . query_mode ) ( & self . 0 , index, & mut info_sz, & mut info_heap_ptr) }
85
+ . to_result_with_val ( || {
86
+ // Transform to owned info on the stack.
87
+ let info = unsafe { * info_heap_ptr } ;
88
+
89
+ let info_heap_ptr = info_heap_ptr. cast :: < u8 > ( ) . cast_mut ( ) ;
90
+
91
+ // User has no benefit from propagating this error. If this
92
+ // fails, it is an error of the UEFI implementation.
93
+ bs. free_pool ( info_heap_ptr)
94
+ . expect ( "buffer should be deallocatable" ) ;
81
95
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
96
Mode {
86
97
index,
87
98
info_sz,
88
99
info : ModeInfo ( info) ,
89
100
}
90
- } ,
91
- )
101
+ } )
92
102
}
93
103
94
104
/// Returns information about all available graphics modes.
95
105
#[ must_use]
96
- pub fn modes ( & self ) -> ModeIter {
106
+ pub fn modes < ' a > ( & ' a self , bs : & ' a BootServices ) -> ModeIter {
97
107
ModeIter {
98
108
gop : self ,
109
+ bs,
99
110
current : 0 ,
100
111
max : self . mode ( ) . max_mode ,
101
112
}
@@ -400,6 +411,7 @@ impl ModeInfo {
400
411
/// Iterator for [`Mode`]s of the [`GraphicsOutput`] protocol.
401
412
pub struct ModeIter < ' gop > {
402
413
gop : & ' gop GraphicsOutput ,
414
+ bs : & ' gop BootServices ,
403
415
current : u32 ,
404
416
max : u32 ,
405
417
}
@@ -410,7 +422,7 @@ impl<'gop> Iterator for ModeIter<'gop> {
410
422
fn next ( & mut self ) -> Option < Self :: Item > {
411
423
let index = self . current ;
412
424
if index < self . max {
413
- let m = self . gop . query_mode ( index) ;
425
+ let m = self . gop . query_mode ( index, self . bs ) ;
414
426
self . current += 1 ;
415
427
416
428
m. ok ( ) . or_else ( || self . next ( ) )
0 commit comments