Sequencer: switching to preview mode works fine again
[blender.git] / source / blender / editors / space_sequencer / space_sequencer.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/editors/space_sequencer/space_sequencer.c
30  *  \ingroup spseq
31  */
32
33
34 #include <string.h>
35 #include <stdio.h>
36
37 #include "DNA_scene_types.h"
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_math.h"
43 #include "BLI_path_util.h"
44 #include "BLI_utildefines.h"
45
46 #include "BKE_context.h"
47 #include "BKE_screen.h"
48 #include "BKE_sequencer.h"
49 #include "BKE_global.h"
50
51 #include "ED_space_api.h"
52 #include "ED_sequencer.h"
53 #include "ED_screen.h"
54 #include "ED_view3d.h" /* only for sequencer view3d drawing callback */
55
56 #include "WM_api.h"
57 #include "WM_types.h"
58
59 #include "UI_resources.h"
60 #include "UI_view2d.h"
61
62 #include "sequencer_intern.h"   // own include
63
64 /* ******************** manage regions ********************* */
65
66 ARegion *sequencer_has_buttons_region(ScrArea *sa)
67 {
68         ARegion *ar, *arnew;
69
70         ar= BKE_area_find_region_type(sa, RGN_TYPE_UI);
71         if(ar) return ar;
72         
73         /* add subdiv level; after header */
74         ar= BKE_area_find_region_type(sa, RGN_TYPE_HEADER);
75
76         /* is error! */
77         if(ar==NULL) return NULL;
78         
79         arnew= MEM_callocN(sizeof(ARegion), "buttons for sequencer");
80         
81         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
82         arnew->regiontype= RGN_TYPE_UI;
83         arnew->alignment= RGN_ALIGN_RIGHT;
84         
85         arnew->flag = RGN_FLAG_HIDDEN;
86         
87         return arnew;
88 }
89
90 static ARegion *sequencer_find_region(ScrArea *sa, short type)
91 {
92         ARegion *ar=NULL;
93         
94         for(ar= sa->regionbase.first; ar; ar= ar->next)
95                 if(ar->regiontype==type)
96                         return ar;
97
98         return ar;
99 }
100
101 /* ******************** default callbacks for sequencer space ***************** */
102
103 static SpaceLink *sequencer_new(const bContext *C)
104 {
105         Scene *scene= CTX_data_scene(C);
106         ARegion *ar;
107         SpaceSeq *sseq;
108         
109         sseq= MEM_callocN(sizeof(SpaceSeq), "initsequencer");
110         sseq->spacetype= SPACE_SEQ;
111         sseq->zoom= 4;
112         sseq->chanshown = 0;
113         sseq->view = SEQ_VIEW_SEQUENCE;
114         sseq->mainb = SEQ_DRAW_IMG_IMBUF;
115         /* header */
116         ar= MEM_callocN(sizeof(ARegion), "header for sequencer");
117         
118         BLI_addtail(&sseq->regionbase, ar);
119         ar->regiontype= RGN_TYPE_HEADER;
120         ar->alignment= RGN_ALIGN_BOTTOM;
121         
122         /* buttons/list view */
123         ar= MEM_callocN(sizeof(ARegion), "buttons for sequencer");
124         
125         BLI_addtail(&sseq->regionbase, ar);
126         ar->regiontype= RGN_TYPE_UI;
127         ar->alignment= RGN_ALIGN_RIGHT;
128         ar->flag = RGN_FLAG_HIDDEN;
129         
130         /* preview area */
131         /* NOTE: if you change values here, also change them in sequencer_init_preview_region */
132         ar= MEM_callocN(sizeof(ARegion), "preview area for sequencer");
133         BLI_addtail(&sseq->regionbase, ar);
134         ar->regiontype= RGN_TYPE_PREVIEW;
135         ar->alignment= RGN_ALIGN_TOP;
136         ar->flag |= RGN_FLAG_HIDDEN;
137         /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
138         ar->v2d.keepzoom= V2D_KEEPASPECT | V2D_KEEPZOOM;
139         ar->v2d.minzoom= 0.00001f;
140         ar->v2d.maxzoom= 100000.0f;
141         ar->v2d.tot.xmin= -960.0f; /* 1920 width centered */
142         ar->v2d.tot.ymin= -540.0f; /* 1080 height centered */
143         ar->v2d.tot.xmax= 960.0f;
144         ar->v2d.tot.ymax= 540.0f;
145         ar->v2d.min[0]= 0.0f;
146         ar->v2d.min[1]= 0.0f;
147         ar->v2d.max[0]= 12000.0f;
148         ar->v2d.max[1]= 12000.0f;
149         ar->v2d.cur= ar->v2d.tot;
150         ar->v2d.align= V2D_ALIGN_FREE; 
151         ar->v2d.keeptot= V2D_KEEPTOT_FREE;
152
153
154         /* main area */
155         ar= MEM_callocN(sizeof(ARegion), "main area for sequencer");
156         
157         BLI_addtail(&sseq->regionbase, ar);
158         ar->regiontype= RGN_TYPE_WINDOW;
159         
160         
161         /* seq space goes from (0,8) to (0, efra) */
162         
163         ar->v2d.tot.xmin= 0.0f;
164         ar->v2d.tot.ymin= 0.0f;
165         ar->v2d.tot.xmax= scene->r.efra;
166         ar->v2d.tot.ymax= 8.0f;
167         
168         ar->v2d.cur= ar->v2d.tot;
169         
170         ar->v2d.min[0]= 10.0f;
171         ar->v2d.min[1]= 0.5f;
172         
173         ar->v2d.max[0]= MAXFRAMEF;
174         ar->v2d.max[1]= MAXSEQ;
175         
176         ar->v2d.minzoom= 0.01f;
177         ar->v2d.maxzoom= 100.0f;
178         
179         ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
180         ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL);
181         ar->v2d.keepzoom= 0;
182         ar->v2d.keeptot= 0;
183         ar->v2d.align= V2D_ALIGN_NO_NEG_Y;
184
185         return (SpaceLink *)sseq;
186 }
187
188 /* not spacelink itself */
189 static void sequencer_free(SpaceLink *UNUSED(sl))
190 {       
191 //      SpaceSeq *sseq= (SpaceSequencer*) sl;
192         
193 // XXX  if(sseq->gpd) free_gpencil_data(sseq->gpd);
194
195 }
196
197
198 /* spacetype; init callback */
199 static void sequencer_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
200 {
201         
202 }
203
204 static void sequencer_refresh(const bContext *C, ScrArea *sa)
205 {
206         wmWindowManager *wm= CTX_wm_manager(C);
207         wmWindow *window= CTX_wm_window(C);
208         SpaceSeq *sseq= (SpaceSeq *)sa->spacedata.first;
209         ARegion *ar_main= sequencer_find_region(sa, RGN_TYPE_WINDOW);
210         ARegion *ar_preview= sequencer_find_region(sa, RGN_TYPE_PREVIEW);
211         int view_changed= 0;
212
213         switch (sseq->view) {
214                 case SEQ_VIEW_SEQUENCE:
215                         if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) {
216                                 ar_main->flag &= ~RGN_FLAG_HIDDEN;
217                                 ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
218                                 view_changed= 1;
219                         }
220                         if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) {
221                                 ar_preview->flag |= RGN_FLAG_HIDDEN;
222                                 ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
223                                 WM_event_remove_handlers((bContext*)C, &ar_preview->handlers);
224                                 view_changed= 1;
225                         }
226                         if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
227                                 ar_main->alignment= RGN_ALIGN_NONE;
228                                 view_changed= 1;
229                         }
230                         if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) {
231                                 ar_preview->alignment= RGN_ALIGN_NONE;
232                                 view_changed= 1;
233                         }
234                         break;
235                 case SEQ_VIEW_PREVIEW:
236                         if (ar_main && !(ar_main->flag & RGN_FLAG_HIDDEN)) {
237                                 ar_main->flag |= RGN_FLAG_HIDDEN;
238                                 ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
239                                 WM_event_remove_handlers((bContext*)C, &ar_main->handlers);
240                                 view_changed= 1;
241                         }
242                         if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) {
243                                 ar_preview->flag &= ~RGN_FLAG_HIDDEN;
244                                 ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
245                                 ar_preview->v2d.cur = ar_preview->v2d.tot;
246                                 view_changed= 1;
247                         }
248                         if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
249                                 ar_main->alignment= RGN_ALIGN_NONE;
250                                 view_changed= 1;
251                         }
252                         if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) {
253                                 ar_preview->alignment= RGN_ALIGN_NONE;
254                                 view_changed= 1;
255                         }
256                         break;
257                 case SEQ_VIEW_SEQUENCE_PREVIEW:
258                         if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) {
259                                 ar_main->flag &= ~RGN_FLAG_HIDDEN;
260                                 ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
261                                 view_changed= 1;
262                         }
263                         if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) {
264                                 ar_preview->flag &= ~RGN_FLAG_HIDDEN;
265                                 ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
266                                 ar_preview->v2d.cur = ar_preview->v2d.tot;
267                                 view_changed= 1;
268                         }
269                         if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
270                                 ar_main->alignment= RGN_ALIGN_NONE;
271                                 view_changed= 1;
272                         }
273                         if (ar_preview && ar_preview->alignment != RGN_ALIGN_TOP) {
274                                 ar_preview->alignment= RGN_ALIGN_TOP;
275                                 view_changed= 1;
276                         }
277                         break;
278         }
279
280         if(view_changed) {
281                 ED_area_initialize(wm, window, sa);
282                 ED_area_tag_redraw(sa);
283         }
284 }
285
286 static SpaceLink *sequencer_duplicate(SpaceLink *sl)
287 {
288         SpaceSeq *sseqn= MEM_dupallocN(sl);
289         
290         /* clear or remove stuff from old */
291 // XXX  sseq->gpd= gpencil_data_duplicate(sseq->gpd);
292
293         return (SpaceLink *)sseqn;
294 }
295
296
297
298 /* *********************** sequencer (main) region ************************ */
299 /* add handlers, stuff you only do once or on area/region changes */
300 static void sequencer_main_area_init(wmWindowManager *wm, ARegion *ar)
301 {
302         wmKeyMap *keymap;
303         ListBase *lb;
304         
305         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
306         
307         keymap= WM_keymap_find(wm->defaultconf, "SequencerCommon", SPACE_SEQ, 0);
308         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
309         
310         /* own keymap */
311         keymap= WM_keymap_find(wm->defaultconf, "Sequencer", SPACE_SEQ, 0);
312         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
313         
314         /* add drop boxes */
315         lb= WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW);
316         
317         WM_event_add_dropbox_handler(&ar->handlers, lb);
318         
319 }
320
321 static void sequencer_main_area_draw(const bContext *C, ARegion *ar)
322 {
323 //      ScrArea *sa= CTX_wm_area(C);
324         
325         /* NLE - strip editing timeline interface */
326         draw_timeline_seq(C, ar);
327 }
328
329 /* ************* dropboxes ************* */
330
331 static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
332 {
333         if(drag->type==WM_DRAG_PATH)
334                 if(ELEM(drag->icon, ICON_FILE_IMAGE, ICON_FILE_BLANK))  /* rule might not work? */
335                         return 1;
336         return 0;
337 }
338
339 static int movie_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
340 {
341         if(drag->type==WM_DRAG_PATH)
342                 if(ELEM3(drag->icon, 0, ICON_FILE_MOVIE, ICON_FILE_BLANK))      /* rule might not work? */
343                         return 1;
344         return 0;
345 }
346
347 static int sound_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
348 {
349         if(drag->type==WM_DRAG_PATH)
350                 if(ELEM(drag->icon, ICON_FILE_SOUND, ICON_FILE_BLANK))  /* rule might not work? */
351                         return 1;
352         return 0;
353 }
354
355 static void sequencer_drop_copy(wmDrag *drag, wmDropBox *drop)
356 {
357         /* copy drag path to properties */
358         if(RNA_struct_find_property(drop->ptr, "filepath"))
359                 RNA_string_set(drop->ptr, "filepath", drag->path);
360
361         if(RNA_struct_find_property(drop->ptr, "directory")) {
362                 PointerRNA itemptr;
363                 char dir[FILE_MAX], file[FILE_MAX];
364
365                 BLI_split_dirfile(drag->path, dir, file);
366                 
367                 RNA_string_set(drop->ptr, "directory", dir);
368
369                 RNA_collection_clear(drop->ptr, "files");
370                 RNA_collection_add(drop->ptr, "files", &itemptr);
371                 RNA_string_set(&itemptr, "name", file);
372         }
373 }
374
375 /* this region dropbox definition */
376 static void sequencer_dropboxes(void)
377 {
378         ListBase *lb= WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW);
379         
380         WM_dropbox_add(lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy);
381         WM_dropbox_add(lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy);
382         WM_dropbox_add(lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy);
383 }
384
385 /* ************* end drop *********** */
386
387 /* add handlers, stuff you only do once or on area/region changes */
388 static void sequencer_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
389 {
390         ED_region_header_init(ar);
391 }
392
393 static void sequencer_header_area_draw(const bContext *C, ARegion *ar)
394 {
395         ED_region_header(C, ar);
396 }
397
398 static void sequencer_main_area_listener(ARegion *ar, wmNotifier *wmn)
399 {
400         /* context changes */
401         switch(wmn->category) {
402                 case NC_SCENE:
403                         switch(wmn->data) {
404                                 case ND_FRAME:
405                                 case ND_FRAME_RANGE:
406                                 case ND_MARKERS:
407                                 case ND_RENDER_OPTIONS: /* for FPS and FPS Base */
408                                 case ND_SEQUENCER:
409                                         ED_region_tag_redraw(ar);
410                                         break;
411                         }
412                         break;
413                 case NC_SPACE:
414                         if(wmn->data == ND_SPACE_SEQUENCER)
415                                 ED_region_tag_redraw(ar);
416                         break;
417                 case NC_ID:
418                         if(wmn->action == NA_RENAME)
419                                 ED_region_tag_redraw(ar);
420                         break;
421         }
422 }
423
424 /* *********************** preview region ************************ */
425 static void sequencer_preview_area_init(wmWindowManager *wm, ARegion *ar)
426 {
427         wmKeyMap *keymap;
428
429         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
430         
431         keymap= WM_keymap_find(wm->defaultconf, "SequencerCommon", SPACE_SEQ, 0);
432         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
433
434         /* own keymap */
435         keymap= WM_keymap_find(wm->defaultconf, "SequencerPreview", SPACE_SEQ, 0);
436         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
437 }
438
439 static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
440 {
441         ScrArea *sa= CTX_wm_area(C);
442         SpaceSeq *sseq= sa->spacedata.first;
443         Scene *scene= CTX_data_scene(C);
444         
445         /* XXX temp fix for wrong setting in sseq->mainb */
446         if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF;
447
448         draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0);
449
450         if(scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
451                 int over_cfra;
452
453                 if(scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS)
454                         over_cfra= scene->ed->over_cfra;
455                 else
456                         over_cfra= scene->r.cfra + scene->ed->over_ofs;
457
458                 if(over_cfra != scene->r.cfra)
459                         draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra);
460         }
461
462 }
463
464 static void sequencer_preview_area_listener(ARegion *ar, wmNotifier *wmn)
465 {
466         /* context changes */
467         switch(wmn->category) {
468                 case NC_SCENE:
469                         switch(wmn->data) {
470                                 case ND_FRAME:
471                                 case ND_MARKERS:
472                                 case ND_SEQUENCER:
473                                         ED_region_tag_redraw(ar);
474                                         break;
475                         }
476                         break;
477                 case NC_SPACE:
478                         if(wmn->data == ND_SPACE_SEQUENCER)
479                                 ED_region_tag_redraw(ar);
480                         break;
481                 case NC_ID:
482                         switch(wmn->data) {
483                                 case NA_RENAME:
484                                         ED_region_tag_redraw(ar);
485                                         break;
486                         }
487                         break;
488         }
489 }
490
491 /* *********************** buttons region ************************ */
492
493 /* add handlers, stuff you only do once or on area/region changes */
494 static void sequencer_buttons_area_init(wmWindowManager *wm, ARegion *ar)
495 {
496         
497         ED_region_panels_init(wm, ar);
498         
499 }
500
501 static void sequencer_buttons_area_draw(const bContext *C, ARegion *ar)
502 {
503         ED_region_panels(C, ar, 1, NULL, -1);
504 }
505
506 static void sequencer_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
507 {
508         /* context changes */
509         switch(wmn->category) {
510                 case NC_SCENE:
511                 switch(wmn->data) {
512                         case ND_FRAME:
513                         case ND_SEQUENCER:
514                                 ED_region_tag_redraw(ar);
515                                 break;
516                 }
517                 break;
518                 case NC_SPACE:
519                         if(wmn->data == ND_SPACE_SEQUENCER)
520                                 ED_region_tag_redraw(ar);
521                         break;
522                 case NC_ID:
523                         if(wmn->action == NA_RENAME)
524                                 ED_region_tag_redraw(ar);
525                         break;
526         }
527 }
528 /* ************************************* */
529
530 /* only called once, from space/spacetypes.c */
531 void ED_spacetype_sequencer(void)
532 {
533         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype sequencer");
534         ARegionType *art;
535         
536         st->spaceid= SPACE_SEQ;
537         strncpy(st->name, "Sequencer", BKE_ST_MAXNAME);
538         
539         st->new= sequencer_new;
540         st->free= sequencer_free;
541         st->init= sequencer_init;
542         st->duplicate= sequencer_duplicate;
543         st->operatortypes= sequencer_operatortypes;
544         st->keymap= sequencer_keymap;
545         st->dropboxes= sequencer_dropboxes;
546         st->refresh= sequencer_refresh;
547
548         /* regions: main window */
549         art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
550         art->regionid = RGN_TYPE_WINDOW;
551         art->init= sequencer_main_area_init;
552         art->draw= sequencer_main_area_draw;
553         art->listener= sequencer_main_area_listener;
554         art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_FRAMES|ED_KEYMAP_ANIMATION;
555
556         BLI_addhead(&st->regiontypes, art);
557
558         /* preview */
559         art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
560         art->regionid = RGN_TYPE_PREVIEW;
561         art->prefsizey = 240; // XXX
562         art->init= sequencer_preview_area_init;
563         art->draw= sequencer_preview_area_draw;
564         art->listener= sequencer_preview_area_listener;
565         art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_ANIMATION;
566         BLI_addhead(&st->regiontypes, art);
567         
568         /* regions: listview/buttons */
569         art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
570         art->regionid = RGN_TYPE_UI;
571         art->prefsizex= 220; // XXX
572         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
573         art->listener= sequencer_buttons_area_listener;
574         art->init= sequencer_buttons_area_init;
575         art->draw= sequencer_buttons_area_draw;
576         BLI_addhead(&st->regiontypes, art);
577         
578         /* Keep as python only for now
579         sequencer_buttons_register(art);
580         */
581
582         /* regions: header */
583         art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
584         art->regionid = RGN_TYPE_HEADER;
585         art->prefsizey= HEADERY;
586         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
587         
588         art->init= sequencer_header_area_init;
589         art->draw= sequencer_header_area_draw;
590         art->listener= sequencer_main_area_listener;
591         
592         BLI_addhead(&st->regiontypes, art);
593         
594         BKE_spacetype_register(st);
595
596         /* set the sequencer callback when not in background mode */
597         if(G.background==0) {
598                 sequencer_view3d_cb= ED_view3d_draw_offscreen_imbuf_simple;
599         }
600 }
601