Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a method, to get Index on uefi::proto::console::gop::Mode #458

Open
C0D3-M4513R opened this issue Jul 3, 2022 · 3 comments
Open

Add a method, to get Index on uefi::proto::console::gop::Mode #458

C0D3-M4513R opened this issue Jul 3, 2022 · 3 comments
Labels
documentation Issues related to the documentation question

Comments

@C0D3-M4513R
Copy link

C0D3-M4513R commented Jul 3, 2022

I am currently writing my own kernel.
I use the GOP to get a framebuffer.
I look through all, and grab the one, that has the best properties.

The annoying part is, that I CAN iterate over all Modes and grab their respective ModeInfo.
It is just, that there is no good way to know which mode I have the info of.
That means it is impossible for me to modeset, because I don't know which index ModeInfo is from.

My current approach is the following. It doesn't feel very clean, but I don't think, that I can come up with a better approach.

let st = unsafe{uefi_services::system_table().as_mut()};

//todo: have a better way, to draw stuff
let mut gop = st.boot_services().locate_protocol::<uefi::proto::console::gop::GraphicsOutput>()?;
//SAFETY:
// FIXME: Cannot satisfy.
// This Application could have been started by another Application.
// If that Application also got the GOP, this is a violation.
let gop = unsafe{&mut *gop.get()};
let i = gop.modes();
the start, and gets set to Some(i.next())).
let i = i.enumerate().map(|(mn,m)|(mn,*m.info())).filter(|(_,m)|m.pixel_format()!=PixelFormat::BltOnly);

I feel like this could be written safer, if uefi allowed getting the Index of Mode.

@C0D3-M4513R
Copy link
Author

C0D3-M4513R commented Jul 3, 2022

Alternatively you could allow us to know how many modes there are.
Then we can iter over the modes using a for loop and query_modes.

AFAIK Currently only queriably by doing:

let i = gop.modes();
let max_modes=i.size_hint().0;

@nicholasbishop
Copy link
Contributor

Here's how you can do this with the existing API:

use uefi::proto::console::gop::{GraphicsOutput, PixelFormat};
use uefi::table::boot::{BootServices, OpenProtocolAttributes, OpenProtocolParams, SearchType};
use uefi::{Handle, Identify, Result};

pub fn gop_test(image: Handle, bt: &BootServices) -> Result {
    let gop_handle = *bt
        .locate_handle_buffer(SearchType::ByProtocol(&GraphicsOutput::GUID))?
        .handles()
        .first()
        .expect("no GOP handle found");

    let gop = bt.open_protocol::<GraphicsOutput>(
        OpenProtocolParams {
            handle: gop_handle,
            agent: image,
            controller: None,
        },
        OpenProtocolAttributes::Exclusive,
    )?;
    // SAFETY: the protocol was opened in exclusive mode so nothing else
    // can use it.
    let gop = unsafe { &mut *gop.interface.get() };

    let mode = gop
        .modes()
        .find(|mode| mode.info().pixel_format() != PixelFormat::BltOnly)
        .expect("no valid mode found");
    gop.set_mode(&mode)?;

    Ok(())
}

(Adapted from https://github.com/rust-osdev/uefi-rs/blob/main/uefi-test-runner/src/proto/console/gop.rs)

@C0D3-M4513R
Copy link
Author

C0D3-M4513R commented Jul 6, 2022

Oops. I completely forgot to look at set_mode.
The abstraction makes sense then. What doesn't make sense is that gop.query_mode is public.
We don't know anything about indexes, and we cannot query anything from the current api.
Either make a index getter, or query_mode private in my eyes.

Any reason why Mode is non-Copy, non-Clone and most of all non-debug?
It is not like we can change something inside of Mode accidentally.

@GabrielMajeri GabrielMajeri added question documentation Issues related to the documentation labels Jul 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Issues related to the documentation question
Projects
None yet
Development

No branches or pull requests

3 participants