2.5 audio cleanup:
[blender.git] / source / blender / editors / screen / screen_edit.c
index 98c5eecfe4bb1eb3b8b2ce7daaccb6f2137274ab..5519b2609a1494dda08edc354fee7278d5fcafa9 100644 (file)
  * ***** END GPL LICENSE BLOCK *****
  */
 
  * ***** END GPL LICENSE BLOCK *****
  */
 
+#include <string.h>
+
 #include "MEM_guardedalloc.h"
 
 #include "MEM_guardedalloc.h"
 
+#include "DNA_vec_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_userdef_types.h"
+
 #include "BLI_blenlib.h"
 #include "BLI_blenlib.h"
-#include "BLI_arithb.h"
 
 
+#include "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
+#include "BKE_node.h"
 #include "BKE_screen.h"
 #include "BKE_screen.h"
+#include "BKE_scene.h"
 #include "BKE_utildefines.h"
 
 #include "BIF_gl.h"
 #include "BKE_utildefines.h"
 
 #include "BIF_gl.h"
 #include "WM_api.h"
 #include "WM_types.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
 
-#include "ED_area.h"
 #include "ED_screen.h"
 #include "ED_screen_types.h"
 
 #include "ED_screen.h"
 #include "ED_screen_types.h"
 
+/* XXX actually should be not here... solve later */
 #include "wm_subwindow.h"
 
 #include "screen_intern.h"     /* own module include */
 
 #include "wm_subwindow.h"
 
 #include "screen_intern.h"     /* own module include */
 
-/* ******************* gesture manager ******************* */
-void ed_gesture_draw_rect(wmWindow *win, wmGesture *gt)
-{
-       wmGestureRect *rect= (wmGestureRect *)gt;
-       sdrawbox(rect->x1, rect->y1, rect->x2, rect->y2);
-}
-
-void ed_gesture_update(wmWindow *win)
-{
-       wmGesture *gt= (wmGesture *)win->gesture.first;
-
-       while(gt) {
-               if(gt->type==GESTURE_RECT)
-                       ed_gesture_draw_rect(win, gt);
-               gt= gt->next;
-       }
-}
 
 /* ******************* screen vert, edge, area managing *********************** */
 
 
 /* ******************* screen vert, edge, area managing *********************** */
 
@@ -103,7 +96,7 @@ static ScrEdge *screen_addedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
 }
 
 
 }
 
 
-static ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
+ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
 {
        ScrEdge *se;
        
 {
        ScrEdge *se;
        
@@ -115,68 +108,7 @@ static ScrEdge *screen_findedge(bScreen *sc, ScrVert *v1, ScrVert *v2)
        return NULL;
 }
 
        return NULL;
 }
 
-static ScrArea *screen_test_edge_area(bScreen* scr, ScrArea *sa, ScrEdge *se)
-{
-       /* test if edge is in area, if not, 
-          then find an area that has it */
-  
-       ScrEdge *se1=0, *se2=0, *se3=0, *se4=0;
-       
-       if(sa) {
-       se1= screen_findedge(scr, sa->v1, sa->v2);
-               se2= screen_findedge(scr, sa->v2, sa->v3);
-       se3= screen_findedge(scr, sa->v3, sa->v4);
-               se4= screen_findedge(scr, sa->v4, sa->v1);
-       }
-       if(se1!=se && se2!=se && se3!=se && se4!=se) {
-               
-               sa= scr->areabase.first;
-               while(sa) {
-                               /* a bit optimise? */
-                               if(se->v1==sa->v1 || se->v1==sa->v2 || se->v1==sa->v3 || se->v1==sa->v4) {
-                               se1= screen_findedge(scr, sa->v1, sa->v2);
-                                       se2= screen_findedge(scr, sa->v2, sa->v3);
-                                       se3= screen_findedge(scr, sa->v3, sa->v4);
-                                       se4= screen_findedge(scr, sa->v4, sa->v1);
-                                       if(se1==se || se2==se || se3==se || se4==se) return sa;
-                               }
-                               sa= sa->next;
-                       }
-       }
-
-       return sa;      /* is null when not find */
-}
-
-static ScrArea *screen_areahascursor(bScreen *scr, int x, int y)
-{
-       ScrArea *sa= NULL;
-       sa= scr->areabase.first;
-       while(sa) {
-               if(BLI_in_rcti(&sa->totrct, x, y)) break;
-               sa= sa->next;
-       }
-
-       return sa;
-}
-
-static AZone *is_in_area_actionzone(ScrArea *sa, int x, int y)
-{
-       AZone *az= NULL;
-       int i= 0;
-       
-       for(az= sa->actionzones.first, i= 0; az; az= az->next, i++) {
-               if(az && az->type == AZONE_TRI) {
-                       if(IsPointInTri2DInts(az->x1, az->y1, az->x2, az->y2, x, y)) break;
-               }
-               if(az->type == AZONE_QUAD) {
-                       if(az->x1 < x && x < az->x2 && az->y1 < y && y < az->y2) break;
-               }
-       }
-       
-       return az;
-}
-
-static void removedouble_scrverts(bScreen *sc)
+void removedouble_scrverts(bScreen *sc)
 {
        ScrVert *v1, *verg;
        ScrEdge *se;
 {
        ScrVert *v1, *verg;
        ScrEdge *se;
@@ -230,7 +162,7 @@ static void removedouble_scrverts(bScreen *sc)
 
 }
 
 
 }
 
-static void removenotused_scrverts(bScreen *sc)
+void removenotused_scrverts(bScreen *sc)
 {
        ScrVert *sv, *svn;
        ScrEdge *se;
 {
        ScrVert *sv, *svn;
        ScrEdge *se;
@@ -256,7 +188,7 @@ static void removenotused_scrverts(bScreen *sc)
        }
 }
 
        }
 }
 
-static void removedouble_scredges(bScreen *sc)
+void removedouble_scredges(bScreen *sc)
 {
        ScrEdge *verg, *se, *sn;
        
 {
        ScrEdge *verg, *se, *sn;
        
@@ -276,7 +208,7 @@ static void removedouble_scredges(bScreen *sc)
        }
 }
 
        }
 }
 
-static void removenotused_scredges(bScreen *sc)
+void removenotused_scredges(bScreen *sc)
 {
        ScrEdge *se, *sen;
        ScrArea *sa;
 {
        ScrEdge *se, *sen;
        ScrArea *sa;
@@ -312,12 +244,12 @@ static void removenotused_scredges(bScreen *sc)
        }
 }
 
        }
 }
 
-static int scredge_is_horizontal(ScrEdge *se)
+int scredge_is_horizontal(ScrEdge *se)
 {
        return (se->v1->vec.y == se->v2->vec.y);
 }
 
 {
        return (se->v1->vec.y == se->v2->vec.y);
 }
 
-static ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
+ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
 {
        ScrEdge *se;
        
 {
        ScrEdge *se;
        
@@ -343,49 +275,9 @@ static ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my)
        return NULL;
 }
 
        return NULL;
 }
 
-/* danger: is used while areamove! */
-static void select_connected_scredge(bScreen *sc, ScrEdge *edge)
-{
-       ScrEdge *se;
-       ScrVert *sv;
-       int oneselected;
-       char dir;
-       
-       /* select connected, only in the right direction */
-       /* 'dir' is the direction of EDGE */
-       
-       if(edge->v1->vec.x==edge->v2->vec.x) dir= 'v';
-       else dir= 'h';
-       
-       sv= sc->vertbase.first;
-       while(sv) {
-               sv->flag = 0;
-               sv= sv->next;
-       }
-       
-       edge->v1->flag= 1;
-       edge->v2->flag= 1;
-       
-       oneselected= 1;
-       while(oneselected) {
-               se= sc->edgebase.first;
-               oneselected= 0;
-               while(se) {
-                       if(se->v1->flag + se->v2->flag==1) {
-                               if(dir=='h') if(se->v1->vec.y==se->v2->vec.y) {
-                                       se->v1->flag= se->v2->flag= 1;
-                                       oneselected= 1;
-                               }
-                               if(dir=='v') if(se->v1->vec.x==se->v2->vec.x) {
-                                       se->v1->flag= se->v2->flag= 1;
-                                       oneselected= 1;
-                               }
-                       }
-                       se= se->next;
-               }
-       }
-}
 
 
+
+/* adds no space data */
 static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v3, ScrVert *v4, short headertype, short spacetype)
 {
        ScrArea *sa= MEM_callocN(sizeof(ScrArea), "addscrarea");
 static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v3, ScrVert *v4, short headertype, short spacetype)
 {
        ScrArea *sa= MEM_callocN(sizeof(ScrArea), "addscrarea");
@@ -394,34 +286,134 @@ static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v
        sa->v3= v3;
        sa->v4= v4;
        sa->headertype= headertype;
        sa->v3= v3;
        sa->v4= v4;
        sa->headertype= headertype;
-       sa->spacetype= spacetype;
+       sa->spacetype= sa->butspacetype= spacetype;
        
        BLI_addtail(&sc->areabase, sa);
        
        return sa;
 }
 
        
        BLI_addtail(&sc->areabase, sa);
        
        return sa;
 }
 
-static void screen_delarea(bScreen *sc, ScrArea *sa)
+static void screen_delarea(bContext *C, bScreen *sc, ScrArea *sa)
 {
 {
-       /* XXX need context to cancel operators ED_area_exit(C, sa); */
+       
+       ED_area_exit(C, sa);
+       
        BKE_screen_area_free(sa);
        BKE_screen_area_free(sa);
+       
        BLI_remlink(&sc->areabase, sa);
        MEM_freeN(sa);
 }
 
        BLI_remlink(&sc->areabase, sa);
        MEM_freeN(sa);
 }
 
-/* Helper function to join 2 areas, it has a return value, 0=failed 1=success
- *     used by the split, join and rip operators
- */
-int screen_join_areas(bScreen *scr, ScrArea *sa1, ScrArea *sa2);
+/* return 0: no split possible */
+/* else return (integer) screencoordinate split point */
+static short testsplitpoint(wmWindow *win, ScrArea *sa, char dir, float fac)
+{
+       short x, y;
+       
+       // area big enough?
+       if(dir=='v' && (sa->v4->vec.x- sa->v1->vec.x <= 2*AREAMINX)) return 0;
+       if(dir=='h' && (sa->v2->vec.y- sa->v1->vec.y <= 2*AREAMINY)) return 0;
+       
+       // to be sure
+       if(fac<0.0) fac= 0.0;
+       if(fac>1.0) fac= 1.0;
+       
+       if(dir=='h') {
+               y= sa->v1->vec.y+ fac*(sa->v2->vec.y- sa->v1->vec.y);
+               
+               if(y- sa->v1->vec.y < AREAMINY) 
+                       y= sa->v1->vec.y+ AREAMINY;
+               else if(sa->v2->vec.y- y < AREAMINY) 
+                       y= sa->v2->vec.y- AREAMINY;
+               else y-= (y % AREAGRID);
+               
+               return y;
+       }
+       else {
+               x= sa->v1->vec.x+ fac*(sa->v4->vec.x- sa->v1->vec.x);
+               
+               if(x- sa->v1->vec.x < AREAMINX) 
+                       x= sa->v1->vec.x+ AREAMINX;
+               else if(sa->v4->vec.x- x < AREAMINX) 
+                       x= sa->v4->vec.x- AREAMINX;
+               else x-= (x % AREAGRID);
+               
+               return x;
+       }
+}
+
+ScrArea *area_split(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac)
+{
+       ScrArea *newa=NULL;
+       ScrVert *sv1, *sv2;
+       short split;
+       
+       if(sa==NULL) return NULL;
+       
+       split= testsplitpoint(win, sa, dir, fac);
+       if(split==0) return NULL;
+       
+       if(dir=='h') {
+               /* new vertices */
+               sv1= screen_addvert(sc, sa->v1->vec.x, split);
+               sv2= screen_addvert(sc, sa->v4->vec.x, split);
+               
+               /* new edges */
+               screen_addedge(sc, sa->v1, sv1);
+               screen_addedge(sc, sv1, sa->v2);
+               screen_addedge(sc, sa->v3, sv2);
+               screen_addedge(sc, sv2, sa->v4);
+               screen_addedge(sc, sv1, sv2);
+               
+               /* new areas: top */
+               newa= screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->headertype, sa->spacetype);
+               area_copy_data(newa, sa, 0);
+               
+               /* area below */
+               sa->v2= sv1;
+               sa->v3= sv2;
+               
+       }
+       else {
+               /* new vertices */
+               sv1= screen_addvert(sc, split, sa->v1->vec.y);
+               sv2= screen_addvert(sc, split, sa->v2->vec.y);
+               
+               /* new edges */
+               screen_addedge(sc, sa->v1, sv1);
+               screen_addedge(sc, sv1, sa->v4);
+               screen_addedge(sc, sa->v2, sv2);
+               screen_addedge(sc, sv2, sa->v3);
+               screen_addedge(sc, sv1, sv2);
+               
+               /* new areas: left */
+               newa= screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->headertype, sa->spacetype);
+               area_copy_data(newa, sa, 0);
+               
+               /* area right */
+               sa->v1= sv1;
+               sa->v2= sv2;
+       }
+       
+       /* remove double vertices en edges */
+       removedouble_scrverts(sc);
+       removedouble_scredges(sc);
+       removenotused_scredges(sc);
+       
+       return newa;
+}
 
 
-static bScreen *addscreen_area(wmWindow *win, char *name, short headertype, short spacetype)
+/* empty screen, with 1 dummy area without spacedata */
+/* uses window size */
+bScreen *ED_screen_add(wmWindow *win, Scene *scene, char *name)
 {
        bScreen *sc;
        ScrVert *sv1, *sv2, *sv3, *sv4;
        
        sc= alloc_libblock(&G.main->screen, ID_SCR, name);
 {
        bScreen *sc;
        ScrVert *sv1, *sv2, *sv3, *sv4;
        
        sc= alloc_libblock(&G.main->screen, ID_SCR, name);
-       
-       sc->scene= G.scene;
+       sc->scene= scene;
+       sc->do_refresh= 1;
+       sc->winid= win->winid;
        
        sv1= screen_addvert(sc, 0, 0);
        sv2= screen_addvert(sc, 0, win->sizey-1);
        
        sv1= screen_addvert(sc, 0, 0);
        sv2= screen_addvert(sc, 0, win->sizey-1);
@@ -433,16 +425,12 @@ static bScreen *addscreen_area(wmWindow *win, char *name, short headertype, shor
        screen_addedge(sc, sv3, sv4);
        screen_addedge(sc, sv4, sv1);
        
        screen_addedge(sc, sv3, sv4);
        screen_addedge(sc, sv4, sv1);
        
-       screen_addarea(sc, sv1, sv2, sv3, sv4, headertype, spacetype);
+       /* dummy type, no spacedata */
+       screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_EMPTY);
                
        return sc;
 }
 
                
        return sc;
 }
 
-static bScreen *addscreen(wmWindow *win, char *name) 
-{
-       return addscreen_area(win, name, HEADERDOWN, SPACE_INFO);
-}
-
 static void screen_copy(bScreen *to, bScreen *from)
 {
        ScrVert *s1, *s2;
 static void screen_copy(bScreen *to, bScreen *from)
 {
        ScrVert *s1, *s2;
@@ -476,11 +464,8 @@ static void screen_copy(bScreen *to, bScreen *from)
                sa->v4= sa->v4->newv;
                
                sa->spacedata.first= sa->spacedata.last= NULL;
                sa->v4= sa->v4->newv;
                
                sa->spacedata.first= sa->spacedata.last= NULL;
-               sa->uiblocks.first= sa->uiblocks.last= NULL;
-               sa->panels.first= sa->panels.last= NULL;
                sa->regionbase.first= sa->regionbase.last= NULL;
                sa->actionzones.first= sa->actionzones.last= NULL;
                sa->regionbase.first= sa->regionbase.last= NULL;
                sa->actionzones.first= sa->actionzones.last= NULL;
-               sa->scriptlink.totscript= 0;
                
                area_copy_data(sa, saf, 0);
        }
                
                area_copy_data(sa, saf, 0);
        }
@@ -491,81 +476,11 @@ static void screen_copy(bScreen *to, bScreen *from)
 
 }
 
 
 }
 
-bScreen *ED_screen_riparea(struct wmWindow *win, bScreen *sc, struct ScrArea *sa)
-{
-       bScreen *newsc=NULL;
-       ScrArea *newa;
-       ScrArea *tsa;
-
-       if(sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */
-       
-       /* make new screen: */
-       newsc= addscreen_area(win, sc->id.name+2, sa->headertype, sa->spacetype);
-
-       /* new area is first (and only area) added to new win */
-       newa = (ScrArea *)newsc->areabase.first;
-       area_copy_data(newa, sa, 0);
-
-       /*remove the original area if possible*/
-       for(tsa= sc->areabase.first; tsa; tsa= tsa->next) {
-               if (screen_join_areas(sc,tsa,sa)) 
-                       break;
-       }
-
-       removedouble_scredges(sc);
-       removenotused_scredges(sc);
-       removenotused_scrverts(sc);
-
-       return newsc;
-}
-
-bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
-{
-       bScreen *newsc;
-       
-       if(sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */
-       
-       /* make new screen: */
-       newsc= addscreen(win, sc->id.name+2);
-       /* copy all data */
-       screen_copy(newsc, sc);
-       
-       return newsc;
-}
-
-/* with sa as center, sb is located at: 0=W, 1=N, 2=E, 3=S */
-/* used with split operator */
-static ScrEdge *area_findsharededge(bScreen *screen, ScrArea *sa, ScrArea *sb)
-{
-       ScrVert *sav1= sa->v1;
-       ScrVert *sav2= sa->v2;
-       ScrVert *sav3= sa->v3;
-       ScrVert *sav4= sa->v4;
-       ScrVert *sbv1= sb->v1;
-       ScrVert *sbv2= sb->v2;
-       ScrVert *sbv3= sb->v3;
-       ScrVert *sbv4= sb->v4;
-       
-       if(sav1==sbv4 && sav2==sbv3) { /* sa to right of sb = W */
-               return screen_findedge(screen, sav1, sav2);
-       }
-       else if(sav2==sbv1 && sav3==sbv4) { /* sa to bottom of sb = N */
-               return screen_findedge(screen, sav2, sav3);
-       }
-       else if(sav3==sbv2 && sav4==sbv1) { /* sa to left of sb = E */
-               return screen_findedge(screen, sav3, sav4);
-       }
-       else if(sav1==sbv2 && sav4==sbv3) { /* sa on top of sb = S*/
-               return screen_findedge(screen, sav1, sav4);
-       }
-       
-       return NULL;
-}
 
 /* with sa as center, sb is located at: 0=W, 1=N, 2=E, 3=S */
 /* -1 = not valid check */
 
 /* with sa as center, sb is located at: 0=W, 1=N, 2=E, 3=S */
 /* -1 = not valid check */
-/* used with split operator */
-static int area_getorientation(bScreen *screen, ScrArea *sa, ScrArea *sb)
+/* used with join operator */
+int area_getorientation(bScreen *screen, ScrArea *sa, ScrArea *sb)
 {
        ScrVert *sav1, *sav2, *sav3, *sav4;
        ScrVert *sbv1, *sbv2, *sbv3, *sbv4;
 {
        ScrVert *sav1, *sav2, *sav3, *sav4;
        ScrVert *sbv1, *sbv2, *sbv3, *sbv4;
@@ -597,126 +512,21 @@ static int area_getorientation(bScreen *screen, ScrArea *sa, ScrArea *sb)
        return -1;
 }
 
        return -1;
 }
 
-/* return 0: no split possible */
-/* else return (integer) screencoordinate split point */
-static short testsplitpoint(wmWindow *win, ScrArea *sa, char dir, float fac)
+/* Helper function to join 2 areas, it has a return value, 0=failed 1=success
+*      used by the split, join operators
+*/
+int screen_area_join(bContext *C, bScreen* scr, ScrArea *sa1, ScrArea *sa2) 
 {
 {
-       short x, y;
+       int dir;
        
        
-       // area big enough?
-       if(sa->v4->vec.x- sa->v1->vec.x <= 2*AREAMINX) return 0;
-       if(sa->v2->vec.y- sa->v1->vec.y <= 2*AREAMINY) return 0;
-
-       // to be sure
-       if(fac<0.0) fac= 0.0;
-       if(fac>1.0) fac= 1.0;
+       dir = area_getorientation(scr, sa1, sa2);
+       /*printf("dir is : %i \n", dir);*/
        
        
-       if(dir=='h') {
-               y= sa->v1->vec.y+ fac*(sa->v2->vec.y- sa->v1->vec.y);
-               
-               if(sa->v2->vec.y==win->sizey-1 && sa->v2->vec.y- y < HEADERY) 
-                       y= sa->v2->vec.y- HEADERY;
-
-               else if(sa->v1->vec.y==0 && y- sa->v1->vec.y < HEADERY)
-                       y= sa->v1->vec.y+ HEADERY;
-
-               else if(y- sa->v1->vec.y < AREAMINY) y= sa->v1->vec.y+ AREAMINY;
-               else if(sa->v2->vec.y- y < AREAMINY) y= sa->v2->vec.y- AREAMINY;
-               else y-= (y % AREAGRID);
-
-               return y;
-       }
-       else {
-               x= sa->v1->vec.x+ fac*(sa->v4->vec.x- sa->v1->vec.x);
-               if(x- sa->v1->vec.x < AREAMINX) x= sa->v1->vec.x+ AREAMINX;
-               else if(sa->v4->vec.x- x < AREAMINX) x= sa->v4->vec.x- AREAMINX;
-               else x-= (x % AREAGRID);
-
-               return x;
-       }
-}
-
-static ScrArea* splitarea(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac)
-{
-       ScrArea *newa=NULL;
-       ScrVert *sv1, *sv2;
-       short split;
-       
-       if(sa==0) return NULL;
-       
-       split= testsplitpoint(win, sa, dir, fac);
-       if(split==0) return NULL;
-       
-       //sc= G.curscreen;
-       
-       //areawinset(sa->win);
-       
-       if(dir=='h') {
-               /* new vertices */
-               sv1= screen_addvert(sc, sa->v1->vec.x, split);
-               sv2= screen_addvert(sc, sa->v4->vec.x, split);
-               
-               /* new edges */
-               screen_addedge(sc, sa->v1, sv1);
-               screen_addedge(sc, sv1, sa->v2);
-               screen_addedge(sc, sa->v3, sv2);
-               screen_addedge(sc, sv2, sa->v4);
-               screen_addedge(sc, sv1, sv2);
-               
-               /* new areas: top */
-               newa= screen_addarea(sc, sv1, sa->v2, sa->v3, sv2, sa->headertype, sa->spacetype);
-               area_copy_data(newa, sa, 0);
-
-               /* area below */
-               sa->v2= sv1;
-               sa->v3= sv2;
-               
-       }
-       else {
-               /* new vertices */
-               sv1= screen_addvert(sc, split, sa->v1->vec.y);
-               sv2= screen_addvert(sc, split, sa->v2->vec.y);
-               
-               /* new edges */
-               screen_addedge(sc, sa->v1, sv1);
-               screen_addedge(sc, sv1, sa->v4);
-               screen_addedge(sc, sa->v2, sv2);
-               screen_addedge(sc, sv2, sa->v3);
-               screen_addedge(sc, sv1, sv2);
-               
-               /* new areas: left */
-               newa= screen_addarea(sc, sa->v1, sa->v2, sv2, sv1, sa->headertype, sa->spacetype);
-               area_copy_data(newa, sa, 0);
-
-               /* area right */
-               sa->v1= sv1;
-               sa->v2= sv2;
-       }
-       
-       /* remove double vertices en edges */
-       removedouble_scrverts(sc);
-       removedouble_scredges(sc);
-       removenotused_scredges(sc);
-       
-       return newa;
-}
-
-
-/* Helper function to join 2 areas, it has a return value, 0=failed 1=success
- *     used by the split, join and rip operators
- */
-int screen_join_areas(bScreen* scr, ScrArea *sa1, ScrArea *sa2) 
-{
-       int dir;
-       
-       dir = area_getorientation(scr, sa1, sa2);
-       /*printf("dir is : %i \n", dir);*/
-       
-       if (dir < 0)
-       {
-               if (sa1 ) sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
-               if (sa2 ) sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
-               return 0;
+       if (dir < 0)
+       {
+               if (sa1 ) sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
+               if (sa2 ) sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
+               return 0;
        }
        
        if(dir == 0) {
        }
        
        if(dir == 0) {
@@ -744,20 +554,60 @@ int screen_join_areas(bScreen* scr, ScrArea *sa1, ScrArea *sa2)
                screen_addedge(scr, sa1->v3, sa1->v4);
        }
        
                screen_addedge(scr, sa1->v3, sa1->v4);
        }
        
-       screen_delarea(scr, sa2);
+       screen_delarea(C, scr, sa2);
        removedouble_scrverts(scr);
        sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
        
        return 1;
 }
 
        removedouble_scrverts(scr);
        sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
        
        return 1;
 }
 
-/* *************************************************************** */
+void select_connected_scredge(bScreen *sc, ScrEdge *edge)
+{
+       ScrEdge *se;
+       ScrVert *sv;
+       int oneselected;
+       char dir;
+       
+       /* select connected, only in the right direction */
+       /* 'dir' is the direction of EDGE */
+       
+       if(edge->v1->vec.x==edge->v2->vec.x) dir= 'v';
+       else dir= 'h';
+       
+       sv= sc->vertbase.first;
+       while(sv) {
+               sv->flag = 0;
+               sv= sv->next;
+       }
+       
+       edge->v1->flag= 1;
+       edge->v2->flag= 1;
+       
+       oneselected= 1;
+       while(oneselected) {
+               se= sc->edgebase.first;
+               oneselected= 0;
+               while(se) {
+                       if(se->v1->flag + se->v2->flag==1) {
+                               if(dir=='h') if(se->v1->vec.y==se->v2->vec.y) {
+                                       se->v1->flag= se->v2->flag= 1;
+                                       oneselected= 1;
+                               }
+                                       if(dir=='v') if(se->v1->vec.x==se->v2->vec.x) {
+                                               se->v1->flag= se->v2->flag= 1;
+                                               oneselected= 1;
+                                       }
+                       }
+                               se= se->next;
+               }
+       }
+}
 
 /* test if screen vertices should be scaled */
 
 /* test if screen vertices should be scaled */
-void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
+static void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
 {
        ScrVert *sv=NULL;
 {
        ScrVert *sv=NULL;
-       ScrArea *sa, *san;
+       ScrArea *sa;
        int sizex, sizey;
        float facx, facy, tempf, min[2], max[2];
        
        int sizex, sizey;
        float facx, facy, tempf, min[2], max[2];
        
@@ -806,28 +656,47 @@ void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
        }
        
        /* test for collapsed areas. This could happen in some blender version... */
        }
        
        /* test for collapsed areas. This could happen in some blender version... */
-       for(sa= sc->areabase.first; sa; sa= san) {
-               san= sa->next;
-               if(sa->v1==sa->v2 || sa->v3==sa->v4 || sa->v2==sa->v3)
-                       screen_delarea(sc, sa);
+       /* ton: removed option now, it needs Context... */
+       
+       /* make each window at least HEADERY high */
+       for(sa= sc->areabase.first; sa; sa= sa->next) {
+               int headery= HEADERY+1;
+               
+               if(sa->v1->vec.y+headery > sa->v2->vec.y) {
+                       /* lower edge */
+                       ScrEdge *se= screen_findedge(sc, sa->v4, sa->v1);
+                       if(se && sa->v1!=sa->v2 ) {
+                               int yval;
+                               
+                               select_connected_scredge(sc, se);
+                               
+                               /* all selected vertices get the right offset */
+                               yval= sa->v2->vec.y-headery;
+                               sv= sc->vertbase.first;
+                               while(sv) {
+                                       /* if is a collapsed area */
+                                       if(sv!=sa->v2 && sv!=sa->v3) {
+                                               if(sv->flag) sv->vec.y= yval;
+                                       }
+                                       sv= sv->next;
+                               }
+                       }
+               }
        }
        }
+       
 }
 
 }
 
+/* *********************** DRAWING **************************************** */
 
 
 #define SCR_BACK 0.55
 #define SCR_ROUND 12
 
 
 
 #define SCR_BACK 0.55
 #define SCR_ROUND 12
 
-/** join areas arrow drawing **/
-typedef struct point{
-       float x,y;
-}_point;
-
 /* draw vertical shape visualising future joining (left as well
  * right direction of future joining) */
 static void draw_horizontal_join_shape(ScrArea *sa, char dir)
 {
 /* draw vertical shape visualising future joining (left as well
  * right direction of future joining) */
 static void draw_horizontal_join_shape(ScrArea *sa, char dir)
 {
-       _point points[10];
+       vec2f points[10];
        short i;
        float w, h;
        float width = sa->v3->vec.x - sa->v1->vec.x;
        short i;
        float w, h;
        float width = sa->v3->vec.x - sa->v1->vec.x;
@@ -899,7 +768,7 @@ static void draw_horizontal_join_shape(ScrArea *sa, char dir)
 /* draw vertical shape visualising future joining (up/down direction) */
 static void draw_vertical_join_shape(ScrArea *sa, char dir)
 {
 /* draw vertical shape visualising future joining (up/down direction) */
 static void draw_vertical_join_shape(ScrArea *sa, char dir)
 {
-       _point points[10];
+       vec2f points[10];
        short i;
        float w, h;
        float width = sa->v3->vec.x - sa->v1->vec.x;
        short i;
        float w, h;
        float width = sa->v3->vec.x - sa->v1->vec.x;
@@ -999,39 +868,87 @@ static void scrarea_draw_shape_light(ScrArea *sa, char dir)
        glDisable(GL_BLEND);
 }
 
        glDisable(GL_BLEND);
 }
 
+static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, short x2, short y2, short a) 
+{
+       /* right border area */
+       if(x2<sizex-1)
+               sdrawline(x2+a, y1, x2+a, y2);
+       
+       /* left border area */
+       if(x1>0)  /* otherwise it draws the emboss of window over */
+               sdrawline(x1+a, y1, x1+a, y2);
+       
+       /* top border area */
+       if(y2<sizey-1)
+               sdrawline(x1, y2+a, x2, y2+a);
+       
+       /* bottom border area */
+       if(y1>0)
+               sdrawline(x1, y1+a, x2, y1+a);
+       
+}
+
 /** screen edges drawing **/
 /** screen edges drawing **/
-static void drawscredge_area(ScrArea *sa)
+static void drawscredge_area(ScrArea *sa, int sizex, int sizey, int center)
 {
 {
-       AZone *az;
        short x1= sa->v1->vec.x;
        short x1= sa->v1->vec.x;
-       short xa1= x1+HEADERY;
        short y1= sa->v1->vec.y;
        short y1= sa->v1->vec.y;
-       short ya1= y1+HEADERY;
        short x2= sa->v3->vec.x;
        short x2= sa->v3->vec.x;
-       short xb2= x2-HEADERY;
        short y2= sa->v3->vec.y;
        short y2= sa->v3->vec.y;
-       short yb2= y2-HEADERY;
+       short a, rt;
        
        
-       cpack(0x0);
-       
-       /* right border area */
-       sdrawline(x2, y1, x2, y2);
+       rt= CLAMPIS(G.rt, 0, 16);
        
        
-       /* left border area */
-       if(x1>0) { /* otherwise it draws the emboss of window over */
-               sdrawline(x1, y1, x1, y2);
+       if(center==0) {
+               cpack(0x505050);
+               for(a=-rt; a<=rt; a++)
+                       if(a!=0)
+                               drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, a);
+       }
+       else {
+               cpack(0x0);
+               drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0);
        }
        }
+}
+
+/* ****************** EXPORTED API TO OTHER MODULES *************************** */
+
+bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
+{
+       bScreen *newsc;
        
        
-       /* top border area */
-       sdrawline(x1, y2, x2, y2);
+       if(sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */
        
        
-       /* bottom border area */
-       sdrawline(x1, y1, x2, y1);
+       /* make new empty screen: */
+       newsc= ED_screen_add(win, sc->scene, sc->id.name+2);
+       /* copy all data */
+       screen_copy(newsc, sc);
+       /* set in window */
+       win->screen= newsc;
+       
+       /* store identifier */
+       win->screen->winid= win->winid;
+       BLI_strncpy(win->screenname, win->screen->id.name+2, 21);
+
+       return newsc;
+}
+
+/* screen sets cursor based on swinid */
+static void region_cursor_set(wmWindow *win, int swinid)
+{
+       ScrArea *sa= win->screen->areabase.first;
        
        
-       /* temporary viz for 'action corner' */
-       for(az= sa->actionzones.first; az; az= az->next) {
-               if(az->type==AZONE_TRI) sdrawtrifill(az->x1, az->y1, az->x2, az->y2, .2, .2, .2);
-               //if(az->type==AZONE_TRI) sdrawtri(az->x1, az->y1, az->x2, az->y2);
+       for(;sa; sa= sa->next) {
+               ARegion *ar= sa->regionbase.first;
+               for(;ar; ar= ar->next) {
+                       if(ar->swinid == swinid) {
+                               if(ar->type && ar->type->cursor)
+                                       ar->type->cursor(win, sa, ar);
+                               else
+                                       WM_cursor_set(win, CURSOR_STD);
+                               return;
+                       }
+               }
        }
 }
 
        }
 }
 
@@ -1039,27 +956,25 @@ void ED_screen_do_listen(wmWindow *win, wmNotifier *note)
 {
        
        /* generic notes */
 {
        
        /* generic notes */
-       switch(note->type) {
-               case WM_NOTE_WINDOW_REDRAW:
-                       win->screen->do_draw= 1;
-                       break;
-               case WM_NOTE_SCREEN_CHANGED:
-                       win->screen->do_draw= win->screen->do_refresh= 1;
+       switch(note->category) {
+               case NC_WM:
+                       if(note->data==ND_FILEREAD)
+                               win->screen->do_draw= 1;
                        break;
                        break;
-               case WM_NOTE_AREA_SPLIT:
-                       printf("WM_NOTE_AREA_SPLIT\n");
-                       break;
-               case WM_NOTE_AREA_DRAG:
-                       printf("WM_NOTE_AREA_DRAG\n");
+               case NC_WINDOW:
+                       win->screen->do_draw= 1;
                        break;
                        break;
-               case WM_NOTE_GESTURE_CHANGED:
-                       printf("WM_NOTE_GESTURE_CHANGED\n");
-                       win->screen->do_gesture= 1;
+               case NC_SCREEN:
+                       if(note->action==NA_EDITED)
+                               win->screen->do_draw= win->screen->do_refresh= 1;
+               case NC_SCENE:
+                       if(note->data==ND_MODE)
+                               region_cursor_set(win, note->swinid);                           
                        break;
        }
 }
 
                        break;
        }
 }
 
-
+/* only for edge lines between areas, and the blended join arrows */
 void ED_screen_draw(wmWindow *win)
 {
        ScrArea *sa;
 void ED_screen_draw(wmWindow *win)
 {
        ScrArea *sa;
@@ -1068,14 +983,17 @@ void ED_screen_draw(wmWindow *win)
        int dir = -1;
        int dira = -1;
 
        int dir = -1;
        int dira = -1;
 
-       wm_subwindow_set(win, win->screen->mainwin);
+       wmSubWindowSet(win, win->screen->mainwin);
        
        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
                if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa;
                if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa;
        
        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
                if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa;
                if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa;
-               drawscredge_area(sa);
+               drawscredge_area(sa, win->sizex, win->sizey, 0);
        }
        }
-
+       for(sa= win->screen->areabase.first; sa; sa= sa->next)
+               drawscredge_area(sa, win->sizex, win->sizey, 1);
+       
+       /* blended join arrow */
        if (sa1 && sa2) {
                dir = area_getorientation(win->screen, sa1, sa2);
                if (dir >= 0) {
        if (sa1 && sa2) {
                dir = area_getorientation(win->screen, sa1, sa2);
                if (dir >= 0) {
@@ -1101,27 +1019,17 @@ void ED_screen_draw(wmWindow *win)
                scrarea_draw_shape_dark(sa2, dir);
                scrarea_draw_shape_light(sa1, dira);
        }
                scrarea_draw_shape_dark(sa2, dir);
                scrarea_draw_shape_light(sa1, dira);
        }
-       if(G.f & G_DEBUG) printf("draw screen\n");
+       
+//     if(G.f & G_DEBUG) printf("draw screen\n");
        win->screen->do_draw= 0;
 }
 
        win->screen->do_draw= 0;
 }
 
-void ED_screen_gesture(wmWindow *win)
-{
-       if(G.f & G_DEBUG) printf("gesture draw screen\n");
-
-       if(win->gesture.first) {
-               ed_gesture_update(win);
-       }
-       win->screen->do_gesture= 0;
-}
-
 /* make this screen usable */
 /* for file read and first use, for scaling window, area moves */
 void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
 {
        ScrArea *sa;
 /* make this screen usable */
 /* for file read and first use, for scaling window, area moves */
 void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
 {
        ScrArea *sa;
-       ARegion *ar;
-       rcti winrct= {0, win->sizex, 0, win->sizey};
+       rcti winrct= {0, win->sizex-1, 0, win->sizey-1};
        
        screen_test_scale(win->screen, win->sizex, win->sizey);
        
        
        screen_test_scale(win->screen, win->sizex, win->sizey);
        
@@ -1131,19 +1039,19 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
                wm_subwindow_position(win, win->screen->mainwin, &winrct);
        
        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
                wm_subwindow_position(win, win->screen->mainwin, &winrct);
        
        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
-               /* set spacetype and region callbacks */
-               /* sets subwindow */
+               /* set spacetype and region callbacks, calls init() */
+               /* sets subwindows for regions, adds handlers */
                ED_area_initialize(wm, win, sa);
        }
 
                ED_area_initialize(wm, win, sa);
        }
 
-       for(ar= win->screen->regionbase.first; ar; ar= ar->next) {
-               /* set subwindow */
-               ED_region_initialize(wm, win, ar);
-       }
+       /* wake up animtimer */
+       if(win->screen->animtimer)
+               WM_event_window_timer_sleep(win, win->screen->animtimer, 0);
        
        if(G.f & G_DEBUG) printf("set screen\n");
        win->screen->do_refresh= 0;
 
        
        if(G.f & G_DEBUG) printf("set screen\n");
        win->screen->do_refresh= 0;
 
+       win->screen->context= ed_screen_context;
 }
 
 /* file read, set all screens, ... */
 }
 
 /* file read, set all screens, ... */
@@ -1160,851 +1068,473 @@ void ED_screens_initialize(wmWindowManager *wm)
        }
 }
 
        }
 }
 
+
+/* *********** exit calls are for closing running stuff ******** */
+
 void ED_region_exit(bContext *C, ARegion *ar)
 {
 void ED_region_exit(bContext *C, ARegion *ar)
 {
-       WM_operator_cancel(C, &ar->modalops, NULL);
-       WM_event_remove_handlers(&ar->handlers);
+       ARegion *prevar= CTX_wm_region(C);
+
+       CTX_wm_region_set(C, ar);
+       WM_event_remove_handlers(C, &ar->handlers);
+       if(ar->swinid)
+               wm_subwindow_close(CTX_wm_window(C), ar->swinid);
+       ar->swinid= 0;
+       
+       if(ar->headerstr)
+               MEM_freeN(ar->headerstr);
+       ar->headerstr= NULL;
+       
+       CTX_wm_region_set(C, prevar);
 }
 
 void ED_area_exit(bContext *C, ScrArea *sa)
 {
 }
 
 void ED_area_exit(bContext *C, ScrArea *sa)
 {
+       ScrArea *prevsa= CTX_wm_area(C);
        ARegion *ar;
 
        ARegion *ar;
 
+       CTX_wm_area_set(C, sa);
        for(ar= sa->regionbase.first; ar; ar= ar->next)
                ED_region_exit(C, ar);
 
        for(ar= sa->regionbase.first; ar; ar= ar->next)
                ED_region_exit(C, ar);
 
-       WM_operator_cancel(C, &sa->modalops, NULL);
-       WM_event_remove_handlers(&sa->handlers);
+       WM_event_remove_handlers(C, &sa->handlers);
+       CTX_wm_area_set(C, prevsa);
 }
 
 void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
 {
 }
 
 void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
 {
+       wmWindow *prevwin= CTX_wm_window(C);
        ScrArea *sa;
        ARegion *ar;
 
        ScrArea *sa;
        ARegion *ar;
 
+       CTX_wm_window_set(C, window);
+       
+       if(screen->animtimer)
+               WM_event_remove_window_timer(window, screen->animtimer);
+       screen->animtimer= NULL;
+       
+       if(screen->mainwin)
+               wm_subwindow_close(window, screen->mainwin);
+       screen->mainwin= 0;
+       screen->subwinactive= 0;
+       
        for(ar= screen->regionbase.first; ar; ar= ar->next)
                ED_region_exit(C, ar);
 
        for(sa= screen->areabase.first; sa; sa= sa->next)
                ED_area_exit(C, sa);
 
        for(ar= screen->regionbase.first; ar; ar= ar->next)
                ED_region_exit(C, ar);
 
        for(sa= screen->areabase.first; sa; sa= sa->next)
                ED_area_exit(C, sa);
 
-       WM_operator_cancel(C, &window->modalops, NULL);
-       WM_event_remove_handlers(&window->handlers);
+       /* mark it available for use for other windows */
+       screen->winid= 0;
+       
+       CTX_wm_window_set(C, prevwin);
 }
 
 }
 
-void placeholder()
+/* *********************************** */
+
+/* case when on area-edge or in azones, or outside window */
+static void screen_cursor_set(wmWindow *win, wmEvent *event)
 {
 {
-       removenotused_scrverts(NULL);
-       removenotused_scredges(NULL);
+       AZone *az= NULL;
+       ScrArea *sa;
+       
+       for(sa= win->screen->areabase.first; sa; sa= sa->next)
+               if((az=is_in_area_actionzone(sa, event->x, event->y)))
+                       break;
+       
+       if(sa) {
+               if(az->type==AZONE_AREA)
+                       WM_cursor_set(win, CURSOR_EDIT);
+               else if(az->type==AZONE_REGION) {
+                       if(az->x1==az->x2)
+                               WM_cursor_set(win, CURSOR_X_MOVE);
+                       else
+                               WM_cursor_set(win, CURSOR_Y_MOVE);
+               }
+       }
+       else {
+               ScrEdge *actedge= screen_find_active_scredge(win->screen, event->x, event->y);
+               
+               if (actedge) {
+                       if(scredge_is_horizontal(actedge))
+                               WM_cursor_set(win, CURSOR_Y_MOVE);
+                       else
+                               WM_cursor_set(win, CURSOR_X_MOVE);
+               }
+               else
+                       WM_cursor_set(win, CURSOR_STD);
+       } 
 }
 
 }
 
-/* called in wm_event_system.c. sets state var in screen */
-void ED_screen_set_subwinactive(wmWindow *win)
+
+/* called in wm_event_system.c. sets state vars in screen, cursors */
+/* event type is mouse move */
+void ED_screen_set_subwinactive(wmWindow *win, wmEvent *event)
 {
        if(win->screen) {
 {
        if(win->screen) {
-               wmEvent *event= win->eventstate;
+               bScreen *scr= win->screen;
                ScrArea *sa;
                ScrArea *sa;
-               
-               for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+               ARegion *ar;
+               int oldswin= scr->subwinactive;
+
+               for(sa= scr->areabase.first; sa; sa= sa->next) {
                        if(event->x > sa->totrct.xmin && event->x < sa->totrct.xmax)
                                if(event->y > sa->totrct.ymin && event->y < sa->totrct.ymax)
                        if(event->x > sa->totrct.xmin && event->x < sa->totrct.xmax)
                                if(event->y > sa->totrct.ymin && event->y < sa->totrct.ymax)
-                                       break;
+                                       if(NULL==is_in_area_actionzone(sa, event->x, event->y))
+                                               break;
                }
                if(sa) {
                }
                if(sa) {
-                       ARegion *ar;
                        for(ar= sa->regionbase.first; ar; ar= ar->next) {
                                if(BLI_in_rcti(&ar->winrct, event->x, event->y))
                        for(ar= sa->regionbase.first; ar; ar= ar->next) {
                                if(BLI_in_rcti(&ar->winrct, event->x, event->y))
-                                       win->screen->subwinactive= ar->swinid;
+                                       scr->subwinactive= ar->swinid;
                        }
                }
                else
                        }
                }
                else
-                       win->screen->subwinactive= win->screen->mainwin;
+                       scr->subwinactive= scr->mainwin;
                
                
-       }
-}
+               /* check for redraw headers */
+               if(oldswin!=scr->subwinactive) {
 
 
-/* ****************** cursor near edge operator ********************************* */
-
-/* operator cb */
-int screen_cursor_test(bContext *C, wmOperator *op, wmEvent *event)
-{
-       if (C->screen->subwinactive==C->screen->mainwin) {
-               ScrEdge *actedge= screen_find_active_scredge(C->screen, event->x, event->y);
+                       for(sa= scr->areabase.first; sa; sa= sa->next) {
+                               int do_draw= 0;
+                               
+                               for(ar= sa->regionbase.first; ar; ar= ar->next)
+                                       if(ar->swinid==oldswin || ar->swinid==scr->subwinactive)
+                                               do_draw= 1;
+                               
+                               if(do_draw) {
+                                       for(ar= sa->regionbase.first; ar; ar= ar->next)
+                                               if(ar->regiontype==RGN_TYPE_HEADER)
+                                                       ED_region_tag_redraw(ar);
+                               }
+                       }
+               }
                
                
-               if (actedge && scredge_is_horizontal(actedge)) {
-                       WM_set_cursor(C, CURSOR_Y_MOVE);
-               } else {
-                       WM_set_cursor(C, CURSOR_X_MOVE);
+               /* cursors, for time being set always on edges, otherwise aregion doesnt switch */
+               if(scr->subwinactive==scr->mainwin) {
+                       screen_cursor_set(win, event);
                }
                }
-       } else {
-               ScrArea *sa= NULL;
-               AZone *az= NULL;
-               for(sa= C->screen->areabase.first; sa; sa= sa->next) {
-                       az= is_in_area_actionzone(sa, event->x, event->y);
-                       if(az!=NULL) break;
+               else if(oldswin!=scr->subwinactive) {
+                       region_cursor_set(win, scr->subwinactive);
                }
                }
-               if(az!=NULL) WM_set_cursor(C, CURSOR_EDIT);
-               else WM_set_cursor(C, CURSOR_STD);
        }
        }
-       
-       return OPERATOR_PASS_THROUGH;
 }
 
 }
 
-/* ************** move area edge operator *********************************** */
-
-/* operator state vars used:  
-           x, y                        mouse coord near edge
-           delta            movement of edge
-
-   internal:
-
-   init()   set default property values, find edge based on mouse coords, test
-            if the edge can be moved, select edges, calculate min and max movement
-
-   apply()     apply delta on selection
-
-   exit()      cleanup, send notifier
-
-   callbacks:
-
-   exec()   execute without any user interaction, based on properties
-            call init(), apply(), exit()
-
-   invoke() gets called on mouse click near edge
-            call init(), add handler
-
-   modal()  accept modal events while doing it
-                       call apply() with delta motion
-            call exit() and remove handler
-
-   cancel() cancel moving
-
-*/
-
-typedef struct sAreaMoveData {
-       int bigger, smaller, origval;
-       char dir;
-} sAreaMoveData;
-
-/* validate selection inside screen, set variables OK */
-/* return 0: init failed */
-static int move_areas_init (bContext *C, wmOperator *op)
+int ED_screen_area_active(const bContext *C)
 {
 {
-       ScrEdge *actedge;
-       ScrArea *sa;
-       sAreaMoveData *md;
-       int x, y;
-
-       /* required properties */
-       if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y)))
-               return 0;
-
-       /* default properties */
-       OP_verify_int(op, "delta", 0, NULL);
-
-       /* setup */
-       actedge= screen_find_active_scredge(C->screen, x, y);
-       if(actedge==NULL) return 0;
-
-       md= MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData");
-       op->customdata= md;
-
-       md->dir= scredge_is_horizontal(actedge)?'h':'v';
-       if(md->dir=='h') md->origval= actedge->v1->vec.y;
-       else md->origval= actedge->v1->vec.x;
-       
-       select_connected_scredge(C->screen, actedge);
-
-       /* now all verices with 'flag==1' are the ones that can be moved. */
-       /* we check all areas and test for free space with MINSIZE */
-       md->bigger= md->smaller= 10000;
-       for(sa= C->screen->areabase.first; sa; sa= sa->next) {
-               if(md->dir=='h') {      /* if top or down edge selected, test height */
-                  
-                  if(sa->v1->flag && sa->v4->flag) {
-                          int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
-                          md->bigger= MIN2(md->bigger, y1);
-                  }
-                  else if(sa->v2->flag && sa->v3->flag) {
-                          int y1= sa->v2->vec.y - sa->v1->vec.y-AREAMINY;
-                          md->smaller= MIN2(md->smaller, y1);
-                  }
-               }
-               else {  /* if left or right edge selected, test width */
-                       if(sa->v1->flag && sa->v2->flag) {
-                               int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX;
-                               md->bigger= MIN2(md->bigger, x1);
-                       }
-                       else if(sa->v3->flag && sa->v4->flag) {
-                               int x1= sa->v4->vec.x - sa->v1->vec.x-AREAMINX;
-                               md->smaller= MIN2(md->smaller, x1);
-                       }
-               }
-       }
+       bScreen *sc= CTX_wm_screen(C);
+       ScrArea *sa= CTX_wm_area(C);
 
 
-       return 1;
+       if(sc && sa) {
+               ARegion *ar;
+               for(ar= sa->regionbase.first; ar; ar= ar->next)
+                       if(ar->swinid == sc->subwinactive)
+                               return 1;
+       }       
+       return 0;
 }
 
 }
 
-/* moves selected screen edge amount of delta */
-/* needs init call to work */
-static void move_areas_apply(bContext *C, wmOperator *op)
+/* operator call, WM + Window + screen already existed before */
+/* Do NOT call in area/region queues! */
+void ED_screen_set(bContext *C, bScreen *sc)
 {
 {
-       ScrVert *v1;
-       int delta;
-       sAreaMoveData *md= op->customdata;
-
-       OP_get_int(op, "delta", &delta);
+       wmWindow *win= CTX_wm_window(C);
+       bScreen *oldscreen= CTX_wm_screen(C);
+       ID *id;
        
        
-       delta= CLAMPIS(delta, -md->smaller, md->bigger);
-       
-       for (v1= C->screen->vertbase.first; v1; v1= v1->next) {
-               if (v1->flag) {
-                       /* that way a nice AREAGRID  */
-                       if((md->dir=='v') && v1->vec.x>0 && v1->vec.x<C->window->sizex-1) {
-                               v1->vec.x= md->origval + delta;
-                               if(delta != md->bigger && delta != -md->smaller) v1->vec.x-= (v1->vec.x % AREAGRID);
-                       }
-                       if((md->dir=='h') && v1->vec.y>0 && v1->vec.y<C->window->sizey-1) {
-                               v1->vec.y= md->origval + delta;
-
-                               v1->vec.y+= AREAGRID-1;
-                               v1->vec.y-= (v1->vec.y % AREAGRID);
-                               
-                               /* prevent too small top header */
-                               if(v1->vec.y > C->window->sizey-HEADERY)
-                                       v1->vec.y= C->window->sizey-HEADERY;
+       /* validate screen, it's called with notifier reference */
+       for(id= CTX_data_main(C)->screen.first; id; id= id->next)
+               if(sc == (bScreen *)id)
+                       break;
+       if(id==NULL) 
+               return;
+       
+       /* check for valid winid */
+       if(sc->winid!=0 && sc->winid!=win->winid)
+               return;
+       
+       if(sc->full) {                          /* find associated full */
+               bScreen *sc1;
+               for(sc1= CTX_data_main(C)->screen.first; sc1; sc1= sc1->id.next) {
+                       ScrArea *sa= sc1->areabase.first;
+                       if(sa->full==sc) {
+                               sc= sc1;
+                               break;
                        }
                }
        }
                        }
                }
        }
-
-       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-}
-
-static void move_areas_exit(bContext *C, wmOperator *op)
-{
-       if(op->customdata)
-               MEM_freeN(op->customdata);
-
-       /* this makes sure aligned edges will result in aligned grabbing */
-       removedouble_scrverts(C->screen);
-       removedouble_scredges(C->screen);
-}
-
-static int move_areas_exec(bContext *C, wmOperator *op)
-{
-       if(!move_areas_init(C, op))
-               return OPERATOR_CANCELLED;
        
        
-       move_areas_apply(C, op);
-       move_areas_exit(C, op);
-       
-       return OPERATOR_FINISHED;
+       if (oldscreen != sc) {
+               wmTimer *wt= oldscreen->animtimer;
+               
+               /* we put timer to sleep, so screen_exit has to think there's no timer */
+               oldscreen->animtimer= NULL;
+               if(wt)
+                       WM_event_window_timer_sleep(win, wt, 1);
+               
+               ED_screen_exit(C, win, oldscreen);
+               oldscreen->animtimer= wt;
+               
+               win->screen= sc;
+               CTX_wm_window_set(C, win);      // stores C->wm.screen... hrmf
+               
+               /* prevent multiwin errors */
+               sc->winid= win->winid;
+               
+               ED_screen_refresh(CTX_wm_manager(C), CTX_wm_window(C));
+               WM_event_add_notifier(C, NC_WINDOW, NULL);
+               
+               /* makes button hilites work */
+               WM_event_add_mousemove(C);
+       }
 }
 
 }
 
-/* interaction callback */
-static int move_areas_invoke(bContext *C, wmOperator *op, wmEvent *event)
+/* only call outside of area/region loops */
+void ED_screen_set_scene(bContext *C, Scene *scene)
 {
 {
-       OP_verify_int(op, "x", event->x, NULL);
-       OP_verify_int(op, "y", event->y, NULL);
-
-       if(!move_areas_init(C, op)) 
-               return OPERATOR_PASS_THROUGH;
-       
-       /* add temp handler */
-       WM_event_add_modal_handler(&C->window->handlers, op);
+       bScreen *sc;
+       bScreen *curscreen= CTX_wm_screen(C);
        
        
-       return OPERATOR_RUNNING_MODAL;
-}
-
-static int move_areas_cancel(bContext *C, wmOperator *op)
-{
-       WM_event_remove_modal_handler(&C->window->handlers, op);                                
-
-       OP_set_int(op, "delta", 0);
-       move_areas_apply(C, op);
-       move_areas_exit(C, op);
-
-       return OPERATOR_CANCELLED;
-}
-
-/* modal callback for while moving edges */
-static int move_areas_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
-       sAreaMoveData *md;
-       int delta, x, y;
-
-       md= op->customdata;
-
-       OP_get_int(op, "x", &x);
-       OP_get_int(op, "y", &y);
-
-       /* execute the events */
-       switch(event->type) {
-               case MOUSEMOVE:
-                       delta= (md->dir == 'v')? event->x - x: event->y - y;
-                       OP_set_int(op, "delta", delta);
-
-                       move_areas_apply(C, op);
-                       break;
+       for(sc= CTX_data_main(C)->screen.first; sc; sc= sc->id.next) {
+               if((U.flag & USER_SCENEGLOBAL) || sc==curscreen) {
                        
                        
-               case LEFTMOUSE:
-                       if(event->val==0) {
-                               move_areas_exit(C, op);
-                               WM_event_remove_modal_handler(&C->window->handlers, op);                                
-                               return OPERATOR_FINISHED;
+                       if(scene != sc->scene) {
+                               /* all areas endlocalview */
+                       // XXX  ScrArea *sa= sc->areabase.first;
+                       //      while(sa) {
+                       //              endlocalview(sa);
+                       //              sa= sa->next;
+                       //      }               
+                               sc->scene= scene;
                        }
                        }
-                       break;
                        
                        
-               case ESCKEY:
-                       return move_areas_cancel(C, op);
+               }
        }
        
        }
        
-       return OPERATOR_RUNNING_MODAL;
-}
-
-void ED_SCR_OT_move_areas(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Move area edges";
-       ot->idname= "ED_SCR_OT_move_areas";
-
-       ot->exec= move_areas_exec;
-       ot->invoke= move_areas_invoke;
-       ot->cancel= move_areas_cancel;
-       ot->modal= move_areas_modal;
-
-       ot->poll= ED_operator_screen_mainwinactive;
-}
-
-/****************** split area ********************/
-/* we do split on init, then we work like move_areas
-       if operation gets cancelled -> join
-       if operation gets confirmed -> yay
-*/
-
-#define SPLIT_STARTED  1
-#define SPLIT_PROGRESS 2
-#define SPLIT_DONE             3
-
-typedef struct sAreaSplitData
-{
-       int state; /* state of operation */
-       int dir; /* direction of new edge */
-       int deltax, deltay;
-       int origval; /* for move areas */
-       int min,max; /* constraints for moving new edge */
-       int pos; /* with sa as center, ne is located at: 0=W, 1=N, 2=E, 3=S */
-       ScrEdge *nedge; /* new edge */
-       ScrEdge *aedge; /* active edge */
-       ScrArea *sarea; /* start area */
-       ScrArea *narea; /* new area */
-} sAreaSplitData;
-
-static int split_area_init(bContext *C, wmOperator *op)
-{
-       AZone *az= NULL;
-       ScrArea *sa= NULL;
-       sAreaSplitData *sd= NULL;
-       int x, y;
-
-       /* required properties */
-       if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y)))
-               return 0;
-       
-       OP_verify_int(op, "delta", 0, NULL);
-       OP_verify_int(op, "dir", 0, NULL);
-       
-       for(sa= C->screen->areabase.first; sa; sa= sa->next) {
-               az= is_in_area_actionzone(sa, x, y);
-               if(az!=NULL) break;
+       //  copy_view3d_lock(0);        /* space.c */
+       
+       /* are there cameras in the views that are not in the scene? */
+       for(sc= CTX_data_main(C)->screen.first; sc; sc= sc->id.next) {
+               if( (U.flag & USER_SCENEGLOBAL) || sc==curscreen) {
+                       ScrArea *sa= sc->areabase.first;
+                       while(sa) {
+                               SpaceLink *sl= sa->spacedata.first;
+                               while(sl) {
+                                       if(sl->spacetype==SPACE_VIEW3D) {
+                                               View3D *v3d= (View3D*) sl;
+                                               if (!v3d->camera || !object_in_scene(v3d->camera, scene)) {
+                                                       v3d->camera= scene_find_camera(sc->scene);
+                                                       // XXX if (sc==curscreen) handle_view3d_lock();
+                                                       if (!v3d->camera && v3d->persp==V3D_CAMOB) 
+                                                               v3d->persp= V3D_PERSP;
+                                               }
+                                       }
+                                       sl= sl->next;
+                               }
+                               sa= sa->next;
+                       }
+               }
        }
        
        }
        
-       if(az==NULL) return 0;
+       CTX_data_scene_set(C, scene);
+       set_scene_bg(scene);
        
        
-       sd= (sAreaSplitData*)MEM_callocN(sizeof (sAreaSplitData), "op_split_area");
-       op->customdata= sd;
+       ED_update_for_newframe(C, 1);
        
        
-       sd->state= SPLIT_STARTED;
-       sd->deltax= 0;
-       sd->deltay= 0;
+       /* complete redraw */
+       WM_event_add_notifier(C, NC_WINDOW, NULL);
        
        
-       return 1;
 }
 
 }
 
-/* the moving of the new egde */
-static void split_area_apply(bContext *C, wmOperator *op)
+/* this function toggles: if area is full then the parent will be restored */
+void ed_screen_fullarea(bContext *C, ScrArea *sa)
 {
 {
-       sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
-       int newval, delta, dir;
-
-       OP_get_int(op, "delta", &delta);
-       OP_get_int(op, "dir", &dir);
-
-       newval= sd->origval + delta;
-       newval= CLAMPIS(newval, -sd->min, sd->max);
+       bScreen *sc, *oldscreen;
        
        
-       if((dir=='v') && (newval > sd->min && newval < sd->max-1)) {
-               sd->nedge->v1->vec.x= newval;
-               sd->nedge->v2->vec.x= newval;
-       }
-       if((dir=='h') && (newval > sd->min+HEADERY && newval < sd->max-HEADERY)) {
-               sd->nedge->v1->vec.y= newval;           
-               sd->nedge->v2->vec.y= newval;
-       }
-}
-
-static void split_area_exit(bContext *C, wmOperator *op)
-{
-       if (op->customdata) {
-               MEM_freeN(op->customdata);
-               op->customdata = NULL;
+       if(sa==NULL) {
+               return;
        }
        }
-       
-       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-
-       /* this makes sure aligned edges will result in aligned grabbing */
-       removedouble_scrverts(C->screen);
-       removedouble_scredges(C->screen);
-}
-
-static int split_area_init_intern(bContext *C, wmOperator *op, sAreaSplitData *sd)
-{
-       float fac= 0.0;
-       int dir;
-
-       OP_get_int(op, "dir", &dir);
-
-       if(dir=='h') {
-               OP_get_int(op, "y", &sd->origval);
-               fac= 1.0 - ((float)(sd->sarea->v3->vec.y - sd->origval)) / (float)sd->sarea->winy;
-               sd->min= sd->aedge->v1->vec.y;
-               sd->max= sd->aedge->v2->vec.y;
+       else if(sa->full) {
+               short fulltype;
+               
+               sc= sa->full;           /* the old screen to restore */
+               oldscreen= CTX_wm_screen(C);    /* the one disappearing */
+               
+               fulltype = sc->full;
+               
+               /* refuse to go out of SCREENAUTOPLAY as long as G_FLAGS_AUTOPLAY
+                  is set */
+               
+               if (fulltype != SCREENAUTOPLAY || (G.flags & G_FILE_AUTOPLAY) == 0) {
+                       ScrArea *old;
+                       
+                       sc->full= 0;
+                       
+                       /* find old area */
+                       for(old= sc->areabase.first; old; old= old->next) 
+                               if(old->full) break;
+                       if(old==NULL) {
+                               printf("something wrong in areafullscreen\n"); 
+                               return;
+                       }
+                           // old feature described below (ton)
+                               // in autoplay screens the headers are disabled by 
+                               // default. So use the old headertype instead
+                       
+                       area_copy_data(old, sa, 1);     /*  1 = swap spacelist */
+                       
+                       old->full= NULL;
+                       
+                       /* animtimer back */
+                       sc->animtimer= oldscreen->animtimer;
+                       oldscreen->animtimer= NULL;
+                       
+                       ED_screen_set(C, sc);
+                       
+                       free_screen(oldscreen);
+                       free_libblock(&CTX_data_main(C)->screen, oldscreen);
+               }
        }
        else {
        }
        else {
-               OP_get_int(op, "x", &sd->origval);
-               fac= 1.0 - ((float)(sd->sarea->v4->vec.x - sd->origval)) / (float)sd->sarea->winx;
-               sd->min= sd->aedge->v1->vec.x;
-               sd->max= sd->aedge->v2->vec.x;
-       }
-       
-       sd->narea= splitarea(C->window, C->screen, sd->sarea, dir, fac);
-       
-       if(sd->narea==NULL) return 0;
-       
-       sd->nedge= area_findsharededge(C->screen, sd->sarea, sd->narea);
-       
-       /* select newly created edge */
-       select_connected_scredge(C->screen, sd->nedge);
-       
-       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-       
-       return 1;
-}
+               ScrArea *newa;
+               
+               oldscreen= CTX_wm_screen(C);
 
 
-static int split_area_exec(bContext *C, wmOperator *op)
-{
-       /* XXX: this does nothing, part of the code should be moved
-        * out of modal() */
-       
-       if(!split_area_init(C, op))
-               return OPERATOR_CANCELLED;
-       
-       split_area_apply(C, op);
-       split_area_exit(C, op);
-       
-       return OPERATOR_FINISHED;
-}
+               /* is there only 1 area? */
+               if(oldscreen->areabase.first==oldscreen->areabase.last) return;
+               
+               oldscreen->full = SCREENFULL;
+               
+               sc= ED_screen_add(CTX_wm_window(C), CTX_data_scene(C), "temp");
+               sc->full = SCREENFULL; // XXX
+               
+               /* timer */
+               sc->animtimer= oldscreen->animtimer;
+               oldscreen->animtimer= NULL;
+               
+               /* returns the top small area */
+               newa= area_split(CTX_wm_window(C), sc, (ScrArea *)sc->areabase.first, 'h', 0.99f);
+               ED_area_newspace(C, newa, SPACE_INFO);
 
 
-static int split_area_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
-       OP_verify_int(op, "x", event->x, NULL);
-       OP_verify_int(op, "y", event->y, NULL);
+               /* copy area */
+               newa= newa->prev;
+               area_copy_data(newa, sa, 1);    /* 1 = swap spacelist */
 
 
-       if(!split_area_init(C, op))
-               return OPERATOR_PASS_THROUGH;
-       
-       /* add temp handler */
-       WM_event_add_modal_handler(&C->window->handlers, op);
-       
-       return OPERATOR_RUNNING_MODAL;
-}
+               sa->full= oldscreen;
+               newa->full= oldscreen;
+               newa->next->full= oldscreen; // XXX
 
 
-static int split_area_cancel(bContext *C, wmOperator *op)
-{
-       sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
+               ED_screen_set(C, sc);
+       }
 
 
-       WM_event_remove_modal_handler(&C->window->handlers, op);
+       /* XXX bad code: setscreen() ends with first area active. fullscreen render assumes this too */
+       CTX_wm_area_set(C, sc->areabase.first);
 
 
-       OP_set_int(op, "delta", 0);
-       if (screen_join_areas(C->screen,sd->sarea, sd->narea)) {
-               if (C->area == sd->narea) {
-                       C->area = NULL;
-               }
-               sd->narea = NULL;
-       }
-       split_area_exit(C, op);
+       /* XXX retopo_force_update(); */
 
 
-       return OPERATOR_CANCELLED;
 }
 
 }
 
-static int split_area_modal(bContext *C, wmOperator *op, wmEvent *event)
+int ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
 {
 {
-       ScrArea *sa= NULL, *sold=NULL;
-       sAreaSplitData *sd= (sAreaSplitData *)op->customdata;
-       int x, y, dir;
-
-       OP_get_int(op, "x", &x);
-       OP_get_int(op, "y", &y);
-       OP_get_int(op, "dir", &dir);
-
-       /* execute the events */
-       switch(event->type) {
-               case MOUSEMOVE:
-                       if(sd->state==SPLIT_STARTED) {
-                               /*
-                                       We first want to determine direction for split.
-                                       Get at least one(x or y) delta of minimum 10 pixels.
-                                       If one dir is delta threshold, and other dir is within "grey area" -> vert/hor split.
-                                       If we get both over threshold -> subdiv.
-                               */
-                               sd->deltax= event->x - x;
-                               sd->deltay= event->y - y;
-                               
-                               if(sd->deltax>10 && sd->deltay<4) {
-                                       printf("split on v\n");
-                                       sd->state= SPLIT_PROGRESS;
-                                       OP_set_int(op, "dir", 'v');
-                                       OP_set_int(op, "delta", sd->deltax);
-                               } else if(sd->deltay>10 && sd->deltax<4) {
-                                       printf("split on h\n");
-                                       sd->state= SPLIT_PROGRESS;
-                                       OP_set_int(op, "dir", 'h');
-                                       OP_set_int(op, "delta", sd->deltay);
-                               }
-                               
-                       } else if(sd->state==SPLIT_PROGRESS) {
-                               sa= screen_areahascursor(C->screen, event->x, event->y);
-
-                               /* area containing cursor has changed */
-                               if(sa && sd->sarea!=sa && sd->narea!=sa) {
-                                       sold= sd->sarea;
-                                       if (screen_join_areas(C->screen,sd->sarea, sd->narea)) {
-                                               if (C->area == sd->narea) {
-                                                       C->area = NULL;
-                                               }
-                                               sd->narea = NULL;
-                                       }
-
-                                       /* now find aedge with same orientation as sd->dir (inverted) */
-                                       if(dir=='v') {
-                                               sd->aedge= screen_findedge(C->screen, sa->v1, sa->v4);
-                                               if(sd->aedge==NULL) sd->aedge= screen_findedge(C->screen, sa->v2, sa->v3);
-                                       }
-                                       else {
-                                               sd->aedge= screen_findedge(C->screen, sa->v1, sa->v2);
-                                               if(sd->aedge==NULL) sd->aedge= screen_findedge(C->screen, sa->v3, sa->v4);
-                                       }
+       if(sa==NULL)
+               return 0;
+       
+       if(sa->full==0)
+               ed_screen_fullarea(C, sa);
 
 
-                                       /* set sd and op to new init state */
-                                       sd->sarea= sa;
-                                       OP_set_int(op, "delta", 0);
-                                       OP_set_int(op, "x", event->x);
-                                       OP_set_int(op, "y", event->y);
-                                       split_area_init_intern(C, op, sd);
-                               }
-                               else {
-                                       /* all is cool, update delta according complicated formula */
-                                       if(dir=='v')
-                                               OP_set_int(op, "delta", event->x - y);
-                                       else
-                                               OP_set_int(op, "delta", event->x - y);
-                                       
-                                       split_area_apply(C, op);
-                               }
-                       } else if (sd->state==SPLIT_DONE) {
-                               /* shouldn't get here anymore */
-                       }
-                       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-                       break;
-               case LEFTMOUSE:
-                       if(event->val==0) { /* mouse up => confirm if not near/on starting edge */
-                               split_area_exit(C, op);
-                               WM_event_remove_modal_handler(&C->window->handlers, op);
-                               return OPERATOR_FINISHED;
-                       }
-                       break;
-               case RIGHTMOUSE: /* cancel operation */
-               case ESCKEY:
-                       return split_area_cancel(C, op);
-       }
+       /* CTX_wm_area(C) is new area */
+       ED_area_newspace(C, CTX_wm_area(C), type);
        
        
-       return OPERATOR_RUNNING_MODAL;
+       return 1;
 }
 
 }
 
-void ED_SCR_OT_split_area(wmOperatorType *ot)
+void ED_screen_full_prevspace(bContext *C)
 {
 {
-       ot->name = "Split area";
-       ot->idname = "ED_SCR_OT_split_area";
+       ScrArea *sa= CTX_wm_area(C);
        
        
-       ot->exec= split_area_exec;
-       ot->invoke= split_area_invoke;
-       ot->modal= split_area_modal;
+       ED_area_prevspace(C);
        
        
-       ot->poll= ED_operator_screenactive;
+       if(sa->full)
+               ed_screen_fullarea(C, sa);
 }
 
 }
 
-/* ************** join area operator ********************************************** */
-
-/* operator state vars used:  
-           x, y       mouse coord near edge
-           delta      movement of edge
-
-   callbacks:
-
-   init()   find edge based on op->veci, 
-                       test if the edge divides two areas, 
-                       store active and nonactive area,
-            
-   apply()
-
-   exit()      cleanup, send notifier
-
-   exec()      remove active window, 
-                       recalc size,
-                       make nonactive window active, 
-                       add notifier for redraw.
-   
-   invoke() handler gets called on Alt+RMB near edge
-            call init()
-            add handler
-
-   modal()     accept modal events while doing it
-                       call apply() with active window and nonactive window
-            call exit() and remove handler when LMB confirm
-
-*/
-
-typedef struct sAreaJoinData
-{
-       int dir;
-       ScrArea *sa1; /* first area to be considered */
-       ScrArea *sa2; /* second area to be considered */
-       ScrArea *scr; /* designed for removal */
-
-} sAreaJoinData;
-
-
-/* validate selection inside screen, set variables OK */
-/* return 0: init failed */
-static int join_areas_init(bContext *C, wmOperator *op)
+/* redraws: uses defines from stime->redraws 
+ * enable: 1 - forward on, -1 - backwards on, 0 - off
+ */
+void ED_screen_animation_timer(bContext *C, int redraws, int enable)
 {
 {
-       ScrArea *actarea = NULL;
-       sAreaJoinData* jd= NULL;
-       int x, y;
-
-       if(!(OP_get_int(op, "x", &x) && OP_get_int(op, "y", &y)))
-               return 0;
-       
-       actarea = screen_areahascursor(C->screen, x, y);
-       if(actarea==NULL)
-               return 0;
-
-       jd = (sAreaJoinData*)MEM_callocN(sizeof (sAreaJoinData), "op_join_areas");
-               
-       jd->sa1 = actarea;
-       jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
+       bScreen *screen= CTX_wm_screen(C);
+       wmWindow *win= CTX_wm_window(C);
+       Scene *scene= CTX_data_scene(C);
        
        
-       op->customdata= jd;
+       if(screen->animtimer)
+               WM_event_remove_window_timer(win, screen->animtimer);
+       screen->animtimer= NULL;
        
        
-       return 1;
-}
-
-/* apply the join of the areas (space types) */
-static int join_areas_apply(bContext *C, wmOperator *op)
-{
-       sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
-       if (!jd) return 0;
-
-       if(!screen_join_areas(C->screen,jd->sa1,jd->sa2)){
-               return 0;
-       }
-       if (C->area == jd->sa2) {
-               C->area = NULL;
+       if(enable) {
+               struct ScreenAnimData *sad= MEM_mallocN(sizeof(ScreenAnimData), "ScreenAnimData");
+               
+               screen->animtimer= WM_event_add_window_timer(win, TIMER0, (1.0/FPS));
+               sad->ar= CTX_wm_region(C);
+               sad->redraws= redraws;
+               sad->flag= (enable < 0) ? ANIMPLAY_FLAG_REVERSE : 0;
+               screen->animtimer->customdata= sad;
+               
        }
        }
-
-       return 1;
+       /* notifier catched by top header, for button */
+       WM_event_add_notifier(C, NC_SCREEN|ND_ANIMPLAY, screen);
 }
 
 }
 
-static int is_inside_area(ScrArea *ar, short x, short y)
+unsigned int ED_screen_view3d_layers(bScreen *screen)
 {
 {
-       int is_inside = 0;
-       if ( (ar->v1->vec.x < x) && (x < ar->v3->vec.x) ) {
-               if ( (y<ar->v3->vec.y) && (ar->v1->vec.y<y) ) {
-                       is_inside = 1;
+       if(screen) {
+               unsigned int layer= screen->scene->lay; /* as minimum this */
+               ScrArea *sa;
+               
+               /* get all used view3d layers */
+               for(sa= screen->areabase.first; sa; sa= sa->next) {
+                       if(sa->spacetype==SPACE_VIEW3D)
+                               layer |= ((View3D *)sa->spacedata.first)->lay;
                }
                }
+               return layer;
        }
        }
-       return is_inside;
+       return 0;
 }
 
 
 }
 
 
-/* finish operation */
-static void join_areas_exit(bContext *C, wmOperator *op)
+/* results in fully updated anim system */
+void ED_update_for_newframe(const bContext *C, int mute)
 {
 {
-       if (op->customdata) {
-               MEM_freeN(op->customdata);
-               op->customdata = NULL;
-       }
-
-       /* this makes sure aligned edges will result in aligned grabbing */
-       removedouble_scredges(C->screen);
-       removenotused_scredges(C->screen);
-       removenotused_scrverts(C->screen);
-}
-
-static int join_areas_exec(bContext *C, wmOperator *op)
-{
-       if(!join_areas_init(C, op)) 
-               return OPERATOR_CANCELLED;
+       bScreen *screen= CTX_wm_screen(C);
+       Scene *scene= screen->scene;
        
        
-       join_areas_apply(C, op);
-       join_areas_exit(C, op);
-
-       return OPERATOR_FINISHED;
-}
-
-/* interaction callback */
-static int join_areas_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
-       OP_verify_int(op, "x", event->x, NULL);
-       OP_verify_int(op, "y", event->y, NULL);
-
-       if(!join_areas_init(C, op)) 
-               return OPERATOR_PASS_THROUGH;
+       //extern void audiostream_scrub(unsigned int frame);    /* seqaudio.c */
        
        
-       /* add temp handler */
-       WM_event_add_modal_handler(&C->window->handlers, op);
+       /* this function applies the changes too */
+       /* XXX future: do all windows */
+       scene_update_for_newframe(scene, ED_screen_view3d_layers(screen)); /* BKE_scene.h */
        
        
-       return OPERATOR_RUNNING_MODAL;
-}
-
-static int join_areas_cancel(bContext *C, wmOperator *op)
-{
-       sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
-
-       if (jd->sa1) {
-               jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
-               jd->sa1->flag &= ~AREA_FLAG_DRAWJOINTO;
-       }
-       if (jd->sa2) {
-               jd->sa2->flag &= ~AREA_FLAG_DRAWJOINFROM;
-               jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
-       }
-
-       WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
-       WM_event_remove_modal_handler(&C->window->handlers, op);                        
-       OP_set_int(op, "delta", 0);
-       join_areas_exit(C, op);
-
-       return OPERATOR_CANCELLED;
-}
-
-/* modal callback while selecting area (space) that will be removed */
-static int join_areas_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
-       /* execute the events */
-       switch(event->type) {
-                       
-               case MOUSEMOVE:
-                       {
-                               sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
-                               ScrArea *sa = screen_areahascursor(C->screen, event->x, event->y);
-                               if (sa) {                                       
-                                       if (jd->sa1 != sa) {
-                                               jd->dir = area_getorientation(C->screen, jd->sa1, sa);
-                                               if (jd->dir >= 0)
-                                               {
-                                                       if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
-                                                       jd->sa2 = sa;
-                                                       jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
-                                               } else {
-                                                       /* we are not bordering on the previously selected area 
-                                                          we check if area has common border with the one marked for removal
-                                                          in this case we can swap areas.
-                                                       */
-                                                       jd->dir = area_getorientation(C->screen, sa, jd->sa2);
-                                                       if (jd->dir >= 0) {
-                                                               if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
-                                                               if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
-                                                               jd->sa1 = jd->sa2;
-                                                               jd->sa2 = sa;
-                                                               if (jd->sa1) jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
-                                                               if (jd->sa2) jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
-                                                       } else {
-                                                               if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
-                                                               jd->sa2 = NULL;
-                                                       }
-                                               }
-                                               WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
-                                       } else {
-                                               /* we are back in the area previously selected for keeping 
-                                                * we swap the areas if possible to allow user to choose */
-                                               if (jd->sa2 != NULL) {
-                                                       if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM;
-                                                       if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
-                                                       jd->sa1 = jd->sa2;
-                                                       jd->sa2 = sa;
-                                                       if (jd->sa1) jd->sa1->flag |= AREA_FLAG_DRAWJOINFROM;
-                                                       if (jd->sa2) jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
-                                                       jd->dir = area_getorientation(C->screen, jd->sa1, jd->sa2);
-                                                       if (jd->dir < 0)
-                                                       {
-                                                               printf("oops, didn't expect that!\n");
-                                                       }
-                                               } else {
-                                                       jd->dir = area_getorientation(C->screen, jd->sa1, sa);
-                                                       if (jd->dir >= 0)
-                                                       {
-                                                               if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO;
-                                                               jd->sa2 = sa;
-                                                               jd->sa2->flag |= AREA_FLAG_DRAWJOINTO;
-                                                       }
-                                               }
-                                               WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_WINDOW_REDRAW, 0, NULL);
-                                       }
-                               }
-                               
-                               break;
-                       }
-               case RIGHTMOUSE:
-                       if(event->val==0) {
-                               join_areas_apply(C, op);
-                               WM_event_add_notifier(C->wm, C->window, 0, WM_NOTE_SCREEN_CHANGED, 0, NULL);
-                               join_areas_exit(C, op);
-                               WM_event_remove_modal_handler(&C->window->handlers, op);
-                               return OPERATOR_FINISHED;
+       //if ( (CFRA>1) && (!mute) && (scene->audio.flag & AUDIO_SCRUB)) 
+       //      audiostream_scrub( CFRA );
+       
+       /* 3d window, preview */
+       //BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
+       
+       /* all movie/sequence images */
+       //BIF_image_update_frame();
+       
+       /* composite */
+       if(scene->use_nodes && scene->nodetree)
+               ntreeCompositTagAnimated(scene->nodetree);
+       
+       /* update animated texture nodes */
+       {
+               Tex *tex;
+               for(tex= CTX_data_main(C)->tex.first; tex; tex= tex->id.next)
+                       if( tex->use_nodes && tex->nodetree ) {
+                               ntreeTexTagAnimated( tex->nodetree );
                        }
                        }
-                       break;
-                       
-               case ESCKEY:
-                       return join_areas_cancel(C, op);
        }
        }
-
-       return OPERATOR_RUNNING_MODAL;
 }
 
 }
 
-/* Operator for joining two areas (space types) */
-void ED_SCR_OT_join_areas(wmOperatorType *ot)
-{
-       /* identifiers */
-       ot->name= "Join area";
-       ot->idname= "ED_SCR_OT_join_areas";
-       
-       /* api callbacks */
-       ot->exec= join_areas_exec;
-       ot->invoke= join_areas_invoke;
-       ot->cancel= join_areas_cancel;
-       ot->modal= join_areas_modal;
-
-       ot->poll= ED_operator_screenactive;
-}