]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c
e1c1d478d78a215ec932fc17df3734e7a3ce4e77
[Ventoy.git] / GRUB2 / MOD_SRC / grub-2.04 / grub-core / gfxmenu / gui_label.c
1 /* gui_label.c - GUI component to display a line of text. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008,2009 Free Software Foundation, Inc.
5 *
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <grub/mm.h>
21 #include <grub/misc.h>
22 #include <grub/gui.h>
23 #include <grub/font.h>
24 #include <grub/gui_string_util.h>
25 #include <grub/i18n.h>
26 #include <grub/color.h>
27 #include <grub/env.h>
28
29 extern int g_ventoy_memdisk_mode;
30 extern int g_ventoy_iso_raw;
31 extern int g_ventoy_iso_uefi_drv;
32
33 static const char *align_options[] =
34 {
35 "left",
36 "center",
37 "right",
38 0
39 };
40
41 enum align_mode {
42 align_left,
43 align_center,
44 align_right
45 };
46
47 struct grub_gui_label
48 {
49 struct grub_gui_component comp;
50
51 grub_gui_container_t parent;
52 grub_video_rect_t bounds;
53 char *id;
54 int visible;
55 char *text;
56 char *template;
57 grub_font_t font;
58 grub_video_rgba_color_t color;
59 int value;
60 enum align_mode align;
61 };
62
63 typedef struct grub_gui_label *grub_gui_label_t;
64
65 static void
66 label_destroy (void *vself)
67 {
68 grub_gui_label_t self = vself;
69 grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
70 grub_free (self->text);
71 grub_free (self->template);
72 grub_free (self);
73 }
74
75 static const char *
76 label_get_id (void *vself)
77 {
78 grub_gui_label_t self = vself;
79 return self->id;
80 }
81
82 static int
83 label_is_instance (void *vself __attribute__((unused)), const char *type)
84 {
85 return grub_strcmp (type, "component") == 0;
86 }
87
88 static void
89 label_paint (void *vself, const grub_video_rect_t *region)
90 {
91 grub_gui_label_t self = vself;
92
93 if (! self->visible)
94 return;
95
96 if (!grub_video_have_common_points (region, &self->bounds))
97 return;
98
99 /* Calculate the starting x coordinate. */
100 int left_x;
101 if (self->align == align_left)
102 left_x = 0;
103 else if (self->align == align_center)
104 left_x = (self->bounds.width
105 - grub_font_get_string_width (self->font, self->text)) / 2;
106 else if (self->align == align_right)
107 left_x = (self->bounds.width
108 - grub_font_get_string_width (self->font, self->text));
109 else
110 return; /* Invalid alignment. */
111
112 if (left_x < 0 || left_x > (int) self->bounds.width)
113 left_x = 0;
114
115 grub_video_rect_t vpsave;
116 grub_gui_set_viewport (&self->bounds, &vpsave);
117 grub_font_draw_string (self->text,
118 self->font,
119 grub_video_map_rgba_color (self->color),
120 left_x,
121 grub_font_get_ascent (self->font));
122 grub_gui_restore_viewport (&vpsave);
123 }
124
125 static void
126 label_set_parent (void *vself, grub_gui_container_t parent)
127 {
128 grub_gui_label_t self = vself;
129 self->parent = parent;
130 }
131
132 static grub_gui_container_t
133 label_get_parent (void *vself)
134 {
135 grub_gui_label_t self = vself;
136 return self->parent;
137 }
138
139 static void
140 label_set_bounds (void *vself, const grub_video_rect_t *bounds)
141 {
142 grub_gui_label_t self = vself;
143 self->bounds = *bounds;
144 }
145
146 static void
147 label_get_bounds (void *vself, grub_video_rect_t *bounds)
148 {
149 grub_gui_label_t self = vself;
150 *bounds = self->bounds;
151 }
152
153 static void
154 label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
155 {
156 grub_gui_label_t self = vself;
157 *width = grub_font_get_string_width (self->font, self->text);
158 *height = (grub_font_get_ascent (self->font)
159 + grub_font_get_descent (self->font));
160 }
161
162 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
163
164 static void
165 label_set_state (void *vself, int visible, int start __attribute__ ((unused)),
166 int current, int end __attribute__ ((unused)))
167 {
168 grub_gui_label_t self = vself;
169 self->value = -current;
170 self->visible = visible;
171 grub_free (self->text);
172 self->text = grub_xasprintf (self->template ? : "%d", self->value);
173 }
174
175 static grub_err_t
176 label_set_property (void *vself, const char *name, const char *value)
177 {
178 grub_gui_label_t self = vself;
179 if (grub_strcmp (name, "text") == 0)
180 {
181 grub_free (self->text);
182 grub_free (self->template);
183 if (! value)
184 {
185 self->template = NULL;
186 self->text = grub_strdup ("");
187 }
188 else
189 {
190 if (grub_strcmp (value, "@KEYMAP_LONG@") == 0)
191 value = _("Press enter to boot the selected OS, "
192 "`e' to edit the commands before booting "
193 "or `c' for a command-line. ESC to return previous menu.");
194 else if (grub_strcmp (value, "@KEYMAP_MIDDLE@") == 0)
195 value = _("Press enter to boot the selected OS, "
196 "`e' to edit the commands before booting "
197 "or `c' for a command-line.");
198 else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0)
199 value = _("enter: boot, `e': options, `c': cmd-line");
200 /* FIXME: Add more templates here if needed. */
201
202 else if (grub_strcmp (value, "@VTOY_MEM_DISK@") == 0) {
203 value = g_ventoy_memdisk_mode ? grub_env_get("VTOY_MEM_DISK_STR") : " ";
204 }
205 else if (grub_strcmp (value, "@VTOY_ISO_RAW@") == 0) {
206 value = g_ventoy_iso_raw ? grub_env_get("VTOY_ISO_RAW_STR") : " ";
207 }
208 else if (grub_strcmp (value, "@VTOY_ISO_UEFI_DRV@") == 0) {
209 value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " ";
210 }
211 else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) {
212 value = grub_env_get("VTOY_HOTKEY_TIP");
213 if (value == NULL) {
214 value = _(" ");
215 }
216 }
217
218 self->template = grub_strdup (value);
219 self->text = grub_xasprintf (value, self->value);
220 }
221 }
222 else if (grub_strcmp (name, "font") == 0)
223 {
224 self->font = grub_font_get (value);
225 }
226 else if (grub_strcmp (name, "color") == 0)
227 {
228 grub_video_parse_color (value, &self->color);
229 }
230 else if (grub_strcmp (name, "align") == 0)
231 {
232 int i;
233 for (i = 0; align_options[i]; i++)
234 {
235 if (grub_strcmp (align_options[i], value) == 0)
236 {
237 self->align = i; /* Set the alignment mode. */
238 break;
239 }
240 }
241 }
242 else if (grub_strcmp (name, "visible") == 0)
243 {
244 self->visible = grub_strcmp (value, "false") != 0;
245 }
246 else if (grub_strcmp (name, "id") == 0)
247 {
248 grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
249 grub_free (self->id);
250 if (value)
251 self->id = grub_strdup (value);
252 else
253 self->id = 0;
254 if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
255 == 0)
256 grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
257 label_set_state);
258 }
259 return GRUB_ERR_NONE;
260 }
261
262 #pragma GCC diagnostic error "-Wformat-nonliteral"
263
264 static struct grub_gui_component_ops label_ops =
265 {
266 .destroy = label_destroy,
267 .get_id = label_get_id,
268 .is_instance = label_is_instance,
269 .paint = label_paint,
270 .set_parent = label_set_parent,
271 .get_parent = label_get_parent,
272 .set_bounds = label_set_bounds,
273 .get_bounds = label_get_bounds,
274 .get_minimal_size = label_get_minimal_size,
275 .set_property = label_set_property
276 };
277
278 grub_gui_component_t
279 grub_gui_label_new (void)
280 {
281 grub_gui_label_t label;
282 label = grub_zalloc (sizeof (*label));
283 if (! label)
284 return 0;
285 label->comp.ops = &label_ops;
286 label->visible = 1;
287 label->text = grub_strdup ("");
288 label->font = grub_font_get ("Unknown Regular 16");
289 label->color.red = 0;
290 label->color.green = 0;
291 label->color.blue = 0;
292 label->color.alpha = 255;
293 label->align = align_left;
294 return (grub_gui_component_t) label;
295 }