1 Star 0 Fork 16

jackzhao166/grub2

forked from OpenCloudOS Stream/grub2 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0067-gfxmenu-support-scrolling-menu-entry-s-text.patch 8.63 KB
一键复制 编辑 原始数据 按行查看 历史
nilusyi 提交于 2024-04-07 16:45 . update patches
From f7e6ef516ae778322df10d425fa1e0d60493c23f Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Mon, 7 Jan 2019 17:55:05 +0800
Subject: [PATCH 067/272] gfxmenu: support scrolling menu entry's text
If menu entry's title text is longer than its display width, the
overlong text simply get truncated. The only possible way to view the
full text is through the menu editing mode, but is a hassle switching
over the mode back and forth. Also menu editing mode could be password
protected which makes it not generally available to everyone.
This patch implemented scrolling text support to the title of grub's
gfxmenu to make it convenient for viewing the truncated text by pressing
the ctrl+l and ctrl+r to scroll the highlighted text left and right. The
scrolled result will remain in place to help memorizing it after
changing highlight to other entry.
V1:
* Use grub_calloc for overflow check and return NULL when it would
occur.
---
grub-core/gfxmenu/gfxmenu.c | 10 +++++++
grub-core/gfxmenu/gui_label.c | 2 ++
grub-core/gfxmenu/gui_list.c | 38 +++++++++++++++++++++++++++
grub-core/gfxmenu/view.c | 49 +++++++++++++++++++++++++++++++++++
grub-core/normal/menu.c | 16 ++++++++++++
include/grub/gfxmenu_view.h | 4 +++
include/grub/menu_viewer.h | 1 +
7 files changed, 120 insertions(+)
diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c
index 72b39f90f..9a79494fe 100644
--- a/grub-core/gfxmenu/gfxmenu.c
+++ b/grub-core/gfxmenu/gfxmenu.c
@@ -108,6 +108,15 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
view->menu = menu;
view->nested = nested;
view->first_timeout = -1;
+ if (menu->size)
+ {
+ view->menu_title_offset = grub_calloc (menu->size, sizeof (*view->menu_title_offset));
+ if (!view->menu_title_offset)
+ {
+ grub_free (instance);
+ return grub_errno;
+ }
+ }
grub_video_set_viewport (0, 0, mode_info.width, mode_info.height);
if (view->double_repaint)
@@ -123,6 +132,7 @@ grub_gfxmenu_try (int entry, grub_menu_t menu, int nested)
instance->fini = grub_gfxmenu_viewer_fini;
instance->print_timeout = grub_gfxmenu_print_timeout;
instance->clear_timeout = grub_gfxmenu_clear_timeout;
+ instance->scroll_chosen_entry = grub_gfxmenu_scroll_chosen_entry;
grub_menu_register_viewer (instance);
diff --git a/grub-core/gfxmenu/gui_label.c b/grub-core/gfxmenu/gui_label.c
index ffd50223c..d37eb1721 100644
--- a/grub-core/gfxmenu/gui_label.c
+++ b/grub-core/gfxmenu/gui_label.c
@@ -192,6 +192,8 @@ label_set_property (void *vself, const char *name, const char *value)
"or `c' for a command-line.");
else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0)
value = _("enter: boot, `e': options, `c': cmd-line");
+ else if (grub_strcmp (value, "@SUSE_KEYMAP_SCROLL_ENTRY@") == 0)
+ value = _("ctrl+l: scroll entry left, ctrl+r: scroll entry right");
/* FIXME: Add more templates here if needed. */
if (grub_printf_fmt_check(value, "%d") != GRUB_ERR_NONE)
diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c
index 2ccd4345f..2d77845f8 100644
--- a/grub-core/gfxmenu/gui_list.c
+++ b/grub-core/gfxmenu/gui_list.c
@@ -24,6 +24,7 @@
#include <grub/gfxmenu_view.h>
#include <grub/gfxwidgets.h>
#include <grub/color.h>
+#include <grub/charset.h>
enum scrollbar_slice_mode {
SCROLLBAR_SLICE_WEST,
@@ -314,6 +315,33 @@ draw_scrollbar (list_impl_t self,
thumb->draw (thumb, thumbx, thumby);
}
+static const char *
+grub_utf8_offset_code (const char *src, grub_size_t srcsize, int num)
+{
+ int count = 0;
+ grub_uint32_t code = 0;
+
+ while (srcsize && num)
+ {
+ if (srcsize != (grub_size_t)-1)
+ srcsize--;
+ if (!grub_utf8_process ((grub_uint8_t)*src++, &code, &count))
+ return 0;
+ if (count != 0)
+ continue;
+ if (code == 0)
+ return 0;
+ if (code > GRUB_UNICODE_LAST_VALID)
+ return 0;
+ --num;
+ }
+
+ if (!num)
+ return src;
+
+ return 0;
+}
+
/* Draw the list of items. */
static void
draw_menu (list_impl_t self, int num_shown_items)
@@ -433,6 +461,16 @@ draw_menu (list_impl_t self, int num_shown_items)
const char *item_title =
grub_menu_get_entry (self->view->menu, menu_index)->title;
+ {
+ int off = self->view->menu_title_offset[menu_index];
+ const char *scrolled_title;
+
+ scrolled_title = grub_utf8_offset_code (item_title, grub_strlen (item_title), off);
+
+ if (scrolled_title)
+ item_title = scrolled_title;
+ }
+
sviewport.y = item_top + top_pad;
sviewport.width = viewport_width;
grub_gui_set_viewport (&sviewport, &svpsave);
diff --git a/grub-core/gfxmenu/view.c b/grub-core/gfxmenu/view.c
index 6358004b2..6e5c206d9 100644
--- a/grub-core/gfxmenu/view.c
+++ b/grub-core/gfxmenu/view.c
@@ -37,6 +37,7 @@
#include <grub/gui_string_util.h>
#include <grub/icon_manager.h>
#include <grub/i18n.h>
+#include <grub/charset.h>
static void
init_terminal (grub_gfxmenu_view_t view);
@@ -103,6 +104,7 @@ grub_gfxmenu_view_new (const char *theme_path,
view->title_text = grub_strdup (_("GRUB Boot Menu"));
view->progress_message_text = 0;
view->theme_path = 0;
+ view->menu_title_offset = 0;
/* Set the timeout bar's frame. */
view->progress_message_frame.width = view->screen.width * 4 / 5;
@@ -142,6 +144,7 @@ grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view)
grub_free (view->title_text);
grub_free (view->progress_message_text);
grub_free (view->theme_path);
+ grub_free (view->menu_title_offset);
if (view->canvas)
view->canvas->component.ops->destroy (view->canvas);
grub_free (view);
@@ -410,6 +413,52 @@ grub_gfxmenu_set_chosen_entry (int entry, void *data)
grub_gfxmenu_redraw_menu (view);
}
+static int
+grub_utf8_get_num_code (const char *src, grub_size_t srcsize)
+{
+ int count = 0;
+ grub_uint32_t code = 0;
+ int num = 0;
+
+ while (srcsize)
+ {
+ if (srcsize != (grub_size_t)-1)
+ srcsize--;
+ if (!grub_utf8_process ((grub_uint8_t)*src++, &code, &count))
+ return 0;
+ if (count != 0)
+ continue;
+ if (code == 0)
+ return num;
+ if (code > GRUB_UNICODE_LAST_VALID)
+ return 0;
+ ++num;
+ }
+
+ return num;
+}
+
+void
+grub_gfxmenu_scroll_chosen_entry (void *data, int diren)
+{
+ grub_gfxmenu_view_t view = data;
+ const char *item_title;
+ int off;
+
+ if (!view->menu->size)
+ return;
+
+ item_title =grub_menu_get_entry (view->menu, view->selected)->title;
+ off = view->menu_title_offset[view->selected] + diren;
+
+ if (off < 0
+ || off > grub_utf8_get_num_code (item_title, grub_strlen(item_title)))
+ return;
+
+ view->menu_title_offset[view->selected] = off;
+ grub_gfxmenu_redraw_menu (view);
+}
+
static void
grub_gfxmenu_draw_terminal_box (void)
{
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index 64b377052..e376c603f 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -389,6 +389,15 @@ menu_set_chosen_entry (int entry)
cur->set_chosen_entry (entry, cur->data);
}
+static void
+menu_scroll_chosen_entry (int diren)
+{
+ struct grub_menu_viewer *cur;
+ for (cur = viewers; cur; cur = cur->next)
+ if (cur->scroll_chosen_entry)
+ cur->scroll_chosen_entry (cur->data, diren);
+}
+
static void
menu_print_timeout (int timeout)
{
@@ -819,6 +828,13 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
menu_set_chosen_entry (current_entry);
break;
+ case GRUB_TERM_CTRL | 'w':
+ menu_scroll_chosen_entry (1);
+ break;
+ case GRUB_TERM_CTRL | 'r':
+ menu_scroll_chosen_entry (-1);
+ break;
+
case '\n':
case '\r':
case GRUB_TERM_KEY_RIGHT:
diff --git a/include/grub/gfxmenu_view.h b/include/grub/gfxmenu_view.h
index c9e12db82..3c71277e7 100644
--- a/include/grub/gfxmenu_view.h
+++ b/include/grub/gfxmenu_view.h
@@ -61,6 +61,8 @@ void
grub_gfxmenu_print_timeout (int timeout, void *data);
void
grub_gfxmenu_set_chosen_entry (int entry, void *data);
+void
+grub_gfxmenu_scroll_chosen_entry (void *data, int diren);
grub_err_t grub_font_draw_string (const char *str,
grub_font_t font,
@@ -119,6 +121,8 @@ struct grub_gfxmenu_view
int nested;
int first_timeout;
+
+ int *menu_title_offset;
};
#endif /* ! GRUB_GFXMENU_VIEW_HEADER */
diff --git a/include/grub/menu_viewer.h b/include/grub/menu_viewer.h
index 604c07ad1..b0580dd53 100644
--- a/include/grub/menu_viewer.h
+++ b/include/grub/menu_viewer.h
@@ -33,6 +33,7 @@ struct grub_menu_viewer
void (*set_chosen_entry) (int entry, void *data);
void (*print_timeout) (int timeout, void *data);
void (*clear_timeout) (void *data);
+ void (*scroll_chosen_entry) (void *data, int diren);
void (*fini) (void *fini);
};
--
2.41.0
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/jackzhao166/grub2.git
git@gitee.com:jackzhao166/grub2.git
jackzhao166
grub2
grub2
master

搜索帮助