Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-12-18 22:41:36 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-12-18 22:41:36 +0300
commit93cc4629e35e85a05c556cabd5b4d2af6a6cf072 (patch)
tree093e7e1274dbd94590f8548426def75bd7909135
parentaf746acaad8fcfb289e6e56e9199c5b492429934 (diff)
2.5: fix for crashes due to access to free'd memory in joining areas,
ripping areas and duplicating windows.
-rw-r--r--source/blender/editors/interface/interface_handlers.c13
-rw-r--r--source/blender/editors/screen/screen_ops.c4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c24
3 files changed, 29 insertions, 12 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index f22431ba73d..a0227af6540 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -3649,16 +3649,25 @@ static int ui_handler_region_menu(bContext *C, wmEvent *event, void *userdata)
static int ui_handler_popup(bContext *C, wmEvent *event, void *userdata)
{
uiMenuBlockHandle *menu= userdata;
+ void (*popup_func)(struct bContext *C, void *arg, int event)= NULL;
+ void *popup_arg= NULL;
+ int retval= 0;
ui_handle_menus_recursive(C, event, menu);
/* free if done, does not free handle itself */
if(menu->menuretval) {
+ if(menu->menuretval == UI_RETURN_OK) {
+ popup_func= menu->popup_func;
+ popup_arg= menu->popup_arg;
+ retval= menu->retvalue;
+ }
+
ui_menu_block_free(C, menu);
WM_event_remove_ui_handler(&CTX_wm_window(C)->handlers, ui_handler_popup, ui_handler_remove_popup, menu);
- if(menu->menuretval == UI_RETURN_OK && menu->popup_func)
- menu->popup_func(C, menu->popup_arg, menu->retvalue);
+ if(popup_func)
+ popup_func(C, popup_arg, retval);
}
else {
/* re-enable tooltips */
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index 4514d54e317..2342d5c2e8b 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -264,7 +264,7 @@ static int screen_area_rip_op(bContext *C, wmOperator *op)
/* allocs new screen and adds to newly created window, using window size */
newsc= screen_add(newwin, sc->id.name+2);
- win->screen= newsc;
+ newwin->screen= newsc;
/* copy area to new screen */
area_copy_data((ScrArea *)newsc->areabase.first, sa, 0);
@@ -767,6 +767,7 @@ static int area_split_cancel(bContext *C, wmOperator *op)
if (screen_area_join(C, CTX_wm_screen(C), sd->sarea, sd->narea)) {
if (CTX_wm_area(C) == sd->narea) {
CTX_wm_area_set(C, NULL);
+ CTX_wm_region_set(C, NULL);
}
sd->narea = NULL;
}
@@ -1018,6 +1019,7 @@ static int area_join_apply(bContext *C, wmOperator *op)
}
if (CTX_wm_area(C) == jd->sa2) {
CTX_wm_area_set(C, NULL);
+ CTX_wm_region_set(C, NULL);
}
return 1;
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index e5d5f7ebc9c..c015da29ea1 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -441,6 +441,12 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi)
return 1;
}
+static int wm_event_always_pass(wmEvent *event)
+{
+ /* some events we always pass on, to ensure proper communication */
+ return (event->type == TIMER);
+}
+
/* Warning: this function removes a modal handler, when finished */
static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event, IDProperty *properties)
{
@@ -462,8 +468,15 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
retval= ot->modal(C, op, event);
/* putting back screen context */
- CTX_wm_area_set(C, area);
- CTX_wm_region_set(C, region);
+ if((retval & OPERATOR_PASS_THROUGH) || wm_event_always_pass(event)) {
+ CTX_wm_area_set(C, area);
+ CTX_wm_region_set(C, region);
+ }
+ else {
+ /* this special cases is for areas and regions that get removed */
+ CTX_wm_area_set(C, NULL);
+ CTX_wm_region_set(C, NULL);
+ }
if((retval & OPERATOR_FINISHED) && (ot->flag & OPTYPE_REGISTER)) {
wm_operator_register(CTX_wm_manager(C), op);
@@ -474,7 +487,6 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
handler->op= NULL;
}
-
/* remove modal handler, operator itself should have been cancelled and freed */
if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
BLI_remlink(handlers, handler);
@@ -524,12 +536,6 @@ static int wm_handler_ui_call(bContext *C, wmEventHandler *handler, wmEvent *eve
return WM_HANDLER_CONTINUE;
}
-static int wm_event_always_pass(wmEvent *event)
-{
- /* some events we always pass on, to ensure proper communication */
- return (event->type == TIMER);
-}
-
static int handler_boundbox_test(wmEventHandler *handler, wmEvent *event)
{
if(handler->bbwin) {