Fix gfxmenu crash.
Reported by: Thorsten Grützmacher. * gfxmenu/gui_circular_progress.c (circprog_destroy): Unregister timeout hook. (circprog_set_property): Register and unregister timeout hook. * gfxmenu/gui_label.c (grub_gui_label): New fields template and value. (label_destroy): Free template. and unregister hook. (label_set_state): New function. (label_set_property): Handle templates and hooks. * gfxmenu/gui_progress_bar.c (progress_bar_destroy): Unregister timeout hook. (progress_bar_set_property): Register and unregister timeout hook. * gfxmenu/view.c (TIMEOUT_COMPONENT_ID): Move from here ... * include/grub/gui.h (GRUB_GFXMENU_TIMEOUT_COMPONENT_ID): ...to here * gfxmenu/view.c (grub_gfxmenu_timeout_notifications): New variable. (update_timeout_visit): Removed. (update_timeouts): New function. (redraw_timeouts): Likewise. (grub_gfxmenu_print_timeout): Use update_timeouts and redraw_timeouts. (grub_gfxmenu_clear_timeout): Likewise. * include/grub/gui.h (grub_gfxmenu_set_state_t): New type. (grub_gfxmenu_timeout_notify): Likewise. (grub_gfxmenu_timeout_notifications): New external variable. (grub_gfxmenu_timeout_register): New function. (grub_gfxmenu_timeout_unregister): Likewise.
This commit is contained in:
parent
c6e5caab1d
commit
cced9145fc
6 changed files with 155 additions and 73 deletions
29
ChangeLog
29
ChangeLog
|
@ -1,3 +1,32 @@
|
|||
2010-05-13 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Fix gfxmenu crash.
|
||||
Reported by: Thorsten Grützmacher.
|
||||
|
||||
* gfxmenu/gui_circular_progress.c (circprog_destroy): Unregister
|
||||
timeout hook.
|
||||
(circprog_set_property): Register and unregister timeout hook.
|
||||
* gfxmenu/gui_label.c (grub_gui_label): New fields template and value.
|
||||
(label_destroy): Free template. and unregister hook.
|
||||
(label_set_state): New function.
|
||||
(label_set_property): Handle templates and hooks.
|
||||
* gfxmenu/gui_progress_bar.c (progress_bar_destroy): Unregister
|
||||
timeout hook.
|
||||
(progress_bar_set_property): Register and unregister timeout hook.
|
||||
* gfxmenu/view.c (TIMEOUT_COMPONENT_ID): Move from here ...
|
||||
* include/grub/gui.h (GRUB_GFXMENU_TIMEOUT_COMPONENT_ID): ...to here
|
||||
* gfxmenu/view.c (grub_gfxmenu_timeout_notifications): New variable.
|
||||
(update_timeout_visit): Removed.
|
||||
(update_timeouts): New function.
|
||||
(redraw_timeouts): Likewise.
|
||||
(grub_gfxmenu_print_timeout): Use update_timeouts and redraw_timeouts.
|
||||
(grub_gfxmenu_clear_timeout): Likewise.
|
||||
* include/grub/gui.h (grub_gfxmenu_set_state_t): New type.
|
||||
(grub_gfxmenu_timeout_notify): Likewise.
|
||||
(grub_gfxmenu_timeout_notifications): New external variable.
|
||||
(grub_gfxmenu_timeout_register): New function.
|
||||
(grub_gfxmenu_timeout_unregister): Likewise.
|
||||
|
||||
2010-05-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Transform (broken) vga terminal into (working) vga video driver.
|
||||
|
|
|
@ -54,6 +54,7 @@ static void
|
|||
circprog_destroy (void *vself)
|
||||
{
|
||||
circular_progress_t self = vself;
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self);
|
||||
}
|
||||
|
||||
|
@ -211,6 +212,17 @@ circprog_get_bounds (void *vself, grub_video_rect_t *bounds)
|
|||
*bounds = self->bounds;
|
||||
}
|
||||
|
||||
static void
|
||||
circprog_set_state (void *vself, int visible, int start,
|
||||
int current, int end)
|
||||
{
|
||||
circular_progress_t self = vself;
|
||||
self->visible = visible;
|
||||
self->start = start;
|
||||
self->value = current;
|
||||
self->end = end;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
circprog_set_property (void *vself, const char *name, const char *value)
|
||||
{
|
||||
|
@ -247,26 +259,20 @@ circprog_set_property (void *vself, const char *name, const char *value)
|
|||
}
|
||||
else if (grub_strcmp (name, "id") == 0)
|
||||
{
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self->id);
|
||||
if (value)
|
||||
self->id = grub_strdup (value);
|
||||
else
|
||||
self->id = 0;
|
||||
if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
|
||||
== 0)
|
||||
grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
|
||||
circprog_set_state);
|
||||
}
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
static void
|
||||
circprog_set_state (void *vself, int visible, int start,
|
||||
int current, int end)
|
||||
{
|
||||
circular_progress_t self = vself;
|
||||
self->visible = visible;
|
||||
self->start = start;
|
||||
self->value = current;
|
||||
self->end = end;
|
||||
}
|
||||
|
||||
static struct grub_gui_component_ops circprog_ops =
|
||||
{
|
||||
.destroy = circprog_destroy,
|
||||
|
|
|
@ -46,8 +46,10 @@ struct grub_gui_label
|
|||
char *id;
|
||||
int visible;
|
||||
char *text;
|
||||
char *template;
|
||||
grub_font_t font;
|
||||
grub_gui_color_t color;
|
||||
int value;
|
||||
enum align_mode align;
|
||||
};
|
||||
|
||||
|
@ -57,7 +59,9 @@ static void
|
|||
label_destroy (void *vself)
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self->text);
|
||||
grub_free (self->template);
|
||||
grub_free (self);
|
||||
}
|
||||
|
||||
|
@ -146,6 +150,17 @@ label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
|
|||
+ grub_font_get_descent (self->font));
|
||||
}
|
||||
|
||||
static void
|
||||
label_set_state (void *vself, int visible, int start __attribute__ ((unused)),
|
||||
int current, int end __attribute__ ((unused)))
|
||||
{
|
||||
grub_gui_label_t self = vself;
|
||||
self->value = -current;
|
||||
self->visible = visible;
|
||||
grub_free (self->text);
|
||||
self->text = grub_xasprintf (self->template ? : "%d", self->value);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
label_set_property (void *vself, const char *name, const char *value)
|
||||
{
|
||||
|
@ -153,9 +168,17 @@ label_set_property (void *vself, const char *name, const char *value)
|
|||
if (grub_strcmp (name, "text") == 0)
|
||||
{
|
||||
grub_free (self->text);
|
||||
grub_free (self->template);
|
||||
if (! value)
|
||||
value = "";
|
||||
self->text = grub_strdup (value);
|
||||
{
|
||||
self->template = NULL;
|
||||
self->text = grub_strdup ("");
|
||||
}
|
||||
else
|
||||
{
|
||||
self->template = grub_strdup (value);
|
||||
self->text = grub_xasprintf (value, self->value);
|
||||
}
|
||||
}
|
||||
else if (grub_strcmp (name, "font") == 0)
|
||||
{
|
||||
|
@ -183,11 +206,16 @@ label_set_property (void *vself, const char *name, const char *value)
|
|||
}
|
||||
else if (grub_strcmp (name, "id") == 0)
|
||||
{
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self->id);
|
||||
if (value)
|
||||
self->id = grub_strdup (value);
|
||||
else
|
||||
self->id = 0;
|
||||
if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
|
||||
== 0)
|
||||
grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
|
||||
label_set_state);
|
||||
}
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ static void
|
|||
progress_bar_destroy (void *vself)
|
||||
{
|
||||
grub_gui_progress_bar_t self = vself;
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self);
|
||||
}
|
||||
|
||||
|
@ -333,11 +334,16 @@ progress_bar_set_property (void *vself, const char *name, const char *value)
|
|||
}
|
||||
else if (grub_strcmp (name, "id") == 0)
|
||||
{
|
||||
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||
grub_free (self->id);
|
||||
if (value)
|
||||
self->id = grub_strdup (value);
|
||||
else
|
||||
self->id = 0;
|
||||
/* if (self->id && grub_strcmp (self->id, GRUB_GFXMENU_TIMEOUT_COMPONENT_ID)
|
||||
== 0)*/
|
||||
grub_gfxmenu_timeout_register ((grub_gui_component_t) self,
|
||||
progress_bar_set_state);
|
||||
}
|
||||
return grub_errno;
|
||||
}
|
||||
|
@ -368,6 +374,7 @@ grub_gui_progress_bar_new (void)
|
|||
self = grub_zalloc (sizeof (*self));
|
||||
if (! self)
|
||||
return 0;
|
||||
|
||||
self->progress.ops = &progress_bar_pb_ops;
|
||||
self->progress.component.ops = &progress_bar_ops;
|
||||
self->visible = 1;
|
||||
|
|
|
@ -37,10 +37,6 @@
|
|||
#include <grub/gui_string_util.h>
|
||||
#include <grub/icon_manager.h>
|
||||
|
||||
/* The component ID identifying GUI components to be updated as the timeout
|
||||
status changes. */
|
||||
#define TIMEOUT_COMPONENT_ID "__timeout__"
|
||||
|
||||
static void
|
||||
init_terminal (grub_gfxmenu_view_t view);
|
||||
static grub_video_rect_t term_rect;
|
||||
|
@ -166,16 +162,28 @@ struct progress_value_data
|
|||
int value;
|
||||
};
|
||||
|
||||
static void
|
||||
update_timeout_visit (grub_gui_component_t component,
|
||||
void *userdata)
|
||||
{
|
||||
struct progress_value_data *pv;
|
||||
pv = (struct progress_value_data *) userdata;
|
||||
struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications;
|
||||
|
||||
((struct grub_gui_progress *) component)->ops
|
||||
->set_state ((struct grub_gui_progress *) component,
|
||||
pv->visible, pv->start, pv->value, pv->end);
|
||||
static void
|
||||
update_timeouts (int visible, int start, int value, int end)
|
||||
{
|
||||
struct grub_gfxmenu_timeout_notify *cur;
|
||||
|
||||
for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next)
|
||||
cur->set_state (cur->self, visible, start, value, end);
|
||||
}
|
||||
|
||||
static void
|
||||
redraw_timeouts (struct grub_gfxmenu_view *view)
|
||||
{
|
||||
struct grub_gfxmenu_timeout_notify *cur;
|
||||
|
||||
for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next)
|
||||
{
|
||||
grub_video_rect_t bounds;
|
||||
cur->self->ops->get_bounds (cur->self, &bounds);
|
||||
grub_gfxmenu_view_redraw (view, &bounds);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -183,67 +191,26 @@ grub_gfxmenu_print_timeout (int timeout, void *data)
|
|||
{
|
||||
struct grub_gfxmenu_view *view = data;
|
||||
|
||||
struct progress_value_data pv;
|
||||
|
||||
auto void redraw_timeout_visit (grub_gui_component_t component,
|
||||
void *userdata __attribute__ ((unused)));
|
||||
|
||||
auto void redraw_timeout_visit (grub_gui_component_t component,
|
||||
void *userdata __attribute__ ((unused)))
|
||||
{
|
||||
grub_video_rect_t bounds;
|
||||
component->ops->get_bounds (component, &bounds);
|
||||
grub_gfxmenu_view_redraw (view, &bounds);
|
||||
}
|
||||
|
||||
if (view->first_timeout == -1)
|
||||
view->first_timeout = timeout;
|
||||
|
||||
pv.visible = 1;
|
||||
pv.start = -(view->first_timeout + 1);
|
||||
pv.end = 0;
|
||||
pv.value = -timeout;
|
||||
|
||||
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
|
||||
TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
|
||||
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
|
||||
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
|
||||
update_timeouts (1, -(view->first_timeout + 1), -timeout, 0);
|
||||
redraw_timeouts (view);
|
||||
grub_video_swap_buffers ();
|
||||
if (view->double_repaint)
|
||||
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
|
||||
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
|
||||
redraw_timeouts (view);
|
||||
}
|
||||
|
||||
void
|
||||
grub_gfxmenu_clear_timeout (void *data)
|
||||
{
|
||||
struct progress_value_data pv;
|
||||
struct grub_gfxmenu_view *view = data;
|
||||
|
||||
auto void redraw_timeout_visit (grub_gui_component_t component,
|
||||
void *userdata __attribute__ ((unused)));
|
||||
|
||||
auto void redraw_timeout_visit (grub_gui_component_t component,
|
||||
void *userdata __attribute__ ((unused)))
|
||||
{
|
||||
grub_video_rect_t bounds;
|
||||
component->ops->get_bounds (component, &bounds);
|
||||
grub_gfxmenu_view_redraw (view, &bounds);
|
||||
}
|
||||
|
||||
pv.visible = 0;
|
||||
pv.start = 1;
|
||||
pv.end = 0;
|
||||
pv.value = 0;
|
||||
|
||||
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
|
||||
TIMEOUT_COMPONENT_ID, update_timeout_visit, &pv);
|
||||
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
|
||||
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
|
||||
update_timeouts (0, 1, 0, 0);
|
||||
redraw_timeouts (view);
|
||||
grub_video_swap_buffers ();
|
||||
if (view->double_repaint)
|
||||
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
|
||||
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
|
||||
redraw_timeouts (view);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -22,10 +22,15 @@
|
|||
#include <grub/video.h>
|
||||
#include <grub/bitmap.h>
|
||||
#include <grub/gfxmenu_view.h>
|
||||
#include <grub/mm.h>
|
||||
|
||||
#ifndef GRUB_GUI_H
|
||||
#define GRUB_GUI_H 1
|
||||
|
||||
/* The component ID identifying GUI components to be updated as the timeout
|
||||
status changes. */
|
||||
#define GRUB_GFXMENU_TIMEOUT_COMPONENT_ID "__timeout__"
|
||||
|
||||
/* A representation of a color. Unlike grub_video_color_t, this
|
||||
representation is independent of any video mode specifics. */
|
||||
typedef struct grub_gui_color
|
||||
|
@ -79,6 +84,46 @@ struct grub_gui_progress_ops
|
|||
void (*set_state) (void *self, int visible, int start, int current, int end);
|
||||
};
|
||||
|
||||
typedef void (*grub_gfxmenu_set_state_t) (void *self, int visible, int start,
|
||||
int current, int end);
|
||||
|
||||
struct grub_gfxmenu_timeout_notify
|
||||
{
|
||||
struct grub_gfxmenu_timeout_notify *next;
|
||||
grub_gfxmenu_set_state_t set_state;
|
||||
grub_gui_component_t self;
|
||||
};
|
||||
|
||||
extern struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications;
|
||||
|
||||
static inline grub_err_t
|
||||
grub_gfxmenu_timeout_register (grub_gui_component_t self,
|
||||
grub_gfxmenu_set_state_t set_state)
|
||||
{
|
||||
struct grub_gfxmenu_timeout_notify *ne = grub_malloc (sizeof (*ne));
|
||||
if (!ne)
|
||||
return grub_errno;
|
||||
ne->set_state = set_state;
|
||||
ne->self = self;
|
||||
ne->next = grub_gfxmenu_timeout_notifications;
|
||||
grub_gfxmenu_timeout_notifications = ne;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static inline void
|
||||
grub_gfxmenu_timeout_unregister (grub_gui_component_t self)
|
||||
{
|
||||
struct grub_gfxmenu_timeout_notify **p, *q;
|
||||
|
||||
for (p = &grub_gfxmenu_timeout_notifications, q = *p;
|
||||
q; p = &(q->next), q = q->next)
|
||||
if (q->self == self)
|
||||
{
|
||||
*p = q->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
typedef signed grub_fixed_signed_t;
|
||||
#define GRUB_FIXED_1 0x10000
|
||||
|
||||
|
|
Loading…
Reference in a new issue