Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
grub2.11974
grub2-gfxmenu-support-scrolling-menu-entry-s-te...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch of Package grub2.11974
From b4c5f80fbfaf912553eca1b12da6fc49de4ae37f Mon Sep 17 00:00:00 2001 From: Michael Chang <mchang@suse.com> 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. --- 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(+) diff --git a/grub-core/gfxmenu/gfxmenu.c b/grub-core/gfxmenu/gfxmenu.c index 8a17dda2c..e834895fb 100644 --- a/grub-core/gfxmenu/gfxmenu.c +++ b/grub-core/gfxmenu/gfxmenu.c @@ -108,6 +108,8 @@ 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_zalloc (sizeof (*view->menu_title_offset) * menu->size); grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); if (view->double_repaint) @@ -123,6 +125,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 a4c817891..8b1358dd4 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. */ self->template = grub_strdup (value); self->text = grub_xasprintf (value, self->value); diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c index 01477cdf2..90487aef4 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 ad5e82b81..7aed7faa1 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); @@ -142,6 +143,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 +412,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 e7a83c2d6..0af20d052 100644 --- a/grub-core/normal/menu.c +++ b/grub-core/normal/menu.c @@ -376,6 +376,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) { @@ -755,6 +764,13 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) menu_set_chosen_entry (current_entry); break; + case GRUB_TERM_CTRL | 'l': + 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 4203c8fb9..56c0d17ae 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 c6513c4e8..5f2a39dc9 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.16.4
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor