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>
|
2010-05-09 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
Transform (broken) vga terminal into (working) vga video driver.
|
Transform (broken) vga terminal into (working) vga video driver.
|
||||||
|
|
|
@ -54,6 +54,7 @@ static void
|
||||||
circprog_destroy (void *vself)
|
circprog_destroy (void *vself)
|
||||||
{
|
{
|
||||||
circular_progress_t self = vself;
|
circular_progress_t self = vself;
|
||||||
|
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||||
grub_free (self);
|
grub_free (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,6 +212,17 @@ circprog_get_bounds (void *vself, grub_video_rect_t *bounds)
|
||||||
*bounds = self->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
|
static grub_err_t
|
||||||
circprog_set_property (void *vself, const char *name, const char *value)
|
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)
|
else if (grub_strcmp (name, "id") == 0)
|
||||||
{
|
{
|
||||||
|
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||||
grub_free (self->id);
|
grub_free (self->id);
|
||||||
if (value)
|
if (value)
|
||||||
self->id = grub_strdup (value);
|
self->id = grub_strdup (value);
|
||||||
else
|
else
|
||||||
self->id = 0;
|
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;
|
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 =
|
static struct grub_gui_component_ops circprog_ops =
|
||||||
{
|
{
|
||||||
.destroy = circprog_destroy,
|
.destroy = circprog_destroy,
|
||||||
|
|
|
@ -46,8 +46,10 @@ struct grub_gui_label
|
||||||
char *id;
|
char *id;
|
||||||
int visible;
|
int visible;
|
||||||
char *text;
|
char *text;
|
||||||
|
char *template;
|
||||||
grub_font_t font;
|
grub_font_t font;
|
||||||
grub_gui_color_t color;
|
grub_gui_color_t color;
|
||||||
|
int value;
|
||||||
enum align_mode align;
|
enum align_mode align;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,7 +59,9 @@ static void
|
||||||
label_destroy (void *vself)
|
label_destroy (void *vself)
|
||||||
{
|
{
|
||||||
grub_gui_label_t self = vself;
|
grub_gui_label_t self = vself;
|
||||||
|
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||||
grub_free (self->text);
|
grub_free (self->text);
|
||||||
|
grub_free (self->template);
|
||||||
grub_free (self);
|
grub_free (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,6 +150,17 @@ label_get_minimal_size (void *vself, unsigned *width, unsigned *height)
|
||||||
+ grub_font_get_descent (self->font));
|
+ 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
|
static grub_err_t
|
||||||
label_set_property (void *vself, const char *name, const char *value)
|
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)
|
if (grub_strcmp (name, "text") == 0)
|
||||||
{
|
{
|
||||||
grub_free (self->text);
|
grub_free (self->text);
|
||||||
|
grub_free (self->template);
|
||||||
if (! value)
|
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)
|
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)
|
else if (grub_strcmp (name, "id") == 0)
|
||||||
{
|
{
|
||||||
|
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||||
grub_free (self->id);
|
grub_free (self->id);
|
||||||
if (value)
|
if (value)
|
||||||
self->id = grub_strdup (value);
|
self->id = grub_strdup (value);
|
||||||
else
|
else
|
||||||
self->id = 0;
|
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;
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ static void
|
||||||
progress_bar_destroy (void *vself)
|
progress_bar_destroy (void *vself)
|
||||||
{
|
{
|
||||||
grub_gui_progress_bar_t self = vself;
|
grub_gui_progress_bar_t self = vself;
|
||||||
|
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||||
grub_free (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)
|
else if (grub_strcmp (name, "id") == 0)
|
||||||
{
|
{
|
||||||
|
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
|
||||||
grub_free (self->id);
|
grub_free (self->id);
|
||||||
if (value)
|
if (value)
|
||||||
self->id = grub_strdup (value);
|
self->id = grub_strdup (value);
|
||||||
else
|
else
|
||||||
self->id = 0;
|
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;
|
return grub_errno;
|
||||||
}
|
}
|
||||||
|
@ -368,6 +374,7 @@ grub_gui_progress_bar_new (void)
|
||||||
self = grub_zalloc (sizeof (*self));
|
self = grub_zalloc (sizeof (*self));
|
||||||
if (! self)
|
if (! self)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
self->progress.ops = &progress_bar_pb_ops;
|
self->progress.ops = &progress_bar_pb_ops;
|
||||||
self->progress.component.ops = &progress_bar_ops;
|
self->progress.component.ops = &progress_bar_ops;
|
||||||
self->visible = 1;
|
self->visible = 1;
|
||||||
|
|
|
@ -37,10 +37,6 @@
|
||||||
#include <grub/gui_string_util.h>
|
#include <grub/gui_string_util.h>
|
||||||
#include <grub/icon_manager.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
|
static void
|
||||||
init_terminal (grub_gfxmenu_view_t view);
|
init_terminal (grub_gfxmenu_view_t view);
|
||||||
static grub_video_rect_t term_rect;
|
static grub_video_rect_t term_rect;
|
||||||
|
@ -166,16 +162,28 @@ struct progress_value_data
|
||||||
int value;
|
int value;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications;
|
||||||
update_timeout_visit (grub_gui_component_t component,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
struct progress_value_data *pv;
|
|
||||||
pv = (struct progress_value_data *) userdata;
|
|
||||||
|
|
||||||
((struct grub_gui_progress *) component)->ops
|
static void
|
||||||
->set_state ((struct grub_gui_progress *) component,
|
update_timeouts (int visible, int start, int value, int end)
|
||||||
pv->visible, pv->start, pv->value, pv->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
|
void
|
||||||
|
@ -183,67 +191,26 @@ grub_gfxmenu_print_timeout (int timeout, void *data)
|
||||||
{
|
{
|
||||||
struct grub_gfxmenu_view *view = 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)
|
if (view->first_timeout == -1)
|
||||||
view->first_timeout = timeout;
|
view->first_timeout = timeout;
|
||||||
|
|
||||||
pv.visible = 1;
|
update_timeouts (1, -(view->first_timeout + 1), -timeout, 0);
|
||||||
pv.start = -(view->first_timeout + 1);
|
redraw_timeouts (view);
|
||||||
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);
|
|
||||||
grub_video_swap_buffers ();
|
grub_video_swap_buffers ();
|
||||||
if (view->double_repaint)
|
if (view->double_repaint)
|
||||||
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
|
redraw_timeouts (view);
|
||||||
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_gfxmenu_clear_timeout (void *data)
|
grub_gfxmenu_clear_timeout (void *data)
|
||||||
{
|
{
|
||||||
struct progress_value_data pv;
|
|
||||||
struct grub_gfxmenu_view *view = data;
|
struct grub_gfxmenu_view *view = data;
|
||||||
|
|
||||||
auto void redraw_timeout_visit (grub_gui_component_t component,
|
update_timeouts (0, 1, 0, 0);
|
||||||
void *userdata __attribute__ ((unused)));
|
redraw_timeouts (view);
|
||||||
|
|
||||||
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);
|
|
||||||
grub_video_swap_buffers ();
|
grub_video_swap_buffers ();
|
||||||
if (view->double_repaint)
|
if (view->double_repaint)
|
||||||
grub_gui_find_by_id ((grub_gui_component_t) view->canvas,
|
redraw_timeouts (view);
|
||||||
TIMEOUT_COMPONENT_ID, redraw_timeout_visit, &pv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -22,10 +22,15 @@
|
||||||
#include <grub/video.h>
|
#include <grub/video.h>
|
||||||
#include <grub/bitmap.h>
|
#include <grub/bitmap.h>
|
||||||
#include <grub/gfxmenu_view.h>
|
#include <grub/gfxmenu_view.h>
|
||||||
|
#include <grub/mm.h>
|
||||||
|
|
||||||
#ifndef GRUB_GUI_H
|
#ifndef GRUB_GUI_H
|
||||||
#define GRUB_GUI_H 1
|
#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
|
/* A representation of a color. Unlike grub_video_color_t, this
|
||||||
representation is independent of any video mode specifics. */
|
representation is independent of any video mode specifics. */
|
||||||
typedef struct grub_gui_color
|
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);
|
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;
|
typedef signed grub_fixed_signed_t;
|
||||||
#define GRUB_FIXED_1 0x10000
|
#define GRUB_FIXED_1 0x10000
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue