2.5 audio cleanup:
[blender.git] / source / blender / editors / screen / screen_edit.c
index 2cf480dc204ca067f2d5807e9f1b3ab2685323bc..5519b2609a1494dda08edc354fee7278d5fcafa9 100644 (file)
 #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 "BKE_context.h"
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
+#include "BKE_node.h"
 #include "BKE_screen.h"
+#include "BKE_scene.h"
 #include "BKE_utildefines.h"
 
 #include "BIF_gl.h"
@@ -47,6 +54,7 @@
 #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 */
@@ -397,16 +405,15 @@ ScrArea *area_split(wmWindow *win, bScreen *sc, ScrArea *sa, char dir, float fac
 
 /* empty screen, with 1 dummy area without spacedata */
 /* uses window size */
-bScreen *screen_add(wmWindow *win, char *name)
+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);
-       sc->scene= G.scene;
+       sc->scene= scene;
        sc->do_refresh= 1;
-       
-       win->screen= sc;
+       sc->winid= win->winid;
        
        sv1= screen_addvert(sc, 0, 0);
        sv2= screen_addvert(sc, 0, win->sizey-1);
@@ -419,7 +426,7 @@ bScreen *screen_add(wmWindow *win, char *name)
        screen_addedge(sc, sv4, sv1);
        
        /* dummy type, no spacedata */
-       screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_INFO);
+       screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_EMPTY);
                
        return sc;
 }
@@ -457,11 +464,8 @@ static void screen_copy(bScreen *to, bScreen *from)
                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->scriptlink.totscript= 0;
                
                area_copy_data(sa, saf, 0);
        }
@@ -864,32 +868,49 @@ static void scrarea_draw_shape_light(ScrArea *sa, char dir)
        glDisable(GL_BLEND);
 }
 
-/** screen edges drawing **/
-static void drawscredge_area(ScrArea *sa)
+static void drawscredge_area_draw(int sizex, int sizey, short x1, short y1, short x2, short y2, short a) 
 {
-       short x1= sa->v1->vec.x;
-       short y1= sa->v1->vec.y;
-       short x2= sa->v3->vec.x;
-       short y2= sa->v3->vec.y;
-       
-       cpack(0x0);
-       
        /* right border area */
-       sdrawline(x2, y1, x2, y2);
+       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, y1, x1, y2);
-       }
+       if(x1>0)  /* otherwise it draws the emboss of window over */
+               sdrawline(x1+a, y1, x1+a, y2);
        
        /* top border area */
-       sdrawline(x1, y2, x2, y2);
+       if(y2<sizey-1)
+               sdrawline(x1, y2+a, x2, y2+a);
        
        /* bottom border area */
-       sdrawline(x1, y1, x2, y1);
+       if(y1>0)
+               sdrawline(x1, y1+a, x2, y1+a);
        
 }
 
+/** screen edges drawing **/
+static void drawscredge_area(ScrArea *sa, int sizex, int sizey, int center)
+{
+       short x1= sa->v1->vec.x;
+       short y1= sa->v1->vec.y;
+       short x2= sa->v3->vec.x;
+       short y2= sa->v3->vec.y;
+       short a, rt;
+       
+       rt= CLAMPIS(G.rt, 0, 16);
+       
+       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)
@@ -899,32 +920,61 @@ bScreen *ED_screen_duplicate(wmWindow *win, bScreen *sc)
        if(sc->full != SCREENNORMAL) return NULL; /* XXX handle this case! */
        
        /* make new empty screen: */
-       newsc= screen_add(win, sc->id.name+2);
+       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;
+       
+       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;
+                       }
+               }
+       }
+}
 
 void ED_screen_do_listen(wmWindow *win, wmNotifier *note)
 {
        
        /* generic notes */
-       switch(note->type) {
-               case WM_NOTE_WINDOW_REDRAW:
-                       win->screen->do_draw= 1;
+       switch(note->category) {
+               case NC_WM:
+                       if(note->data==ND_FILEREAD)
+                               win->screen->do_draw= 1;
                        break;
-               case WM_NOTE_SCREEN_CHANGED:
-                       win->screen->do_draw= win->screen->do_refresh= 1;
+               case NC_WINDOW:
+                       win->screen->do_draw= 1;
                        break;
-               case WM_NOTE_GESTURE_REDRAW:
-                       win->screen->do_gesture= 1;     /* XXX gestures are stored in window, draw per region... a bit weak? wait for proper composite? (ton) */
+               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;
        }
 }
 
-
+/* only for edge lines between areas, and the blended join arrows */
 void ED_screen_draw(wmWindow *win)
 {
        ScrArea *sa;
@@ -933,14 +983,16 @@ void ED_screen_draw(wmWindow *win)
        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;
-               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);
@@ -968,7 +1020,7 @@ void ED_screen_draw(wmWindow *win)
                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;
 }
 
@@ -992,11 +1044,14 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
                ED_area_initialize(wm, win, sa);
        }
 
+       /* 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;
 
-       /* cursor types too */
-       ED_screen_set_subwinactive(win);
+       win->screen->context= ed_screen_context;
 }
 
 /* file read, set all screens, ... */
@@ -1013,79 +1068,116 @@ void ED_screens_initialize(wmWindowManager *wm)
        }
 }
 
+
+/* *********** exit calls are for closing running stuff ******** */
+
 void ED_region_exit(bContext *C, ARegion *ar)
 {
-       ARegion *prevar= C->region;
+       ARegion *prevar= CTX_wm_region(C);
 
-       C->region= ar;
+       CTX_wm_region_set(C, ar);
        WM_event_remove_handlers(C, &ar->handlers);
-       C->region= prevar;
+       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)
 {
-       ScrArea *prevsa= C->area;
+       ScrArea *prevsa= CTX_wm_area(C);
        ARegion *ar;
 
-       C->area= sa;
+       CTX_wm_area_set(C, sa);
        for(ar= sa->regionbase.first; ar; ar= ar->next)
                ED_region_exit(C, ar);
 
        WM_event_remove_handlers(C, &sa->handlers);
-       C->area= prevsa;
+       CTX_wm_area_set(C, prevsa);
 }
 
 void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
 {
-       wmWindow *prevwin= C?C->window:NULL;
+       wmWindow *prevwin= CTX_wm_window(C);
        ScrArea *sa;
        ARegion *ar;
 
-       C->window= window;
+       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);
 
-       WM_event_remove_handlers(C, &window->handlers);
-       C->window= prevwin;
+       /* mark it available for use for other windows */
+       screen->winid= 0;
+       
+       CTX_wm_window_set(C, prevwin);
 }
 
-/* case when on area-edge or in azones */
+/* *********************************** */
+
+/* case when on area-edge or in azones, or outside window */
 static void screen_cursor_set(wmWindow *win, wmEvent *event)
 {
+       AZone *az= NULL;
        ScrArea *sa;
        
        for(sa= win->screen->areabase.first; sa; sa= sa->next)
-               if(is_in_area_actionzone(sa, event->x, event->y))
+               if((az=is_in_area_actionzone(sa, event->x, event->y)))
                        break;
        
        if(sa) {
-               WM_cursor_set(win, CURSOR_EDIT);
+               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 && scredge_is_horizontal(actedge)) {
-                       WM_cursor_set(win, CURSOR_Y_MOVE);
-               } else {
-                       WM_cursor_set(win, CURSOR_X_MOVE);
+               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) {
-               wmEvent *event= win->eventstate;
+               bScreen *scr= win->screen;
                ScrArea *sa;
                ARegion *ar;
-               int oldswin= win->screen->subwinactive;
-               
-               for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+               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(NULL==is_in_area_actionzone(sa, event->x, event->y))
@@ -1094,59 +1186,355 @@ void ED_screen_set_subwinactive(wmWindow *win)
                if(sa) {
                        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
-                       win->screen->subwinactive= win->screen->mainwin;
+                       scr->subwinactive= scr->mainwin;
                
                /* check for redraw headers */
-               if(oldswin!=win->screen->subwinactive) {
+               if(oldswin!=scr->subwinactive) {
 
-                       for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+                       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==win->screen->subwinactive)
+                                       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)
-                                                       ar->do_draw= 1; /* XXX */
+                                                       ED_region_tag_redraw(ar);
                                }
                        }
                }
                
                /* cursors, for time being set always on edges, otherwise aregion doesnt switch */
-               if(win->screen->subwinactive==win->screen->mainwin) {
+               if(scr->subwinactive==scr->mainwin) {
                        screen_cursor_set(win, event);
                }
-               else if(oldswin!=win->screen->subwinactive) {
-                       /* cursor space type switching */
-                       for(sa= win->screen->areabase.first; sa; sa= sa->next) {
-                               for(ar= sa->regionbase.first; ar; ar= ar->next) {
-                                       if(ar->swinid==win->screen->subwinactive) {
-                                               if(sa->type->cursor)
-                                                       sa->type->cursor(win, ar);
-                                               else 
-                                                       WM_cursor_set(win, CURSOR_STD);
-                                       }
-                               }
-                                       
-                       }
+               else if(oldswin!=scr->subwinactive) {
+                       region_cursor_set(win, scr->subwinactive);
                }
        }
 }
 
 int ED_screen_area_active(const bContext *C)
 {
+       bScreen *sc= CTX_wm_screen(C);
+       ScrArea *sa= CTX_wm_area(C);
 
-       if(C->screen && C->area) {
+       if(sc && sa) {
                ARegion *ar;
-               for(ar= C->area->regionbase.first; ar; ar= ar->next)
-                       if(ar->swinid == C->screen->subwinactive)
+               for(ar= sa->regionbase.first; ar; ar= ar->next)
+                       if(ar->swinid == sc->subwinactive)
                                return 1;
        }       
        return 0;
 }
+
+/* operator call, WM + Window + screen already existed before */
+/* Do NOT call in area/region queues! */
+void ED_screen_set(bContext *C, bScreen *sc)
+{
+       wmWindow *win= CTX_wm_window(C);
+       bScreen *oldscreen= CTX_wm_screen(C);
+       ID *id;
+       
+       /* 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;
+                       }
+               }
+       }
+       
+       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);
+       }
+}
+
+/* only call outside of area/region loops */
+void ED_screen_set_scene(bContext *C, Scene *scene)
+{
+       bScreen *sc;
+       bScreen *curscreen= CTX_wm_screen(C);
+       
+       for(sc= CTX_data_main(C)->screen.first; sc; sc= sc->id.next) {
+               if((U.flag & USER_SCENEGLOBAL) || sc==curscreen) {
+                       
+                       if(scene != sc->scene) {
+                               /* all areas endlocalview */
+                       // XXX  ScrArea *sa= sc->areabase.first;
+                       //      while(sa) {
+                       //              endlocalview(sa);
+                       //              sa= sa->next;
+                       //      }               
+                               sc->scene= scene;
+                       }
+                       
+               }
+       }
+       
+       //  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;
+                       }
+               }
+       }
+       
+       CTX_data_scene_set(C, scene);
+       set_scene_bg(scene);
+       
+       ED_update_for_newframe(C, 1);
+       
+       /* complete redraw */
+       WM_event_add_notifier(C, NC_WINDOW, NULL);
+       
+}
+
+/* this function toggles: if area is full then the parent will be restored */
+void ed_screen_fullarea(bContext *C, ScrArea *sa)
+{
+       bScreen *sc, *oldscreen;
+       
+       if(sa==NULL) {
+               return;
+       }
+       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 {
+               ScrArea *newa;
+               
+               oldscreen= CTX_wm_screen(C);
+
+               /* 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);
+
+               /* copy area */
+               newa= newa->prev;
+               area_copy_data(newa, sa, 1);    /* 1 = swap spacelist */
+
+               sa->full= oldscreen;
+               newa->full= oldscreen;
+               newa->next->full= oldscreen; // XXX
+
+               ED_screen_set(C, sc);
+       }
+
+       /* XXX bad code: setscreen() ends with first area active. fullscreen render assumes this too */
+       CTX_wm_area_set(C, sc->areabase.first);
+
+       /* XXX retopo_force_update(); */
+
+}
+
+int ED_screen_full_newspace(bContext *C, ScrArea *sa, int type)
+{
+       if(sa==NULL)
+               return 0;
+       
+       if(sa->full==0)
+               ed_screen_fullarea(C, sa);
+
+       /* CTX_wm_area(C) is new area */
+       ED_area_newspace(C, CTX_wm_area(C), type);
+       
+       return 1;
+}
+
+void ED_screen_full_prevspace(bContext *C)
+{
+       ScrArea *sa= CTX_wm_area(C);
+       
+       ED_area_prevspace(C);
+       
+       if(sa->full)
+               ed_screen_fullarea(C, sa);
+}
+
+/* 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)
+{
+       bScreen *screen= CTX_wm_screen(C);
+       wmWindow *win= CTX_wm_window(C);
+       Scene *scene= CTX_data_scene(C);
+       
+       if(screen->animtimer)
+               WM_event_remove_window_timer(win, screen->animtimer);
+       screen->animtimer= 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;
+               
+       }
+       /* notifier catched by top header, for button */
+       WM_event_add_notifier(C, NC_SCREEN|ND_ANIMPLAY, screen);
+}
+
+unsigned int ED_screen_view3d_layers(bScreen *screen)
+{
+       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 0;
+}
+
+
+/* results in fully updated anim system */
+void ED_update_for_newframe(const bContext *C, int mute)
+{
+       bScreen *screen= CTX_wm_screen(C);
+       Scene *scene= screen->scene;
+       
+       //extern void audiostream_scrub(unsigned int frame);    /* seqaudio.c */
+       
+       /* this function applies the changes too */
+       /* XXX future: do all windows */
+       scene_update_for_newframe(scene, ED_screen_view3d_layers(screen)); /* BKE_scene.h */
+       
+       //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 );
+                       }
+       }
+}
+
+