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