]> glassweightruler.freedombox.rocks Git - Ventoy.git/blob - GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c
63d8c7be207a6cd915be612c9509370db9a8281c
[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_grub2_mode;
32 extern int g_ventoy_wimboot_mode;
33 extern int g_ventoy_iso_uefi_drv;
34
35 static const char *align_options[] =
36 {
37 "left",
38 "center",
39 "right",
40 0
41 };
42
43 enum align_mode {
44 align_left,
45 align_center,
46 align_right
47 };
48
49 struct grub_gui_label
50 {
51 struct grub_gui_component comp;
52
53 grub_gui_container_t parent;
54 grub_video_rect_t bounds;
55 char *id;
56 int visible;
57 char *text;
58 char *template;
59 grub_font_t font;
60 grub_video_rgba_color_t color;
61 int value;
62 int vtoytip;
63 enum align_mode align;
64 };
65
66 typedef struct grub_gui_label *grub_gui_label_t;
67
68 extern const char * g_ventoy_tip_msg1;
69 extern const char * g_ventoy_tip_msg2;
70
71 static void
72 label_destroy (void *vself)
73 {
74 grub_gui_label_t self = vself;
75 grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
76 grub_free (self->text);
77 grub_free (self->template);
78 grub_free (self);
79 }
80
81 static const char *
82 label_get_id (void *vself)
83 {
84 grub_gui_label_t self = vself;
85 return self->id;
86 }
87
88 static int
89 label_is_instance (void *vself __attribute__((unused)), const char *type)
90 {
91 return grub_strcmp (type, "component") == 0;
92 }
93
94 static void
95 label_paint (void *vself, const grub_video_rect_t *region)
96 {
97 const char *text;
98 grub_gui_label_t self = vself;
99
100 if (! self->visible)
101 return;
102
103 if (!grub_video_have_common_points (region, &self->bounds))
104 return;
105
106 if (self->vtoytip == 1) {
107 text = g_ventoy_tip_msg1 ? g_ventoy_tip_msg1 : "";
108 } else if (self->vtoytip == 2) {
109 text = g_ventoy_tip_msg2 ? g_ventoy_tip_msg2 : "";
110 } else {
111 text = self->text;
112 }
113
114 /* Calculate the starting x coordinate. */
115 int left_x;
116 if (self->align == align_left)
117 left_x = 0;
118 else if (self->align == align_center)
119 left_x = (self->bounds.width
120 - grub_font_get_string_width (self->font, text)) / 2;
121 else if (self->align == align_right)
122 left_x = (self->bounds.width
123 - grub_font_get_string_width (self->font, text));
124 else
125 return; /* Invalid alignment. */
126
127 if (left_x < 0 || left_x > (int) self->bounds.width)
128 left_x = 0;
129
130 grub_video_rect_t vpsave;
131 grub_gui_set_viewport (&self->bounds, &vpsave);
132 grub_font_draw_string (text,
133 self->font,
134 grub_video_map_rgba_color (self->color),
135 left_x,
136 grub_font_get_ascent (self->font));
137 grub_gui_restore_viewport (&vpsave);
138 }
139
140 static void
141 label_set_parent (void *vself, grub_gui_container_t parent)
142 {
143 grub_gui_label_t self = vself;
144 self->parent = parent;
145 }
146
147 static grub_gui_container_t
148 label_get_parent (void *vself)
149 {
150 grub_gui_label_t self = vself;
151 return self->parent;
152 }
153
154 static void
155 label_set_bounds (void *vself, const grub_video_rect_t *bounds)
156 {
157 grub_gui_label_t self = vself;
158 self->bounds = *bounds;
159 }
160
161 static void
162 label_get_bounds (void *vself, grub_video_rect_t *bounds)
163 {
164 grub_gui_label_t self = vself;
165 *bounds = self->bounds;
166 }
167
168 static void
169 label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
170 {
171 grub_gui_label_t self = vself;
172 *width = grub_font_get_string_width (self->font, self->text);
173 *height = (grub_font_get_ascent (self->font)
174 + grub_font_get_descent (self->font));
175 }
176
177 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
178
179 static void
180 label_set_state (void *vself, int visible, int start __attribute__ ((unused)),
181 int current, int end __attribute__ ((unused)))
182 {
183 grub_gui_label_t self = vself;
184 self->value = -current;
185 self->visible = visible;
186 grub_free (self->text);
187 self->text = grub_xasprintf (self->template ? : "%d", self->value);
188 }
189
190 static grub_err_t
191 label_set_property (void *vself, const char *name, const char *value)
192 {
193 grub_gui_label_t self = vself;
194 if (grub_strcmp (name, "text") == 0)
195 {
196 grub_free (self->text);
197 grub_free (self->template);
198 if (! value)
199 {
200 self->template = NULL;
201 self->text = grub_strdup ("");
202 }
203 else
204 {
205 if (grub_strcmp (value, "@KEYMAP_LONG@") == 0)
206 value = _("Press enter to boot the selected OS, "
207 "`e' to edit the commands before booting "
208 "or `c' for a command-line. ESC to return previous menu.");
209 else if (grub_strcmp (value, "@KEYMAP_MIDDLE@") == 0)
210 value = _("Press enter to boot the selected OS, "
211 "`e' to edit the commands before booting "
212 "or `c' for a command-line.");
213 else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0)
214 value = _("enter: boot, `e': options, `c': cmd-line");
215 /* FIXME: Add more templates here if needed. */
216
217 else if (grub_strcmp (value, "@VTOY_MEM_DISK@") == 0) {
218 value = g_ventoy_memdisk_mode ? grub_env_get("VTOY_MEM_DISK_STR") : " ";
219 }
220 else if (grub_strcmp (value, "@VTOY_ISO_RAW@") == 0) {
221 value = g_ventoy_iso_raw ? grub_env_get("VTOY_ISO_RAW_STR") : " ";
222 }
223 else if (grub_strcmp (value, "@VTOY_GRUB2_MODE@") == 0) {
224 value = g_ventoy_grub2_mode ? grub_env_get("VTOY_GRUB2_MODE_STR") : " ";
225 }
226 else if (grub_strcmp (value, "@VTOY_WIMBOOT_MODE@") == 0) {
227 value = g_ventoy_wimboot_mode ? grub_env_get("VTOY_WIMBOOT_MODE_STR") : " ";
228 }
229 else if (grub_strcmp (value, "@VTOY_ISO_UEFI_DRV@") == 0) {
230 value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " ";
231 }
232 else if (grub_strcmp (value, "@VTOY_HOTKEY_TIP@") == 0) {
233 value = grub_env_get("VTOY_HOTKEY_TIP");
234 if (value == NULL) {
235 value = _(" ");
236 }
237 }
238
239 self->template = grub_strdup (value);
240 self->text = grub_xasprintf (value, self->value);
241 }
242 }
243 else if (grub_strcmp (name, "font") == 0)
244 {
245 self->font = grub_font_get (value);
246 }
247 else if (grub_strcmp (name, "color") == 0)
248 {
249 grub_video_parse_color (value, &self->color);
250 }
251 else if (grub_strcmp (name, "align") == 0)
252 {
253 int i;
254 for (i = 0; align_options[i]; i++)
255 {
256 if (grub_strcmp (align_options[i], value) == 0)
257 {
258 self->align = i; /* Set the alignment mode. */
259 break;
260 }
261 }
262 }
263 else if (grub_strcmp (name, "visible") == 0)
264 {
265 self->visible = grub_strcmp (value, "false") != 0;
266 }
267 else if (grub_strcmp (name, "id") == 0)
268 {
269 grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
270 grub_free (self->id);
271 if (value) {
272 self->id = grub_strdup (value);
273 if (grub_strcmp(value, "VTOY_MENU_TIP_1") == 0) {
274 self->vtoytip = 1;
275 } else if (grub_strcmp(value, "VTOY_MENU_TIP_2") == 0) {
276 self->vtoytip = 2;
277 }
278 }
279 else
280 self->id = 0;
281 if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
282 == 0)
283 grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
284 label_set_state);
285 }
286 return GRUB_ERR_NONE;
287 }
288
289 #pragma GCC diagnostic error "-Wformat-nonliteral"
290
291 static struct grub_gui_component_ops label_ops =
292 {
293 .destroy = label_destroy,
294 .get_id = label_get_id,
295 .is_instance = label_is_instance,
296 .paint = label_paint,
297 .set_parent = label_set_parent,
298 .get_parent = label_get_parent,
299 .set_bounds = label_set_bounds,
300 .get_bounds = label_get_bounds,
301 .get_minimal_size = label_get_minimal_size,
302 .set_property = label_set_property
303 };
304
305 grub_gui_component_t
306 grub_gui_label_new (void)
307 {
308 grub_gui_label_t label;
309 label = grub_zalloc (sizeof (*label));
310 if (! label)
311 return 0;
312 label->comp.ops = &label_ops;
313 label->visible = 1;
314 label->text = grub_strdup ("");
315 label->font = grub_font_get ("Unknown Regular 16");
316 label->color.red = 0;
317 label->color.green = 0;
318 label->color.blue = 0;
319 label->color.alpha = 255;
320 label->align = align_left;
321 return (grub_gui_component_t) label;
322 }