source: grub-pc/trunk/fuentes/grub-core/gfxmenu/gui_image.c @ 22

Last change on this file since 22 was 22, checked in by mabarracus, 4 years ago

updated version and apply net.ifnames=0 into debian/rules

File size: 6.7 KB
Line 
1/* gui_image.c - GUI component to display an image.  */
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/gui_string_util.h>
24#include <grub/bitmap.h>
25#include <grub/bitmap_scale.h>
26
27struct grub_gui_image
28{
29  struct grub_gui_component component;
30
31  grub_gui_container_t parent;
32  grub_video_rect_t bounds;
33  char *id;
34  char *theme_dir;
35  struct grub_video_bitmap *raw_bitmap;
36  struct grub_video_bitmap *bitmap;
37};
38
39typedef struct grub_gui_image *grub_gui_image_t;
40
41static void
42image_destroy (void *vself)
43{
44  grub_gui_image_t self = vself;
45
46  /* Free the scaled bitmap, unless it's a reference to the raw bitmap.  */
47  if (self->bitmap && (self->bitmap != self->raw_bitmap))
48    grub_video_bitmap_destroy (self->bitmap);
49  if (self->raw_bitmap)
50    grub_video_bitmap_destroy (self->raw_bitmap);
51
52  grub_free (self);
53}
54
55static const char *
56image_get_id (void *vself)
57{
58  grub_gui_image_t self = vself;
59  return self->id;
60}
61
62static int
63image_is_instance (void *vself __attribute__((unused)), const char *type)
64{
65  return grub_strcmp (type, "component") == 0;
66}
67
68static void
69image_paint (void *vself, const grub_video_rect_t *region)
70{
71  grub_gui_image_t self = vself;
72  grub_video_rect_t vpsave;
73
74  if (! self->bitmap)
75    return;
76  if (!grub_video_have_common_points (region, &self->bounds))
77    return;
78
79  grub_gui_set_viewport (&self->bounds, &vpsave);
80  grub_video_blit_bitmap (self->bitmap, GRUB_VIDEO_BLIT_BLEND,
81                          0, 0, 0, 0,
82                          grub_video_bitmap_get_width (self->bitmap),
83                          grub_video_bitmap_get_height (self->bitmap));
84  grub_gui_restore_viewport (&vpsave);
85}
86
87static void
88image_set_parent (void *vself, grub_gui_container_t parent)
89{
90  grub_gui_image_t self = vself;
91  self->parent = parent;
92}
93
94static grub_gui_container_t
95image_get_parent (void *vself)
96{
97  grub_gui_image_t self = vself;
98  return self->parent;
99}
100
101static grub_err_t
102rescale_image (grub_gui_image_t self)
103{
104  signed width;
105  signed height;
106
107  if (! self->raw_bitmap)
108    {
109      if (self->bitmap)
110        {
111          grub_video_bitmap_destroy (self->bitmap);
112          self->bitmap = 0;
113        }
114      return grub_errno;
115    }
116
117  width = self->bounds.width;
118  height = self->bounds.height;
119
120  if (self->bitmap
121      && ((signed) grub_video_bitmap_get_width (self->bitmap) == width)
122      && ((signed) grub_video_bitmap_get_height (self->bitmap) == height))
123    {
124      /* Nothing to do; already the right size.  */
125      return grub_errno;
126    }
127
128  /* Free any old scaled bitmap,
129     *unless* it's a reference to the raw bitmap.  */
130  if (self->bitmap && (self->bitmap != self->raw_bitmap))
131    grub_video_bitmap_destroy (self->bitmap);
132
133  self->bitmap = 0;
134
135  /* Create a scaled bitmap, unless the requested size is the same
136     as the raw size -- in that case a reference is made.  */
137  if ((signed) grub_video_bitmap_get_width (self->raw_bitmap) == width
138      && (signed) grub_video_bitmap_get_height (self->raw_bitmap) == height)
139    {
140      self->bitmap = self->raw_bitmap;
141      return grub_errno;
142    }
143
144  /* Don't scale to an invalid size.  */
145  if (width <= 0 || height <= 0)
146    return grub_errno;
147
148  /* Create the scaled bitmap.  */
149  grub_video_bitmap_create_scaled (&self->bitmap,
150                                   width,
151                                   height,
152                                   self->raw_bitmap,
153                                   GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST);
154  return grub_errno;
155}
156
157static void
158image_set_bounds (void *vself, const grub_video_rect_t *bounds)
159{
160  grub_gui_image_t self = vself;
161  self->bounds = *bounds;
162  rescale_image (self);
163}
164
165static void
166image_get_bounds (void *vself, grub_video_rect_t *bounds)
167{
168  grub_gui_image_t self = vself;
169  *bounds = self->bounds;
170}
171
172/* FIXME: inform rendering system it's not forced minimum.  */
173static void
174image_get_minimal_size (void *vself, unsigned *width, unsigned *height)
175{
176  grub_gui_image_t self = vself;
177
178  if (self->raw_bitmap)
179    {
180      *width = grub_video_bitmap_get_width (self->raw_bitmap);
181      *height = grub_video_bitmap_get_height (self->raw_bitmap);
182    }
183  else
184    {
185      *width = 0;
186      *height = 0;
187    }
188}
189
190static grub_err_t
191load_image (grub_gui_image_t self, const char *path)
192{
193  struct grub_video_bitmap *bitmap;
194  if (grub_video_bitmap_load (&bitmap, path) != GRUB_ERR_NONE)
195    return grub_errno;
196
197  if (self->bitmap && (self->bitmap != self->raw_bitmap))
198    grub_video_bitmap_destroy (self->bitmap);
199  if (self->raw_bitmap)
200    grub_video_bitmap_destroy (self->raw_bitmap);
201
202  self->raw_bitmap = bitmap;
203  return rescale_image (self);
204}
205
206static grub_err_t
207image_set_property (void *vself, const char *name, const char *value)
208{
209  grub_gui_image_t self = vself;
210  if (grub_strcmp (name, "theme_dir") == 0)
211    {
212      grub_free (self->theme_dir);
213      self->theme_dir = grub_strdup (value);
214    }
215  else if (grub_strcmp (name, "file") == 0)
216    {
217      char *absvalue;
218      grub_err_t err;
219
220      /* Resolve to an absolute path.  */
221      if (! self->theme_dir)
222        return grub_error (GRUB_ERR_BUG, "unspecified theme_dir");
223      absvalue = grub_resolve_relative_path (self->theme_dir, value);
224      if (! absvalue)
225        return grub_errno;
226
227      err = load_image (self, absvalue);
228      grub_free (absvalue);
229
230      return err;
231    }
232  else if (grub_strcmp (name, "id") == 0)
233    {
234      grub_free (self->id);
235      if (value)
236        self->id = grub_strdup (value);
237      else
238        self->id = 0;
239    }
240  return grub_errno;
241}
242
243static struct grub_gui_component_ops image_ops =
244{
245  .destroy = image_destroy,
246  .get_id = image_get_id,
247  .is_instance = image_is_instance,
248  .paint = image_paint,
249  .set_parent = image_set_parent,
250  .get_parent = image_get_parent,
251  .set_bounds = image_set_bounds,
252  .get_bounds = image_get_bounds,
253  .get_minimal_size = image_get_minimal_size,
254  .set_property = image_set_property
255};
256
257grub_gui_component_t
258grub_gui_image_new (void)
259{
260  grub_gui_image_t image;
261  image = grub_zalloc (sizeof (*image));
262  if (! image)
263    return 0;
264  image->component.ops = &image_ops;
265  return (grub_gui_component_t) image;
266}
267
Note: See TracBrowser for help on using the repository browser.