]> glassweightruler.freedombox.rocks Git - Ventoy.git/commitdiff
Add mouse support for uefi (#1457)
authorA1ive <10670106+a1ive@users.noreply.github.com>
Tue, 29 Mar 2022 14:49:37 +0000 (22:49 +0800)
committerGitHub <noreply@github.com>
Tue, 29 Mar 2022 14:49:37 +0000 (22:49 +0800)
* fix gcc11 warnings

* add mouse support for uefi

GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def
GRUB2/MOD_SRC/grub-2.04/grub-core/fs/fshelp.c
GRUB2/MOD_SRC/grub-2.04/grub-core/kern/disk.c
GRUB2/MOD_SRC/grub-2.04/grub-core/term/efi/mouse.c [new file with mode: 0644]
GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c
GRUB2/MOD_SRC/grub-2.04/install.sh
GRUB2/MOD_SRC/grub-2.04/util/grub-install.c

index 987400db46a1f182cb250b156b46f09162cfcfcd..5daba477db5241d88587176705d022118cc6203b 100644 (file)
@@ -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;
index f5b6772e2f85d602977ecf9513e39c0ac0edf6d2..9a98c04bd5be9cfb18e784ec64891a02d3b689bb 100644 (file)
@@ -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;
index 04d6ce76db085eaa1ca027621124589912f0b484..e3da637fb4263dd72ba3b5ed3c99df34fdb7a16a 100644 (file)
@@ -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 (file)
index 0000000..c4e3ace
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/term.h>
+#include <grub/misc.h>
+#include <grub/types.h>
+#include <grub/command.h>
+#include <grub/i18n.h>
+#include <grub/err.h>
+#include <grub/efi/efi.h>
+#include <grub/efi/api.h>
+
+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
+}
index c5897d9e8da99b57f39e8339880012162cab5149..61703ef482b2fd9d300c4d5cbde32527df5da4ee 100644 (file)
@@ -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)
index 5b7175b49a84d361ff3283e1c88b6bcaf67391a1..c6b0d0f267619fb3b72dbbf293e6daaf535157ef 100644 (file)
@@ -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"
 
index fc4a9dc665f91daa254ddeccbd8a7b19735b82fd..76c7bbe1fb79c39009658637357e8f70ae8f8620 100644 (file)
@@ -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;