1 /* gui_label.c - GUI component to display a line of text. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008,2009 Free Software Foundation, Inc.
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.
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.
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/>.
21 #include <grub/misc.h>
23 #include <grub/font.h>
24 #include <grub/gui_string_util.h>
25 #include <grub/i18n.h>
26 #include <grub/color.h>
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 extern char g_ventoy_hotkey_tip
[256];
36 static const char *align_options
[] =
52 struct grub_gui_component comp
;
54 grub_gui_container_t parent
;
55 grub_video_rect_t bounds
;
61 grub_video_rgba_color_t color
;
64 enum align_mode align
;
67 typedef struct grub_gui_label
*grub_gui_label_t
;
69 extern const char * g_ventoy_tip_msg1
;
70 extern const char * g_ventoy_tip_msg2
;
73 label_destroy (void *vself
)
75 grub_gui_label_t self
= vself
;
76 grub_gfxmenu_timeout_unregister ((grub_gui_component_t
) self
);
77 grub_free (self
->text
);
78 grub_free (self
->template);
83 label_get_id (void *vself
)
85 grub_gui_label_t self
= vself
;
90 label_is_instance (void *vself
__attribute__((unused
)), const char *type
)
92 return grub_strcmp (type
, "component") == 0;
96 label_paint (void *vself
, const grub_video_rect_t
*region
)
99 grub_gui_label_t self
= vself
;
104 if (!grub_video_have_common_points (region
, &self
->bounds
))
107 if (self
->vtoytip
== 1) {
108 text
= g_ventoy_tip_msg1
? g_ventoy_tip_msg1
: "";
109 } else if (self
->vtoytip
== 2) {
110 text
= g_ventoy_tip_msg2
? g_ventoy_tip_msg2
: "";
115 /* Calculate the starting x coordinate. */
117 if (self
->align
== align_left
)
119 else if (self
->align
== align_center
)
120 left_x
= (self
->bounds
.width
121 - grub_font_get_string_width (self
->font
, text
)) / 2;
122 else if (self
->align
== align_right
)
123 left_x
= (self
->bounds
.width
124 - grub_font_get_string_width (self
->font
, text
));
126 return; /* Invalid alignment. */
128 if (left_x
< 0 || left_x
> (int) self
->bounds
.width
)
131 grub_video_rect_t vpsave
;
132 grub_gui_set_viewport (&self
->bounds
, &vpsave
);
133 grub_font_draw_string (text
,
135 grub_video_map_rgba_color (self
->color
),
137 grub_font_get_ascent (self
->font
));
138 grub_gui_restore_viewport (&vpsave
);
142 label_set_parent (void *vself
, grub_gui_container_t parent
)
144 grub_gui_label_t self
= vself
;
145 self
->parent
= parent
;
148 static grub_gui_container_t
149 label_get_parent (void *vself
)
151 grub_gui_label_t self
= vself
;
156 label_set_bounds (void *vself
, const grub_video_rect_t
*bounds
)
158 grub_gui_label_t self
= vself
;
159 self
->bounds
= *bounds
;
163 label_get_bounds (void *vself
, grub_video_rect_t
*bounds
)
165 grub_gui_label_t self
= vself
;
166 *bounds
= self
->bounds
;
170 label_get_minimal_size (void *vself
, unsigned *width
, unsigned *height
)
172 grub_gui_label_t self
= vself
;
173 *width
= grub_font_get_string_width (self
->font
, self
->text
);
174 *height
= (grub_font_get_ascent (self
->font
)
175 + grub_font_get_descent (self
->font
));
178 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
181 label_set_state (void *vself
, int visible
, int start
__attribute__ ((unused
)),
182 int current
, int end
__attribute__ ((unused
)))
184 grub_gui_label_t self
= vself
;
185 self
->value
= -current
;
186 self
->visible
= visible
;
187 grub_free (self
->text
);
188 self
->text
= grub_xasprintf (self
->template ? : "%d", self
->value
);
192 label_set_property (void *vself
, const char *name
, const char *value
)
194 grub_gui_label_t self
= vself
;
195 if (grub_strcmp (name
, "text") == 0)
197 grub_free (self
->text
);
198 grub_free (self
->template);
201 self
->template = NULL
;
202 self
->text
= grub_strdup ("");
206 if (grub_strcmp (value
, "@KEYMAP_LONG@") == 0)
207 value
= _("Press enter to boot the selected OS, "
208 "`e' to edit the commands before booting "
209 "or `c' for a command-line. ESC to return previous menu.");
210 else if (grub_strcmp (value
, "@KEYMAP_MIDDLE@") == 0)
211 value
= _("Press enter to boot the selected OS, "
212 "`e' to edit the commands before booting "
213 "or `c' for a command-line.");
214 else if (grub_strcmp (value
, "@KEYMAP_SHORT@") == 0)
215 value
= _("enter: boot, `e': options, `c': cmd-line");
216 /* FIXME: Add more templates here if needed. */
218 else if (grub_strcmp (value
, "@VTOY_MEM_DISK@") == 0) {
219 value
= g_ventoy_memdisk_mode
? grub_env_get("VTOY_MEM_DISK_STR") : " ";
221 else if (grub_strcmp (value
, "@VTOY_ISO_RAW@") == 0) {
222 value
= g_ventoy_iso_raw
? grub_env_get("VTOY_ISO_RAW_STR") : " ";
224 else if (grub_strcmp (value
, "@VTOY_GRUB2_MODE@") == 0) {
225 value
= g_ventoy_grub2_mode
? grub_env_get("VTOY_GRUB2_MODE_STR") : " ";
227 else if (grub_strcmp (value
, "@VTOY_WIMBOOT_MODE@") == 0) {
228 value
= g_ventoy_wimboot_mode
? grub_env_get("VTOY_WIMBOOT_MODE_STR") : " ";
230 else if (grub_strcmp (value
, "@VTOY_ISO_UEFI_DRV@") == 0) {
231 value
= g_ventoy_iso_uefi_drv
? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " ";
233 else if (grub_strcmp (value
, "@VTOY_HOTKEY_TIP@") == 0) {
234 value
= g_ventoy_hotkey_tip
;
237 self
->template = grub_strdup (value
);
238 self
->text
= grub_xasprintf (value
, self
->value
);
241 else if (grub_strcmp (name
, "font") == 0)
243 self
->font
= grub_font_get (value
);
245 else if (grub_strcmp (name
, "color") == 0)
247 grub_video_parse_color (value
, &self
->color
);
249 else if (grub_strcmp (name
, "align") == 0)
252 for (i
= 0; align_options
[i
]; i
++)
254 if (grub_strcmp (align_options
[i
], value
) == 0)
256 self
->align
= i
; /* Set the alignment mode. */
261 else if (grub_strcmp (name
, "visible") == 0)
263 self
->visible
= grub_strcmp (value
, "false") != 0;
265 else if (grub_strcmp (name
, "id") == 0)
267 grub_gfxmenu_timeout_unregister ((grub_gui_component_t
) self
);
268 grub_free (self
->id
);
270 self
->id
= grub_strdup (value
);
271 if (grub_strcmp(value
, "VTOY_MENU_TIP_1") == 0) {
273 } else if (grub_strcmp(value
, "VTOY_MENU_TIP_2") == 0) {
279 if (self
->id
&& grub_strcmp (self
->id
, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID
)
281 grub_gfxmenu_timeout_register ((grub_gui_component_t
) self
,
284 return GRUB_ERR_NONE
;
287 #pragma GCC diagnostic error "-Wformat-nonliteral"
289 static struct grub_gui_component_ops label_ops
=
291 .destroy
= label_destroy
,
292 .get_id
= label_get_id
,
293 .is_instance
= label_is_instance
,
294 .paint
= label_paint
,
295 .set_parent
= label_set_parent
,
296 .get_parent
= label_get_parent
,
297 .set_bounds
= label_set_bounds
,
298 .get_bounds
= label_get_bounds
,
299 .get_minimal_size
= label_get_minimal_size
,
300 .set_property
= label_set_property
304 grub_gui_label_new (void)
306 grub_gui_label_t label
;
307 label
= grub_zalloc (sizeof (*label
));
310 label
->comp
.ops
= &label_ops
;
312 label
->text
= grub_strdup ("");
313 label
->font
= grub_font_get ("Unknown Regular 16");
314 label
->color
.red
= 0;
315 label
->color
.green
= 0;
316 label
->color
.blue
= 0;
317 label
->color
.alpha
= 255;
318 label
->align
= align_left
;
319 return (grub_gui_component_t
) label
;