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