Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
dadigang
Ventoy
Commits
84abffc4
Commit
84abffc4
authored
Sep 27, 2020
by
longpanda
Browse files
theme
parent
bf4e0140
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
839 additions
and
0 deletions
+839
-0
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c
+839
-0
No files found.
GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c
0 → 100644
View file @
84abffc4
/* theme_loader.c - Theme file loader for gfxmenu. */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2008 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/types.h>
#include <grub/file.h>
#include <grub/misc.h>
#include <grub/mm.h>
#include <grub/err.h>
#include <grub/dl.h>
#include <grub/video.h>
#include <grub/gui_string_util.h>
#include <grub/bitmap.h>
#include <grub/bitmap_scale.h>
#include <grub/gfxwidgets.h>
#include <grub/gfxmenu_view.h>
#include <grub/gui.h>
#include <grub/color.h>
#include <grub/env.h>
static
grub_err_t
parse_proportional_spec
(
const
char
*
value
,
signed
*
abs
,
grub_fixed_signed_t
*
prop
);
/* Construct a new box widget using ABSPATTERN to find the pixmap files for
it, storing the new box instance at *BOXPTR.
PATTERN should be of the form: "(hd0,0)/somewhere/style*.png".
The '*' then gets substituted with the various pixmap names that the
box uses. */
static
grub_err_t
recreate_box_absolute
(
grub_gfxmenu_box_t
*
boxptr
,
const
char
*
abspattern
)
{
char
*
prefix
;
char
*
suffix
;
char
*
star
;
grub_gfxmenu_box_t
box
;
star
=
grub_strchr
(
abspattern
,
'*'
);
if
(
!
star
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"missing `*' in box pixmap pattern `%s'"
,
abspattern
);
/* Prefix: Get the part before the '*'. */
prefix
=
grub_malloc
(
star
-
abspattern
+
1
);
if
(
!
prefix
)
return
grub_errno
;
grub_memcpy
(
prefix
,
abspattern
,
star
-
abspattern
);
prefix
[
star
-
abspattern
]
=
'\0'
;
/* Suffix: Everything after the '*' is the suffix. */
suffix
=
star
+
1
;
box
=
grub_gfxmenu_create_box
(
prefix
,
suffix
);
grub_free
(
prefix
);
if
(
!
box
)
return
grub_errno
;
if
(
*
boxptr
)
(
*
boxptr
)
->
destroy
(
*
boxptr
);
*
boxptr
=
box
;
return
grub_errno
;
}
/* Construct a new box widget using PATTERN to find the pixmap files for it,
storing the new widget at *BOXPTR. PATTERN should be of the form:
"somewhere/style*.png". The '*' then gets substituted with the various
pixmap names that the widget uses.
Important! The value of *BOXPTR must be initialized! It must either
(1) Be 0 (a NULL pointer), or
(2) Be a pointer to a valid 'grub_gfxmenu_box_t' instance.
In this case, the previous instance is destroyed. */
grub_err_t
grub_gui_recreate_box
(
grub_gfxmenu_box_t
*
boxptr
,
const
char
*
pattern
,
const
char
*
theme_dir
)
{
char
*
abspattern
;
/* Check arguments. */
if
(
!
pattern
)
{
/* If no pixmap pattern is given, then just create an empty box. */
if
(
*
boxptr
)
(
*
boxptr
)
->
destroy
(
*
boxptr
);
*
boxptr
=
grub_gfxmenu_create_box
(
0
,
0
);
return
grub_errno
;
}
if
(
!
theme_dir
)
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"styled box missing theme directory"
);
/* Resolve to an absolute path. */
abspattern
=
grub_resolve_relative_path
(
theme_dir
,
pattern
);
if
(
!
abspattern
)
return
grub_errno
;
/* Create the box. */
recreate_box_absolute
(
boxptr
,
abspattern
);
grub_free
(
abspattern
);
return
grub_errno
;
}
static
grub_err_t
theme_get_unsigned_int_from_proportional
(
const
char
*
value
,
unsigned
absolute_value
,
unsigned
int
*
parsed_value
)
{
grub_err_t
err
;
grub_fixed_signed_t
frac
;
signed
pixels
;
err
=
parse_proportional_spec
(
value
,
&
pixels
,
&
frac
);
if
(
err
!=
GRUB_ERR_NONE
)
return
err
;
int
result
=
grub_fixed_sfs_multiply
(
absolute_value
,
frac
)
+
pixels
;
if
(
result
<
0
)
result
=
0
;
*
parsed_value
=
result
;
return
GRUB_ERR_NONE
;
}
/* Set the specified property NAME on the view to the given string VALUE.
The caller is responsible for the lifetimes of NAME and VALUE. */
static
grub_err_t
theme_set_string
(
grub_gfxmenu_view_t
view
,
const
char
*
name
,
const
char
*
value
,
const
char
*
theme_dir
,
const
char
*
filename
,
int
line_num
,
int
col_num
)
{
if
(
!
grub_strcmp
(
"title-font"
,
name
))
view
->
title_font
=
grub_font_get
(
value
);
else
if
(
!
grub_strcmp
(
"message-font"
,
name
))
view
->
message_font
=
grub_font_get
(
value
);
else
if
(
!
grub_strcmp
(
"terminal-font"
,
name
))
{
grub_free
(
view
->
terminal_font_name
);
view
->
terminal_font_name
=
grub_strdup
(
value
);
if
(
!
view
->
terminal_font_name
)
return
grub_errno
;
}
else
if
(
!
grub_strcmp
(
"title-color"
,
name
))
grub_video_parse_color
(
value
,
&
view
->
title_color
);
else
if
(
!
grub_strcmp
(
"message-color"
,
name
))
grub_video_parse_color
(
value
,
&
view
->
message_color
);
else
if
(
!
grub_strcmp
(
"message-bg-color"
,
name
))
grub_video_parse_color
(
value
,
&
view
->
message_bg_color
);
else
if
(
!
grub_strcmp
(
"desktop-image"
,
name
))
{
struct
grub_video_bitmap
*
raw_bitmap
;
char
*
path
;
path
=
grub_resolve_relative_path
(
theme_dir
,
value
);
if
(
!
path
)
return
grub_errno
;
if
(
grub_video_bitmap_load
(
&
raw_bitmap
,
path
)
!=
GRUB_ERR_NONE
)
{
grub_free
(
path
);
return
grub_errno
;
}
grub_free
(
path
);
grub_video_bitmap_destroy
(
view
->
raw_desktop_image
);
view
->
raw_desktop_image
=
raw_bitmap
;
}
else
if
(
!
grub_strcmp
(
"desktop-image-scale-method"
,
name
))
{
if
(
!
value
||
!
grub_strcmp
(
"stretch"
,
value
))
view
->
desktop_image_scale_method
=
GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH
;
else
if
(
!
grub_strcmp
(
"crop"
,
value
))
view
->
desktop_image_scale_method
=
GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP
;
else
if
(
!
grub_strcmp
(
"padding"
,
value
))
view
->
desktop_image_scale_method
=
GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING
;
else
if
(
!
grub_strcmp
(
"fitwidth"
,
value
))
view
->
desktop_image_scale_method
=
GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH
;
else
if
(
!
grub_strcmp
(
"fitheight"
,
value
))
view
->
desktop_image_scale_method
=
GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT
;
else
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"Unsupported scale method: %s"
,
value
);
}
else
if
(
!
grub_strcmp
(
"desktop-image-h-align"
,
name
))
{
if
(
!
grub_strcmp
(
"left"
,
value
))
view
->
desktop_image_h_align
=
GRUB_VIDEO_BITMAP_H_ALIGN_LEFT
;
else
if
(
!
grub_strcmp
(
"center"
,
value
))
view
->
desktop_image_h_align
=
GRUB_VIDEO_BITMAP_H_ALIGN_CENTER
;
else
if
(
!
grub_strcmp
(
"right"
,
value
))
view
->
desktop_image_h_align
=
GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT
;
else
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"Unsupported horizontal align method: %s"
,
value
);
}
else
if
(
!
grub_strcmp
(
"desktop-image-v-align"
,
name
))
{
if
(
!
grub_strcmp
(
"top"
,
value
))
view
->
desktop_image_v_align
=
GRUB_VIDEO_BITMAP_V_ALIGN_TOP
;
else
if
(
!
grub_strcmp
(
"center"
,
value
))
view
->
desktop_image_v_align
=
GRUB_VIDEO_BITMAP_V_ALIGN_CENTER
;
else
if
(
!
grub_strcmp
(
"bottom"
,
value
))
view
->
desktop_image_v_align
=
GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM
;
else
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"Unsupported vertical align method: %s"
,
value
);
}
else
if
(
!
grub_strcmp
(
"desktop-color"
,
name
))
grub_video_parse_color
(
value
,
&
view
->
desktop_color
);
else
if
(
!
grub_strcmp
(
"terminal-box"
,
name
))
{
grub_err_t
err
;
err
=
grub_gui_recreate_box
(
&
view
->
terminal_box
,
value
,
theme_dir
);
if
(
err
!=
GRUB_ERR_NONE
)
return
err
;
}
else
if
(
!
grub_strcmp
(
"terminal-border"
,
name
))
{
view
->
terminal_border
=
grub_strtoul
(
value
,
0
,
10
);
if
(
grub_errno
)
return
grub_errno
;
}
else
if
(
!
grub_strcmp
(
"terminal-left"
,
name
))
{
unsigned
int
tmp
;
int
err
=
theme_get_unsigned_int_from_proportional
(
value
,
view
->
screen
.
width
,
&
tmp
);
if
(
err
!=
GRUB_ERR_NONE
)
return
err
;
view
->
terminal_rect
.
x
=
tmp
;
}
else
if
(
!
grub_strcmp
(
"terminal-top"
,
name
))
{
unsigned
int
tmp
;
int
err
=
theme_get_unsigned_int_from_proportional
(
value
,
view
->
screen
.
height
,
&
tmp
);
if
(
err
!=
GRUB_ERR_NONE
)
return
err
;
view
->
terminal_rect
.
y
=
tmp
;
}
else
if
(
!
grub_strcmp
(
"terminal-width"
,
name
))
{
unsigned
int
tmp
;
int
err
=
theme_get_unsigned_int_from_proportional
(
value
,
view
->
screen
.
width
,
&
tmp
);
if
(
err
!=
GRUB_ERR_NONE
)
return
err
;
view
->
terminal_rect
.
width
=
tmp
;
}
else
if
(
!
grub_strcmp
(
"terminal-height"
,
name
))
{
unsigned
int
tmp
;
int
err
=
theme_get_unsigned_int_from_proportional
(
value
,
view
->
screen
.
height
,
&
tmp
);
if
(
err
!=
GRUB_ERR_NONE
)
return
err
;
view
->
terminal_rect
.
height
=
tmp
;
}
else
if
(
!
grub_strcmp
(
"title-text"
,
name
))
{
grub_free
(
view
->
title_text
);
view
->
title_text
=
grub_strdup
(
value
);
if
(
!
view
->
title_text
)
return
grub_errno
;
}
else
{
return
grub_error
(
GRUB_ERR_BAD_ARGUMENT
,
"%s:%d:%d unknown property `%s'"
,
filename
,
line_num
,
col_num
,
name
);
}
return
grub_errno
;
}
struct
parsebuf
{
char
*
buf
;
int
pos
;
int
len
;
int
line_num
;
int
col_num
;
const
char
*
filename
;
char
*
theme_dir
;
grub_gfxmenu_view_t
view
;
};
static
int
has_more
(
struct
parsebuf
*
p
)
{
return
p
->
pos
<
p
->
len
;
}
static
int
read_char
(
struct
parsebuf
*
p
)
{
if
(
has_more
(
p
))
{
char
c
;
c
=
p
->
buf
[
p
->
pos
++
];
if
(
c
==
'\n'
)
{
p
->
line_num
++
;
p
->
col_num
=
1
;
}
else
{
p
->
col_num
++
;
}
return
c
;
}
else
return
-
1
;
}
static
int
peek_char
(
struct
parsebuf
*
p
)
{
if
(
has_more
(
p
))
return
p
->
buf
[
p
->
pos
];
else
return
-
1
;
}
static
int
is_whitespace
(
char
c
)
{
return
(
c
==
' '
||
c
==
'\t'
||
c
==
'\r'
||
c
==
'\n'
||
c
==
'\f'
);
}
static
void
skip_whitespace
(
struct
parsebuf
*
p
)
{
while
(
has_more
(
p
)
&&
is_whitespace
(
peek_char
(
p
)))
read_char
(
p
);
}
static
void
advance_to_next_line
(
struct
parsebuf
*
p
)
{
int
c
;
/* Eat characters up to the newline. */
do
{
c
=
read_char
(
p
);
}
while
(
c
!=
-
1
&&
c
!=
'\n'
);
}
static
int
is_identifier_char
(
int
c
)
{
return
(
c
!=
-
1
&&
(
grub_isalpha
(
c
)
||
grub_isdigit
(
c
)
||
c
==
'_'
||
c
==
'-'
));
}
static
char
*
read_identifier
(
struct
parsebuf
*
p
)
{
/* Index of the first character of the identifier in p->buf. */
int
start
;
/* Next index after the last character of the identifer in p->buf. */
int
end
;
skip_whitespace
(
p
);
/* Capture the start of the identifier. */
start
=
p
->
pos
;
/* Scan for the end. */
while
(
is_identifier_char
(
peek_char
(
p
)))
read_char
(
p
);
end
=
p
->
pos
;
if
(
end
-
start
<
1
)
return
0
;
return
grub_new_substring
(
p
->
buf
,
start
,
end
);
}
static
char
*
read_expression
(
struct
parsebuf
*
p
)
{
int
start
;
int
end
;
skip_whitespace
(
p
);
if
(
peek_char
(
p
)
==
'"'
)
{
/* Read as a quoted string.
The quotation marks are not included in the expression value. */
/* Skip opening quotation mark. */
read_char
(
p
);
start
=
p
->
pos
;
while
(
has_more
(
p
)
&&
peek_char
(
p
)
!=
'"'
)
read_char
(
p
);
end
=
p
->
pos
;
/* Skip the terminating quotation mark. */
read_char
(
p
);
}
else
if
(
peek_char
(
p
)
==
'('
)
{
/* Read as a parenthesized string -- for tuples/coordinates. */
/* The parentheses are included in the expression value. */
int
c
;
start
=
p
->
pos
;
do
{
c
=
read_char
(
p
);
}
while
(
c
!=
-
1
&&
c
!=
')'
);
end
=
p
->
pos
;
}
else
if
(
has_more
(
p
))
{
/* Read as a single word -- for numeric values or words without
whitespace. */
start
=
p
->
pos
;
while
(
has_more
(
p
)
&&
!
is_whitespace
(
peek_char
(
p
)))
read_char
(
p
);
end
=
p
->
pos
;
}
else
{
/* The end of the theme file has been reached. */
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d expression expected in theme file"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
);
return
0
;
}
return
grub_new_substring
(
p
->
buf
,
start
,
end
);
}
static
grub_err_t
parse_proportional_spec
(
const
char
*
value
,
signed
*
abs
,
grub_fixed_signed_t
*
prop
)
{
signed
num
;
const
char
*
ptr
;
int
sig
=
0
;
*
abs
=
0
;
*
prop
=
0
;
ptr
=
value
;
while
(
*
ptr
)
{
sig
=
0
;
while
(
*
ptr
==
'-'
||
*
ptr
==
'+'
)
{
if
(
*
ptr
==
'-'
)
sig
=
!
sig
;
ptr
++
;
}
num
=
grub_strtoul
(
ptr
,
(
char
**
)
&
ptr
,
0
);
if
(
grub_errno
)
return
grub_errno
;
if
(
sig
)
num
=
-
num
;
if
(
*
ptr
==
'%'
)
{
*
prop
+=
grub_fixed_fsf_divide
(
grub_signed_to_fixed
(
num
),
100
);
ptr
++
;
}
else
*
abs
+=
num
;
}
return
GRUB_ERR_NONE
;
}
/* Read a GUI object specification from the theme file.
Any components created will be added to the GUI container PARENT. */
static
grub_err_t
read_object
(
struct
parsebuf
*
p
,
grub_gui_container_t
parent
)
{
grub_video_rect_t
bounds
;
char
*
name
;
name
=
read_identifier
(
p
);
if
(
!
name
)
goto
cleanup
;
grub_gui_component_t
component
=
0
;
if
(
grub_strcmp
(
name
,
"label"
)
==
0
)
{
component
=
grub_gui_label_new
();
}
else
if
(
grub_strcmp
(
name
,
"image"
)
==
0
)
{
component
=
grub_gui_image_new
();
}
else
if
(
grub_strcmp
(
name
,
"vbox"
)
==
0
)
{
component
=
(
grub_gui_component_t
)
grub_gui_vbox_new
();
}
else
if
(
grub_strcmp
(
name
,
"hbox"
)
==
0
)
{
component
=
(
grub_gui_component_t
)
grub_gui_hbox_new
();
}
else
if
(
grub_strcmp
(
name
,
"canvas"
)
==
0
)
{
component
=
(
grub_gui_component_t
)
grub_gui_canvas_new
();
}
else
if
(
grub_strcmp
(
name
,
"progress_bar"
)
==
0
)
{
component
=
grub_gui_progress_bar_new
();
}
else
if
(
grub_strcmp
(
name
,
"circular_progress"
)
==
0
)
{
component
=
grub_gui_circular_progress_new
();
}
else
if
(
grub_strcmp
(
name
,
"boot_menu"
)
==
0
)
{
component
=
grub_gui_list_new
();
}
else
{
/* Unknown type. */
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d unknown object type `%s'"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
,
name
);
goto
cleanup
;
}
if
(
!
component
)
goto
cleanup
;
/* Inform the component about the theme so it can find its resources. */
component
->
ops
->
set_property
(
component
,
"theme_dir"
,
p
->
theme_dir
);
component
->
ops
->
set_property
(
component
,
"theme_path"
,
p
->
filename
);
/* Add the component as a child of PARENT. */
bounds
.
x
=
0
;
bounds
.
y
=
0
;
bounds
.
width
=
-
1
;
bounds
.
height
=
-
1
;
component
->
ops
->
set_bounds
(
component
,
&
bounds
);
parent
->
ops
->
add
(
parent
,
component
);
skip_whitespace
(
p
);
if
(
read_char
(
p
)
!=
'{'
)
{
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d expected `{' after object type name `%s'"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
,
name
);
goto
cleanup
;
}
while
(
has_more
(
p
))
{
skip_whitespace
(
p
);
/* Check whether the end has been encountered. */
if
(
peek_char
(
p
)
==
'}'
)
{
/* Skip the closing brace. */
read_char
(
p
);
break
;
}
if
(
peek_char
(
p
)
==
'#'
)
{
/* Skip comments. */
advance_to_next_line
(
p
);
continue
;
}
if
(
peek_char
(
p
)
==
'+'
)
{
/* Skip the '+'. */
read_char
(
p
);
/* Check whether this component is a container. */
if
(
component
->
ops
->
is_instance
(
component
,
"container"
))
{
/* Read the sub-object recursively and add it as a child. */
if
(
read_object
(
p
,
(
grub_gui_container_t
)
component
)
!=
0
)
goto
cleanup
;
/* After reading the sub-object, resume parsing, expecting
another property assignment or sub-object definition. */
continue
;
}
else
{
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d attempted to add object to non-container"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
);
goto
cleanup
;
}
}
char
*
property
;
property
=
read_identifier
(
p
);
if
(
!
property
)
{
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d identifier expected in theme file"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
);
goto
cleanup
;
}
skip_whitespace
(
p
);
if
(
read_char
(
p
)
!=
'='
)
{
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d expected `=' after property name `%s'"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
,
property
);
grub_free
(
property
);
goto
cleanup
;
}
skip_whitespace
(
p
);
char
*
value
;
value
=
read_expression
(
p
);
if
(
!
value
)
{
grub_free
(
property
);
goto
cleanup
;
}
/* Handle the property value. */
if
(
grub_strcmp
(
property
,
"left"
)
==
0
)
parse_proportional_spec
(
value
,
&
component
->
x
,
&
component
->
xfrac
);
else
if
(
grub_strcmp
(
property
,
"top"
)
==
0
)
parse_proportional_spec
(
value
,
&
component
->
y
,
&
component
->
yfrac
);
else
if
(
grub_strcmp
(
property
,
"width"
)
==
0
)
parse_proportional_spec
(
value
,
&
component
->
w
,
&
component
->
wfrac
);
else
if
(
grub_strcmp
(
property
,
"height"
)
==
0
)
parse_proportional_spec
(
value
,
&
component
->
h
,
&
component
->
hfrac
);
else
/* General property handling. */
component
->
ops
->
set_property
(
component
,
property
,
value
);
grub_free
(
value
);
grub_free
(
property
);
if
(
grub_errno
!=
GRUB_ERR_NONE
)
goto
cleanup
;
}
cleanup:
grub_free
(
name
);
return
grub_errno
;
}
static
grub_err_t
read_property
(
struct
parsebuf
*
p
)
{
char
*
name
;
/* Read the property name. */
name
=
read_identifier
(
p
);
if
(
!
name
)
{
advance_to_next_line
(
p
);
return
grub_errno
;
}
/* Skip whitespace before separator. */
skip_whitespace
(
p
);
/* Read separator. */
if
(
read_char
(
p
)
!=
':'
)
{
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d missing separator after property name `%s'"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
,
name
);
goto
done
;
}
/* Skip whitespace after separator. */
skip_whitespace
(
p
);
/* Get the value based on its type. */
if
(
peek_char
(
p
)
==
'"'
)
{
/* String value (e.g., '"My string"'). */
char
*
value
=
read_expression
(
p
);
if
(
!
value
)
{
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d missing property value"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
);
goto
done
;
}
/* If theme_set_string results in an error, grub_errno will be returned
below. */
theme_set_string
(
p
->
view
,
name
,
value
,
p
->
theme_dir
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
);
grub_free
(
value
);
}
else
{
grub_error
(
GRUB_ERR_IO
,
"%s:%d:%d property value invalid; "
"enclose literal values in quotes (
\"
)"
,
p
->
filename
,
p
->
line_num
,
p
->
col_num
);
goto
done
;
}
done:
grub_free
(
name
);
return
grub_errno
;
}
/* Set properties on the view based on settings from the specified
theme file. */
grub_err_t
grub_gfxmenu_view_load_theme
(
grub_gfxmenu_view_t
view
,
const
char
*
theme_path
)
{
grub_file_t
file
;
struct
parsebuf
p
;
p
.
view
=
view
;
p
.
theme_dir
=
grub_get_dirname
(
theme_path
);
file
=
grub_file_open
(
theme_path
,
GRUB_FILE_TYPE_THEME
);
if
(
!
file
)
{
grub_free
(
p
.
theme_dir
);
return
grub_errno
;
}
p
.
len
=
grub_file_size
(
file
);
p
.
buf
=
grub_malloc
(
p
.
len
+
4096
);
p
.
pos
=
0
;
p
.
line_num
=
1
;
p
.
col_num
=
1
;
p
.
filename
=
theme_path
;
if
(
!
p
.
buf
)
{
grub_file_close
(
file
);
grub_free
(
p
.
theme_dir
);
return
grub_errno
;
}
if
(
grub_file_read
(
file
,
p
.
buf
,
p
.
len
)
!=
p
.
len
)
{
grub_free
(
p
.
buf
);
grub_file_close
(
file
);
grub_free
(
p
.
theme_dir
);
return
grub_errno
;
}
{
const
char
*
checkret
=
grub_env_get
(
"VTOY_CHKDEV_RESULT_STRING"
);
if
(
checkret
==
NULL
||
checkret
[
0
]
!=
'0'
)
{
p
.
len
+=
grub_snprintf
(
p
.
buf
+
p
.
len
,
4096
,
"
\n
+ hbox{
\n
left = 1%%
\n
top = 90%%
\n
"
" + label {text =
\"
[Unofficial Ventoy]
\"
color =
\"
red
\"
align =
\"
left
\"
}
\n
"
"}
\n
"
);
}
}
if
(
view
->
canvas
)
view
->
canvas
->
component
.
ops
->
destroy
(
view
->
canvas
);
view
->
canvas
=
grub_gui_canvas_new
();
if
(
!
view
->
canvas
)
goto
fail
;
((
grub_gui_component_t
)
view
->
canvas
)
->
ops
->
set_bounds
((
grub_gui_component_t
)
view
->
canvas
,
&
view
->
screen
);
while
(
has_more
(
&
p
))
{
/* Skip comments (lines beginning with #). */
if
(
peek_char
(
&
p
)
==
'#'
)
{
advance_to_next_line
(
&
p
);
continue
;
}
/* Find the first non-whitespace character. */
skip_whitespace
(
&
p
);
/* Handle the content. */
if
(
peek_char
(
&
p
)
==
'+'
)
{
/* Skip the '+'. */
read_char
(
&
p
);
read_object
(
&
p
,
view
->
canvas
);
}
else
{
read_property
(
&
p
);
}
if
(
grub_errno
!=
GRUB_ERR_NONE
)
goto
fail
;
}
/* Set the new theme path. */
grub_free
(
view
->
theme_path
);
view
->
theme_path
=
grub_strdup
(
theme_path
);
goto
cleanup
;
fail:
if
(
view
->
canvas
)
{
view
->
canvas
->
component
.
ops
->
destroy
(
view
->
canvas
);
view
->
canvas
=
0
;
}
cleanup:
grub_free
(
p
.
buf
);
grub_file_close
(
file
);
grub_free
(
p
.
theme_dir
);
return
grub_errno
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment