• Uncategorized

About linux : How-do-I-read-the-mouse-pointer-position-within-the-UEFI

Question Detail

I want to read the mouse pointer position within the UEFI. I found a protocol called SimplePointerProtocol which should allow me to do that.
I have the following Zig code with many comments so that Zig illiterates understand.

// Some imports. The Zig standard library covers the UEFI API.
const std = @import("std");
const uefi = std.os.uefi;

// The console output protocol
var con_out: *uefi.protocols.SimpleTextOutputProtocol = undefined;

// Printing facilities. You can ignore this.
var buf: [256]u8 = undefined;
fn printf(comptime format: []const u8, args: anytype) void {
    const formatted_buf = std.fmt.bufPrint(buf[0..], format, args) catch unreachable;
    for (formatted_buf) |c| {
        const c_ = [2]u16{ c, 0 };
        _ = con_out.outputString(@ptrCast(*const [1:0]u16, &c_));
    }
}

pub fn main() void {
    const boot_services = uefi.system_table.boot_services.?;

    // Obtain the simple pointer protocol
    var simple_pointer_protocol: *uefi.protocols.SimplePointerProtocol = undefined;
    _ = boot_services.locateProtocol(&uefi.protocols.SimplePointerProtocol.guid, null, @ptrCast(*?*anyopaque, &simple_pointer_protocol));

    // Obtain the console output protocol
    con_out = uefi.system_table.con_out.?;

    // Clear the screen
    _ = con_out.reset(false);

    printf("{s}", .{"waiting for mouse input..."});

    // Await events
    var index: usize = undefined; // This is unused
    var simple_pointer_state: uefi.protocols.SimplePointerState = undefined;
    while (boot_services.waitForEvent(1, @ptrCast([*]uefi.Event, &simple_pointer_protocol.wait_for_input), &index) == uefi.Status.Success) {
        printf("{s}", .{"data received"});

        // Get the mouse pointer state and print it
        _ = simple_pointer_protocol.getState(&simple_pointer_state);
        printf("X: {}, Y: {}", .{ simple_pointer_state.relative_movement_x, simple_pointer_state.relative_movement_y });
    }
}

This code compiles and seems to work.

The problem is that it never emits any event.
I allow QEMU to grab my mouse but no matter whether I move the mouse, press buttons or anything, it seems to wait at waitForEvent forever:

Now I believe this is actually more of a problem with QEMU and or OVMF itself.
Here is how I start QEMU:

qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -hdd fat:rw:. -serial stdio

Am I missing any flags for this to work?
I also tried this:

qemu-system-x86_64 -bios /usr/share/ovmf/OVMF.fd -hdd fat:rw:. -serial stdio -usb -device usb-mouse -device usb-kbd -show-cursor

and other combinations. Nothing seems to do the trick.

How can I read the mouse pointer position within the UEFI using QEMU or any other UEFI emulator?

As an alternative, does anyone have good resources for using the USB protocols/interfaces provided by UEFI (EFI_USB2_HC_PROTOCOL, EFI_USB_IO_PROTOCOL etc.) and read the mouse data myself?

Question Answer

No answer for now.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.