代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/grub2 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From b4c5f80fbfaf912553eca1b12da6fc49de4ae37f Mon Sep 17 00:00:00 2001
From: Michael Chang <[email protected]>
Date: Mon, 7 Jan 2019 17:55:05 +0800
Subject: [PATCH] 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 | 3 +++
grub-core/gfxmenu/gui_label.c | 2 ++
grub-core/gfxmenu/gui_list.c | 38 ++++++++++++++++++++++++++++++++++
grub-core/gfxmenu/view.c | 48 +++++++++++++++++++++++++++++++++++++++++++
grub-core/normal/menu.c | 16 +++++++++++++++
include/grub/gfxmenu_view.h | 4 ++++
include/grub/menu_viewer.h | 1 +
7 files changed, 112 insertions(+)
--- a/grub-core/gfxmenu/gfxmenu.c
+++ b/grub-core/gfxmenu/gfxmenu.c
@@ -108,6 +108,15 @@
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 @@
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);
--- a/grub-core/gfxmenu/gui_label.c
+++ b/grub-core/gfxmenu/gui_label.c
@@ -192,6 +192,8 @@
"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)
--- 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 @@
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 @@
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);
--- 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 @@
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_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_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)
{
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -400,6 +400,15 @@
}
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)
{
struct grub_menu_viewer *cur;
@@ -829,6 +838,13 @@
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:
--- a/include/grub/gfxmenu_view.h
+++ b/include/grub/gfxmenu_view.h
@@ -61,6 +61,8 @@
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 @@
int nested;
int first_timeout;
+
+ int *menu_title_offset;
};
#endif /* ! GRUB_GFXMENU_VIEW_HEADER */
--- a/include/grub/menu_viewer.h
+++ b/include/grub/menu_viewer.h
@@ -33,6 +33,7 @@
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);
};
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。