From a20592ecd18a82a62d84b1a6087ff2e608d633b4 Mon Sep 17 00:00:00 2001
From: A1ive <10670106+a1ive@users.noreply.github.com>
Date: Tue, 29 Mar 2022 22:49:37 +0800
Subject: [PATCH] Add mouse support for uefi (#1457)
* fix gcc11 warnings
* add mouse support for uefi
---
.../grub-2.04/grub-core/Makefile.core.def | 6 +
GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c | 2 +-
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c | 2 +-
.../grub-2.04/grub-core/term/efi/mouse.c | 247 ++++++++++++++++++
.../grub-2.04/grub-core/ventoy/ventoy_cmd.c | 2 +-
GRUB2/MOD_SRC/grub-2.04/install.sh | 2 +-
GRUB2/MOD_SRC/grub-2.04/util/grub-install.c | 1 +
7 files changed, 258 insertions(+), 4 deletions(-)
create mode 100644 GRUB2/MOD_SRC/grub-2.04/grub-core/term/efi/mouse.c
diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def
index 987400db..5daba477 100644
--- a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def
+++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def
@@ -1622,6 +1622,12 @@ module = {
common = term/setkey.c;
};
+module = {
+ name = mouse;
+ efi = term/efi/mouse.c;
+ enable = efi;
+};
+
module = {
name = hello;
common = hello/hello.c;
diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c
index f5b6772e..9a98c04b 100644
--- a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c
+++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c
@@ -426,7 +426,7 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
if (grub_errno)
return -1;
}
- else if (read_hook != (grub_disk_read_hook_t)grub_disk_blocklist_read)
+ else if (read_hook != (void *)grub_disk_blocklist_read)
grub_memset (buf, 0, blockend);
buf += blocksize - skipfirst;
diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c
index 04d6ce76..e3da637f 100644
--- a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c
+++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c
@@ -471,7 +471,7 @@ grub_err_t
grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
grub_off_t offset, grub_size_t size, void *buf)
{
- if (disk->read_hook == (grub_disk_read_hook_t)grub_disk_blocklist_read)
+ if (disk->read_hook == (void *)grub_disk_blocklist_read)
{
return grub_disk_blocklist_read((ventoy_img_chunk_list *)disk->read_hook_data, sector, size, disk->log_sector_size);
}
diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/term/efi/mouse.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/efi/mouse.c
new file mode 100644
index 00000000..c4e3ace5
--- /dev/null
+++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/efi/mouse.c
@@ -0,0 +1,247 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+#define GRUB_EFI_SIMPLE_POINTER_GUID \
+ { 0x31878c87, 0x0b75, 0x11d5, \
+ { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
+ }
+
+typedef struct
+{
+ grub_efi_int32_t x;
+ grub_efi_int32_t y;
+ grub_efi_int32_t z;
+ grub_efi_boolean_t left;
+ grub_efi_boolean_t right;
+} grub_efi_mouse_state;
+
+grub_efi_mouse_state no_move = {0, 0, 0, 0, 0};
+
+typedef struct
+{
+ grub_efi_uint64_t x;
+ grub_efi_uint64_t y;
+ grub_efi_uint64_t z;
+ grub_efi_boolean_t left;
+ grub_efi_boolean_t right;
+} grub_efi_mouse_mode;
+
+struct grub_efi_simple_pointer_protocol
+{
+ grub_efi_status_t (*reset) (struct grub_efi_simple_pointer_protocol *this,
+ grub_efi_boolean_t extended_verification);
+ grub_efi_status_t (*get_state) (struct grub_efi_simple_pointer_protocol *this,
+ grub_efi_mouse_state *state);
+ grub_efi_event_t *wait_for_input;
+ grub_efi_mouse_mode *mode;
+};
+typedef struct grub_efi_simple_pointer_protocol grub_efi_simple_pointer_protocol_t;
+
+typedef struct
+{
+ grub_efi_uintn_t count;
+ grub_efi_simple_pointer_protocol_t **mouse;
+} grub_efi_mouse_prot_t;
+
+static grub_int32_t
+mouse_div (grub_int32_t a, grub_uint64_t b)
+{
+ grub_int32_t s = 1, q, ret;
+ grub_uint64_t n = a;
+ if (!b)
+ return 0;
+ if (a < 0)
+ {
+ s = -1;
+ n = -a;
+ }
+ q = grub_divmod64 (n, b, NULL);
+ ret = s * (q > 0 ? q : -q);
+ return ret;
+}
+
+static grub_efi_mouse_prot_t *
+grub_efi_mouse_prot_init (void)
+{
+ grub_efi_status_t status;
+ grub_efi_guid_t mouse_guid = GRUB_EFI_SIMPLE_POINTER_GUID;
+ grub_efi_mouse_prot_t *mouse_input = NULL;
+ grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
+ grub_efi_handle_t *buf;
+ grub_efi_uintn_t count;
+ grub_efi_uintn_t i;
+
+ status = efi_call_5 (b->locate_handle_buffer, GRUB_EFI_BY_PROTOCOL,
+ &mouse_guid, NULL, &count, &buf);
+ if (status != GRUB_EFI_SUCCESS)
+ {
+#ifdef MOUSE_DEBUG
+ grub_printf ("ERROR: SimplePointerProtocol not found.\n");
+#endif
+ return NULL;
+ }
+
+ mouse_input = grub_malloc (sizeof (grub_efi_mouse_prot_t));
+ if (!mouse_input)
+ return NULL;
+ mouse_input->mouse = grub_malloc (count
+ * sizeof (grub_efi_simple_pointer_protocol_t *));
+ if (!mouse_input->mouse)
+ {
+ grub_free (mouse_input);
+ return NULL;
+ }
+ mouse_input->count = count;
+ for (i = 0; i < count; i++)
+ {
+ efi_call_3 (b->handle_protocol,
+ buf[i], &mouse_guid, (void **)&mouse_input->mouse[i]);
+#ifdef MOUSE_DEBUG
+ grub_printf ("%d %p ", (int)i, mouse_input->mouse[i]);
+#endif
+ efi_call_2 (mouse_input->mouse[i]->reset, mouse_input->mouse[i], 1);
+#ifdef MOUSE_DEBUG
+ grub_printf
+ ("[%"PRIuGRUB_UINT64_T"] [%"PRIuGRUB_UINT64_T"] [%"PRIuGRUB_UINT64_T"]\n",
+ mouse_input->mouse[i]->mode->x,
+ mouse_input->mouse[i]->mode->y, mouse_input->mouse[i]->mode->z);
+#endif
+ }
+ return mouse_input;
+}
+
+static grub_err_t
+grub_efi_mouse_input_init (struct grub_term_input *term)
+{
+ grub_efi_mouse_prot_t *mouse_input = NULL;
+ if (term->data)
+ return 0;
+ mouse_input = grub_efi_mouse_prot_init ();
+ if (!mouse_input)
+ return GRUB_ERR_BAD_OS;
+
+ term->data = (void *)mouse_input;
+
+ return 0;
+}
+
+static int
+grub_mouse_getkey (struct grub_term_input *term)
+{
+ grub_efi_mouse_state cur;
+ grub_efi_mouse_prot_t *mouse = term->data;
+ //int x;
+ int y;
+ grub_efi_uintn_t i;
+ if (!mouse)
+ return GRUB_TERM_NO_KEY;
+ for (i = 0; i < mouse->count; i++)
+ {
+ efi_call_2 (mouse->mouse[i]->get_state, mouse->mouse[i], &cur);
+ if (grub_memcmp (&cur, &no_move, sizeof (grub_efi_mouse_state)) != 0)
+ {
+ y = mouse_div (cur.y, mouse->mouse[i]->mode->y);
+ if (cur.left)
+ return 0x0d;
+ if (cur.right)
+ return GRUB_TERM_ESC;
+ if (y > 0)
+ return GRUB_TERM_KEY_DOWN;
+ if (y < 0)
+ return GRUB_TERM_KEY_UP;
+ }
+ }
+ return GRUB_TERM_NO_KEY;
+}
+
+#ifdef MOUSE_DEBUG
+static grub_err_t
+grub_cmd_mouse_test (grub_command_t cmd __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+
+{
+ grub_efi_mouse_state cur;
+ int x = 0, y = 0, z = 0;
+ grub_efi_uintn_t i;
+ grub_efi_mouse_prot_t *mouse = NULL;
+
+ mouse = grub_efi_mouse_prot_init ();
+ if (!mouse)
+ return grub_error (GRUB_ERR_BAD_OS, "mouse not found.\n");
+ grub_printf ("Press [1] to exit.\n");
+ while (1)
+ {
+ if (grub_getkey_noblock () == '1')
+ break;
+ for (i = 0; i < mouse->count; i++)
+ {
+ efi_call_2 (mouse->mouse[i]->get_state, mouse->mouse[i], &cur);
+ if (grub_memcmp (&cur, &no_move, sizeof (grub_efi_mouse_state)) != 0)
+ {
+ x = mouse_div (cur.x, mouse->mouse[i]->mode->x);
+ y = mouse_div (cur.y, mouse->mouse[i]->mode->y);
+ z = mouse_div (cur.z, mouse->mouse[i]->mode->z);
+ grub_printf ("[ID=%d] X=%d Y=%d Z=%d L=%d R=%d\n",
+ (int)i, x, y, z, cur.left, cur.right);
+ }
+ }
+ grub_refresh ();
+ }
+ grub_free (mouse->mouse);
+ grub_free (mouse);
+ return GRUB_ERR_NONE;
+}
+static grub_command_t cmd;
+#endif
+
+static struct grub_term_input grub_mouse_term_input =
+{
+ .name = "mouse",
+ .getkey = grub_mouse_getkey,
+ .init = grub_efi_mouse_input_init,
+};
+
+GRUB_MOD_INIT(mouse)
+{
+ grub_term_register_input ("mouse", &grub_mouse_term_input);
+#ifdef MOUSE_DEBUG
+ cmd = grub_register_command ("mouse_test", grub_cmd_mouse_test, 0,
+ N_("UEFI mouse test."));
+#endif
+}
+
+GRUB_MOD_FINI(mouse)
+{
+ grub_term_unregister_input (&grub_mouse_term_input);
+#ifdef MOUSE_DEBUG
+ grub_unregister_command (cmd);
+#endif
+}
diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
index c5897d9e..61703ef4 100644
--- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
+++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
@@ -3152,7 +3152,7 @@ int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, gr
}
else
{
- file->read_hook = (grub_disk_read_hook_t)grub_disk_blocklist_read;
+ file->read_hook = (void *)grub_disk_blocklist_read;
file->read_hook_data = chunklist;
for (size = file->size; size > 0; size -= read)
diff --git a/GRUB2/MOD_SRC/grub-2.04/install.sh b/GRUB2/MOD_SRC/grub-2.04/install.sh
index 5b7175b4..c6b0d0f2 100644
--- a/GRUB2/MOD_SRC/grub-2.04/install.sh
+++ b/GRUB2/MOD_SRC/grub-2.04/install.sh
@@ -15,7 +15,7 @@ net_modules_legacy="net tftp http"
all_modules_legacy="file setkey date drivemap blocklist regexp newc vga_text ntldr search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_gpt part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu"
net_modules_uefi="efinet net tftp http"
-all_modules_uefi="file setkey blocklist ventoy test true regexp newc search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu"
+all_modules_uefi="file setkey blocklist ventoy test true regexp newc search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu mouse"
all_modules_arm64_uefi="file setkey blocklist ventoy test true regexp newc search gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop video video_fb gfxterm_background gfxterm_menu"
diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c
index fc4a9dc6..76c7bbe1 100644
--- a/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c
+++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c
@@ -1165,6 +1165,7 @@ main (int argc, char *argv[])
break;
case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI:
efi_file = "grubmips64el.efi";
+ break;
case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
efi_file = "grubriscv32.efi";
break;