mirror of
git://projects.qi-hardware.com/fped.git
synced 2024-11-22 12:49:42 +02:00
When moving a vector, the list order could get confused, resulting in a
segfault, failure to update the screen content, and assigning of invalid references. - gui_tools.c: removed duplicate (harmless) line - inst.c: when moving a vector to a new base, we may have to reorder the list so that the assertion vectors always follow their bases is still maintained. git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5713 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
parent
b6e5c6d20a
commit
2dffbfeaa9
@ -917,7 +917,6 @@ void tool_drag(struct coord to)
|
|||||||
|
|
||||||
void tool_cancel_drag(void)
|
void tool_cancel_drag(void)
|
||||||
{
|
{
|
||||||
if (drag.anchors_n && drag.inst->ops->end_drag_move)
|
|
||||||
if (drag.anchors_n && drag.inst->ops->end_drag_move)
|
if (drag.anchors_n && drag.inst->ops->end_drag_move)
|
||||||
drag.inst->ops->end_drag_move();
|
drag.inst->ops->end_drag_move();
|
||||||
drag.new = NULL;
|
drag.new = NULL;
|
||||||
|
53
inst.c
53
inst.c
@ -612,6 +612,58 @@ static int vec_op_anchors(struct inst *inst, struct vec ***anchors)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When instantiating and when dumping, we assume that bases appear in the
|
||||||
|
* frame->vecs list before vectors using them. A move may change this order.
|
||||||
|
* We therefore have to sort the list after the move.
|
||||||
|
*
|
||||||
|
* Since the list is already ordered, cleaning it up is just O(n).
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static void do_move_to_vec(struct inst *inst, struct inst *to, int i)
|
||||||
|
{
|
||||||
|
struct vec *to_vec = inst_get_vec(to);
|
||||||
|
struct vec *vec = inst->vec;
|
||||||
|
struct frame *frame = vec->frame;
|
||||||
|
struct vec *v, **anchor, **walk;
|
||||||
|
|
||||||
|
assert(!i);
|
||||||
|
vec->base = to_vec;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark the vector that's being rebased and all vectors that
|
||||||
|
* (recursively) depend on it.
|
||||||
|
*
|
||||||
|
* We're only interested in the range between the vector being moved
|
||||||
|
* and the new base. If the vector follows the base, the list is
|
||||||
|
* already in the correct order and nothing needs moving.
|
||||||
|
*/
|
||||||
|
for (v = vec; v && v != to_vec; v = v->next)
|
||||||
|
v->mark = v->base ? v->base->mark : 0;
|
||||||
|
if (!v)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All the marked vectors appearing on the list before the new base
|
||||||
|
* are moved after the new base, preserving their order.
|
||||||
|
*/
|
||||||
|
anchor = &to_vec->next;
|
||||||
|
walk = &frame->vecs;
|
||||||
|
while (*walk != to_vec) {
|
||||||
|
v = *walk;
|
||||||
|
if (!v->mark)
|
||||||
|
walk = &v->next;
|
||||||
|
else {
|
||||||
|
*walk = v->next;
|
||||||
|
v->next = *anchor;
|
||||||
|
*anchor = v;
|
||||||
|
anchor = &v->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct inst_ops vec_ops = {
|
static struct inst_ops vec_ops = {
|
||||||
.draw = gui_draw_vec,
|
.draw = gui_draw_vec,
|
||||||
.hover = gui_hover_vec,
|
.hover = gui_hover_vec,
|
||||||
@ -620,6 +672,7 @@ static struct inst_ops vec_ops = {
|
|||||||
.find_point = find_point_vec,
|
.find_point = find_point_vec,
|
||||||
.anchors = vec_op_anchors,
|
.anchors = vec_op_anchors,
|
||||||
.draw_move = draw_move_vec,
|
.draw_move = draw_move_vec,
|
||||||
|
.do_move_to = do_move_to_vec,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
3
obj.h
3
obj.h
@ -105,6 +105,9 @@ struct vec {
|
|||||||
/* index into table of samples */
|
/* index into table of samples */
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
/* for re-ordering after a move */
|
||||||
|
int mark;
|
||||||
|
|
||||||
/* for the GUI */
|
/* for the GUI */
|
||||||
GtkWidget *list_widget; /* NULL if items aren't shown */
|
GtkWidget *list_widget; /* NULL if items aren't shown */
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user