diff options
Diffstat (limited to 'source/blender/blenkernel/intern/screen.c')
-rw-r--r-- | source/blender/blenkernel/intern/screen.c | 189 |
1 files changed, 181 insertions, 8 deletions
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 7a45493e1f4..74e30984436 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -1,6 +1,4 @@ - -/* screen.c - * +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -33,22 +31,197 @@ #include <stdio.h> #include <math.h> +#include "MEM_guardedalloc.h" + #include "DNA_screen_types.h" -#include "BKE_bad_level_calls.h" +#include "DNA_space_types.h" + #include "BLI_blenlib.h" #include "BKE_screen.h" -#ifdef HAVE_CONFIG_H -#include <config.h> +#ifndef DISABLE_PYTHON +#include "BPY_extern.h" +#endif + +/* ************ Spacetype/regiontype handling ************** */ + +/* keep global; this has to be accessible outside of windowmanager */ +static ListBase spacetypes= {NULL, NULL}; + +/* not SpaceType itself */ +static void spacetype_free(SpaceType *st) +{ + BLI_freelistN(&st->regiontypes); +} + +void BKE_spacetypes_free(void) +{ + SpaceType *st; + + for(st= spacetypes.first; st; st= st->next) { + spacetype_free(st); + } + + BLI_freelistN(&spacetypes); +} + +SpaceType *BKE_spacetype_from_id(int spaceid) +{ + SpaceType *st; + + for(st= spacetypes.first; st; st= st->next) { + if(st->spaceid==spaceid) + return st; + } + return NULL; +} + +const ListBase *BKE_spacetypes_list() +{ + return &spacetypes; +} + +void BKE_spacetype_register(SpaceType *st) +{ + SpaceType *stype; + + /* sanity check */ + stype= BKE_spacetype_from_id(st->spaceid); + if(stype) { + printf("error: redefinition of spacetype %s\n", stype->name); + spacetype_free(stype); + MEM_freeN(stype); + } + + BLI_addtail(&spacetypes, st); +} + +/* ***************** Space handling ********************** */ + +void BKE_spacedata_freelist(ListBase *lb) +{ + SpaceLink *sl; + ARegion *ar; + + for (sl= lb->first; sl; sl= sl->next) { + SpaceType *st= BKE_spacetype_from_id(sl->spacetype); + + /* free regions for pushed spaces */ + for(ar=sl->regionbase.first; ar; ar=ar->next) { + BKE_area_region_free(ar); + } + BLI_freelistN(&sl->regionbase); + + if(st && st->free) + st->free(sl); + } + + BLI_freelistN(lb); +} + +ARegion *BKE_area_region_copy(ARegion *ar) +{ + ARegion *newar= MEM_dupallocN(ar); + + newar->handlers.first= newar->handlers.last= NULL; + newar->uiblocks.first= newar->uiblocks.last= NULL; + newar->swinid= 0; + + /* XXX regiondata callback */ + if(ar->regiondata) + newar->regiondata= MEM_dupallocN(ar->regiondata); + + return newar; +} + + +/* from lb2 to lb1, lb1 is supposed to be free'd */ +static void region_copylist(ListBase *lb1, ListBase *lb2) +{ + ARegion *ar; + + /* to be sure */ + lb1->first= lb1->last= NULL; + + for(ar= lb2->first; ar; ar= ar->next) { + ARegion *arnew= BKE_area_region_copy(ar); + BLI_addtail(lb1, arnew); + } +} + + +/* lb1 should be empty */ +void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2) +{ + SpaceLink *sl; + + lb1->first= lb2->last= NULL; /* to be sure */ + + for (sl= lb2->first; sl; sl= sl->next) { + SpaceType *st= BKE_spacetype_from_id(sl->spacetype); + + if(st && st->duplicate) { + SpaceLink *slnew= st->duplicate(sl); + + BLI_addtail(lb1, slnew); + + region_copylist(&slnew->regionbase, &sl->regionbase); + } + } +} + +/* not region itself */ +void BKE_area_region_free(ARegion *ar) +{ + if(ar && ar->type && ar->type->free) + ar->type->free(ar); +} + +/* not area itself */ +void BKE_screen_area_free(ScrArea *sa) +{ + ARegion *ar, *arn; + + for(ar=sa->regionbase.first; ar; ar=arn) { + arn= ar->next; + BKE_area_region_free(ar); + } + + BKE_spacedata_freelist(&sa->spacedata); + + BLI_freelistN(&sa->regionbase); + BLI_freelistN(&sa->actionzones); + + BLI_freelistN(&sa->panels); + // uiFreeBlocks(&sa->uiblocks); + // uiFreePanels(&sa->panels); + +#ifndef DISABLE_PYTHON + BPY_free_scriptlink(&sa->scriptlink); #endif +} /* don't free screen itself */ void free_screen(bScreen *sc) { - unlink_screen(sc); - + ScrArea *sa, *san; + ARegion *ar, *arn; + + for(ar=sc->regionbase.first; ar; ar=arn) { + arn= ar->next; + BKE_area_region_free(ar); + } + BLI_freelistN(&sc->regionbase); + + for(sa= sc->areabase.first; sa; sa= san) { + san= sa->next; + BKE_screen_area_free(sa); + } + BLI_freelistN(&sc->vertbase); BLI_freelistN(&sc->edgebase); BLI_freelistN(&sc->areabase); } + + |