Merged 15170:15635 from trunk (no conflicts or even merges)
[blender.git] / source / blender / python / api2_2x / sceneSequence.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * This is a new part of Blender.
22  *
23  * Contributor(s): Campbell Barton
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include "sceneSequence.h" /* This must come first */
29
30 #include "MEM_guardedalloc.h"
31
32 #include "DNA_sequence_types.h"
33 #include "DNA_scene_types.h" /* for Base */
34
35 #include "BKE_mesh.h"
36 #include "BKE_library.h"
37 #include "BKE_global.h"
38 #include "BKE_main.h"
39 #include "BKE_scene.h"
40
41 #include "BIF_editseq.h" /* get_last_seq */
42 #include "BLI_blenlib.h"
43 #include "BSE_sequence.h"
44 #include "Ipo.h"
45 #include "blendef.h"  /* CLAMP */
46 #include "BKE_utildefines.h"
47 #include "Scene.h"
48 #include "Sound.h"
49 #include "gen_utils.h"
50
51 enum seq_consts {
52         EXPP_SEQ_ATTR_TYPE = 0,
53         EXPP_SEQ_ATTR_CHAN,
54         EXPP_SEQ_ATTR_LENGTH,
55         EXPP_SEQ_ATTR_START,
56         EXPP_SEQ_ATTR_STARTOFS,
57         EXPP_SEQ_ATTR_ENDOFS,
58         EXPP_SEQ_ATTR_STARTSTILL,
59         EXPP_SEQ_ATTR_ENDSTILL
60 };
61
62
63 /*****************************************************************************/
64 /* Python API function prototypes for the Blender module.                */
65 /*****************************************************************************/
66 /*PyObject *M_Sequence_Get( PyObject * self, PyObject * args );*/
67
68 /*****************************************************************************/
69 /* Python method structure definition for Blender.Object module:         */
70 /*****************************************************************************/
71 /*struct PyMethodDef M_Sequence_methods[] = {
72         {"Get", ( PyCFunction ) M_Sequence_Get, METH_VARARGS,
73 "(name) - return the sequence with the name 'name',\
74 returns None if notfound.\nIf 'name' is not specified, it returns a list of all sequences."},
75         {NULL, NULL, 0, NULL}
76 };*/
77
78 /*****************************************************************************/
79 /* Python BPy_Sequence methods table:                                      */
80 /*****************************************************************************/
81 static PyObject *Sequence_copy( BPy_Sequence * self );
82 static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args );
83 static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args );
84 static PyObject *Sequence_rebuildProxy( BPy_Sequence * self );
85
86 static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args );
87 static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args );
88 static void intern_pos_update(Sequence * seq); 
89
90 static PyMethodDef BPy_Sequence_methods[] = {
91         /* name, method, flags, doc */
92         {"new", ( PyCFunction ) Sequence_new, METH_VARARGS,
93          "(data) - Return a new sequence."},
94         {"remove", ( PyCFunction ) Sequence_remove, METH_VARARGS,
95          "(data) - Remove a strip."},
96         {"__copy__", ( PyCFunction ) Sequence_copy, METH_NOARGS,
97          "() - Return a copy of the sequence containing the same objects."},
98         {"copy", ( PyCFunction ) Sequence_copy, METH_NOARGS,
99          "() - Return a copy of the sequence containing the same objects."},
100         {"rebuildProxy", ( PyCFunction ) Sequence_rebuildProxy, METH_VARARGS,
101          "() - Rebuild the active strip's Proxy."},
102         {NULL, NULL, 0, NULL}
103 };
104
105 static PyMethodDef BPy_SceneSeq_methods[] = {
106         /* name, method, flags, doc */
107         {"new", ( PyCFunction ) SceneSeq_new, METH_VARARGS,
108          "(data) - Return a new sequence."},
109         {"remove", ( PyCFunction ) SceneSeq_remove, METH_VARARGS,
110          "(data) - Remove a strip."},
111         {NULL, NULL, 0, NULL}
112 };
113
114 /* use to add a sequence to a scene or its listbase */
115 static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
116 {
117         PyObject *py_data = NULL;
118         
119         Sequence *seq;
120         int a;
121         Strip *strip;
122         StripElem *se;
123         int start, machine;
124         
125         if( !PyArg_ParseTuple( args, "Oii", &py_data, &start, &machine ) )
126                 return EXPP_ReturnPyObjError( PyExc_ValueError,
127                         "expect sequence data then 2 ints - (seqdata, start, track)" );
128         
129         seq = alloc_sequence(seqbase, start, machine); /* warning, this sets last */
130         
131         if (PyTuple_Check(py_data) && PyTuple_GET_SIZE(py_data) == 2) {
132                 /* Image */
133                 PyObject *list;
134                 char *name;
135                 
136                 if (!PyArg_ParseTuple( py_data, "sO!", &name, &PyList_Type, &list)) {
137                         BLI_remlink(seqbase, seq);
138                         MEM_freeN(seq);
139                         
140                         return EXPP_ReturnPyObjError( PyExc_ValueError,
141                                 "images data needs to be a tuple of a string and a list of images - (path, [filenames...])" );
142                 }
143                 
144                 seq->type= SEQ_IMAGE;
145                 
146                 seq->len = PyList_Size( list );
147                 
148                 
149                 /* strip and stripdata */
150                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
151                 strip->len= seq->len;
152                 strip->us= 1;
153                 strncpy(strip->dir, name, FILE_MAXDIR-1);
154                 strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
155
156                 for(a=0; a<seq->len; a++) {
157                         name = PyString_AsString(PyList_GetItem( list, a ));
158                         strncpy(se->name, name, FILE_MAXFILE-1);
159                         se++;
160                 }               
161         } else if (PyTuple_Check(py_data) && PyTuple_GET_SIZE(py_data) == 3) {
162                 float r,g,b;
163                 SolidColorVars *colvars;
164                 seq->effectdata = MEM_callocN(sizeof(struct SolidColorVars), "solidcolor");
165                 colvars = (SolidColorVars *)seq->effectdata;
166                 
167                 if (!PyArg_ParseTuple( py_data, "fff", &r, &g, &b)) {
168                         return EXPP_ReturnPyObjError( PyExc_ValueError,
169                                         "color needs to be a tuple of 3 floats - (r,g,b)" );
170                 }
171                 
172                 seq->type= SEQ_COLOR;
173                 
174                 CLAMP(r,0,1);
175                 CLAMP(g,0,1);
176                 CLAMP(b,0,1);
177                 
178                 colvars->col[0] = r;
179                 colvars->col[1] = b;
180                 colvars->col[2] = g;
181                 
182                 /* basic defaults */
183                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
184                 strip->len = seq->len = 1;
185                 strip->us= 1;
186                 strip->stripdata= se= MEM_callocN(seq->len*sizeof(StripElem), "stripelem");
187                 
188         } else if (BPy_Sound_Check(py_data)) {
189                 /* sound */
190                 int totframe;
191                 bSound *sound = (( BPy_Sound * )py_data)->sound;
192                 
193                 
194                 seq->type= SEQ_RAM_SOUND;
195                 seq->sound = sound;
196                 
197                 totframe= (int) ( ((float)(sound->streamlen-1)/( (float)sce->audio.mixrate*4.0 ))* (float)sce->r.frs_sec / sce->r.frs_sec_base);
198                 
199                 sound->flags |= SOUND_FLAGS_SEQUENCE;
200                 
201                 
202                 /* strip and stripdata */
203                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
204                 strip->len= totframe;
205                 strip->us= 1;
206                 strncpy(strip->dir, sound->name, FILE_MAXDIR-1);
207                 strip->stripdata= se= MEM_callocN(sizeof(StripElem), "stripelem");
208
209                 /* name sound in first strip */
210                 strncpy(se->name, sound->name, FILE_MAXFILE-1);
211                 
212         } else if (BPy_Scene_Check(py_data)) {
213                 /* scene */
214                 Scene *sce = ((BPy_Scene *)py_data)->scene;
215                 
216                 seq->type= SEQ_SCENE;
217                 seq->scene= sce;
218                 
219                 /*seq->sfra= sce->r.sfra;*/
220                 seq->len= sce->r.efra - sce->r.sfra + 1;
221
222                 seq->strip= strip= MEM_callocN(sizeof(Strip), "strip");
223                 strncpy(seq->name + 2, sce->id.name + 2, 
224                         sizeof(seq->name) - 2);
225                 strip->len= seq->len;
226                 strip->us= 1;
227         } else {
228                 /* movie, pydata is a path to a movie file */
229                 char *name = PyString_AsString ( py_data );
230                 if (!name) {
231                         /* only free these 2 because other stuff isnt set */
232                         BLI_remlink(seqbase, seq);
233                         MEM_freeN(seq);
234                         
235                         return EXPP_ReturnPyObjError( PyExc_TypeError,
236                                 "expects a string for chan/bone name and an int for the frame where to put the new key" );
237                 }
238                 
239                 seq->type= SEQ_MOVIE;
240         }
241         strncpy(seq->name+2, "Untitled", 21);
242         intern_pos_update(seq);
243         return Sequence_CreatePyObject(seq, NULL, sce);
244 }
245
246 static PyObject *Sequence_new( BPy_Sequence * self, PyObject * args )
247 {
248         return NewSeq_internal(&self->seq->seqbase, args, self->scene);
249 }
250
251 static PyObject *SceneSeq_new( BPy_SceneSeq * self, PyObject * args )
252 {
253         return NewSeq_internal( &((Editing *)self->scene->ed)->seqbase, args, self->scene);
254 }
255
256 static void del_seq__internal(Sequence *seq)
257 {
258         if(seq->ipo) seq->ipo->id.us--;
259         
260         if(seq->type==SEQ_RAM_SOUND && seq->sound) 
261                 seq->sound->id.us--;
262         free_sequence(seq);
263 }
264
265 static void recurs_del_seq(ListBase *lb)
266 {
267         Sequence *seq, *seqn;
268
269         seq= lb->first;
270         while(seq) {
271                 seqn= seq->next;
272                 BLI_remlink(lb, seq);
273                 if(seq->type==SEQ_META) recurs_del_seq(&seq->seqbase);
274                 del_seq__internal(seq);
275                 seq= seqn;
276         }
277 }
278
279 static PyObject *RemoveSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
280 {
281         BPy_Sequence *bpy_seq = NULL;
282         
283         if( !PyArg_ParseTuple( args, "O!", &Sequence_Type, &bpy_seq ) )
284                 return EXPP_ReturnPyObjError( PyExc_ValueError,
285                         "expects a sequence object" );
286         
287         /* quick way to tell if we dont have the seq */
288         if (sce != bpy_seq->scene)
289                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
290                         "Sequence does not exist here, cannot remove" );
291         
292         recurs_del_seq(&bpy_seq->seq->seqbase);
293         del_seq__internal(bpy_seq->seq);
294         clear_last_seq(); /* just incase */
295         Py_RETURN_NONE;
296 }
297
298 static PyObject *Sequence_remove( BPy_Sequence * self, PyObject * args )
299 {
300         return RemoveSeq_internal(&self->seq->seqbase, args, self->scene);
301 }
302
303 static PyObject *SceneSeq_remove( BPy_SceneSeq * self, PyObject * args )
304 {
305         return RemoveSeq_internal( &((Editing *)self->scene->ed)->seqbase, args, self->scene);
306 }
307
308
309 static PyObject *Sequence_copy( BPy_Sequence * self )
310 {
311         printf("Sequence Copy not implimented yet!\n");
312         Py_RETURN_NONE;
313 }
314
315
316 /*****************************************************************************/
317 /* PythonTypeObject callback function prototypes                         */
318 /*****************************************************************************/
319 static PyObject *Sequence_repr( BPy_Sequence * obj );
320 static PyObject *SceneSeq_repr( BPy_SceneSeq * obj );
321 static int Sequence_compare( BPy_Sequence * a, BPy_Sequence * b );
322 static int SceneSeq_compare( BPy_SceneSeq * a, BPy_SceneSeq * b );
323
324 /*****************************************************************************/
325 /* Python BPy_Sequence methods:                                                  */
326 /*****************************************************************************/
327
328
329 static PyObject *Sequence_getIter( BPy_Sequence * self )
330 {
331         Sequence *iter = self->seq->seqbase.first;
332         
333         if (!self->iter) {
334                 self->iter = iter;
335                 return EXPP_incr_ret ( (PyObject *) self );
336         } else {
337                 return Sequence_CreatePyObject(self->seq, iter, self->scene);
338         }
339 }
340
341 static PyObject *SceneSeq_getIter( BPy_SceneSeq * self )
342 {
343         Sequence *iter = ((Editing *)self->scene->ed)->seqbase.first;
344         
345         if (!self->iter) {
346                 self->iter = iter;
347                 return EXPP_incr_ret ( (PyObject *) self );
348         } else {
349                 return SceneSeq_CreatePyObject(self->scene, iter);
350         }
351 }
352
353
354 /*
355  * Return next Seq
356  */
357 static PyObject *Sequence_nextIter( BPy_Sequence * self )
358 {
359         PyObject *object;
360         if( !(self->iter) ) {
361                 self->iter = NULL; /* so we can add objects again */
362                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
363                                 "iterator at end" );
364         }
365         
366         object= Sequence_CreatePyObject( self->iter, NULL, self->scene ); 
367         self->iter= self->iter->next;
368         return object;
369 }
370
371
372 /*
373  * Return next Seq
374  */
375 static PyObject *SceneSeq_nextIter( BPy_Sequence * self )
376 {
377         PyObject *object;
378         if( !(self->iter) ) {
379                 self->iter = NULL; /* so we can add objects again */
380                 return EXPP_ReturnPyObjError( PyExc_StopIteration,
381                                 "iterator at end" );
382         }
383         
384         object= Sequence_CreatePyObject( self->iter, NULL, self->scene );
385         self->iter= self->iter->next;
386         return object;
387 }
388
389
390 static PyObject *Sequence_getName( BPy_Sequence * self )
391 {
392         return PyString_FromString( self->seq->name+2 );
393 }
394
395 static int Sequence_setName( BPy_Sequence * self, PyObject * value )
396 {
397         char *name = NULL;
398         
399         name = PyString_AsString ( value );
400         if( !name )
401                 return EXPP_ReturnIntError( PyExc_TypeError,
402                                               "expected string argument" );
403
404         strncpy(self->seq->name+2, name, 21);
405         return 0;
406 }
407
408
409 static PyObject *Sequence_getProxyDir( BPy_Sequence * self )
410 {
411         return PyString_FromString( self->seq->strip->proxy ? self->seq->strip->proxy->dir : "" );
412 }
413
414
415 static int Sequence_setProxyDir( BPy_Sequence * self, PyObject * value )
416 {
417         char *name = NULL;
418         
419         name = PyString_AsString ( value );
420         if( !name ) {
421                 return EXPP_ReturnIntError( PyExc_TypeError,
422                                               "expected string argument" );
423         }
424         
425         if (strlen(name) == 0) {
426                 if (self->seq->strip->proxy) {
427                         MEM_freeN(self->seq->strip->proxy); 
428                 }
429         } else {
430                 self->seq->strip->proxy = MEM_callocN(sizeof(struct StripProxy), "StripProxy");
431                 strncpy(self->seq->strip->proxy->dir, name, sizeof(struct StripProxy));
432         }
433         return 0;
434 }
435
436
437 static PyObject *Sequence_rebuildProxy( BPy_Sequence * self )
438 {
439         if (self->seq->strip->proxy)
440                 seq_proxy_rebuild(self->seq);
441         Py_RETURN_NONE;
442 }
443
444
445 static PyObject *Sequence_getSound( BPy_Sequence * self )
446 {
447         if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound)
448                 return Sound_CreatePyObject(self->seq->sound);
449         Py_RETURN_NONE;
450 }
451
452 static PyObject *Sequence_getIpo( BPy_Sequence * self )
453 {
454         struct Ipo *ipo;
455         
456         ipo = self->seq->ipo;
457
458         if( ipo )
459                 return Ipo_CreatePyObject( ipo );
460         Py_RETURN_NONE;
461 }
462
463
464 static PyObject *SceneSeq_getActive( BPy_SceneSeq * self )
465 {
466         Sequence *last_seq = NULL, *seq;
467         Editing *ed = self->scene->ed;
468
469         if (!ed)
470                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
471                                               "scene has no sequence data to edit" );
472         
473         seq = ed->seqbasep->first;
474         
475         while (seq) {
476                 if (seq->flag & SELECT)
477                         last_seq = seq;
478                 
479                 seq = seq->next;
480         }
481         if (last_seq)
482                 return Sequence_CreatePyObject(last_seq, NULL, self->scene );
483         
484         Py_RETURN_NONE;
485 }
486
487 static PyObject *SceneSeq_getMetaStrip( BPy_SceneSeq * self )
488 {
489         Sequence *seq = NULL;
490         Editing *ed = self->scene->ed;
491         MetaStack *ms;
492         if (!ed)
493                 return EXPP_ReturnPyObjError( PyExc_RuntimeError,
494                                               "scene has no sequence data to edit" );
495         
496         ms = ed->metastack.last;
497         if (!ms)
498                 Py_RETURN_NONE;
499         
500         seq = ms->parseq;
501         return Sequence_CreatePyObject(seq, NULL, self->scene);
502 }
503
504
505 /*
506  * this should accept a Py_None argument and just delete the Ipo link
507  * (as Object_clearIpo() does)
508  */
509
510 static int Sequence_setIpo( BPy_Sequence * self, PyObject * value )
511 {
512         Ipo *ipo = NULL;
513         Ipo *oldipo;
514         ID *id;
515         
516         oldipo = self->seq->ipo;
517         
518         /* if parameter is not None, check for valid Ipo */
519
520         if ( value != Py_None ) {
521                 if ( !BPy_Ipo_Check( value ) )
522                         return EXPP_ReturnIntError( PyExc_TypeError,
523                                         "expected an Ipo object" );
524
525                 ipo = Ipo_FromPyObject( value );
526
527                 if( !ipo )
528                         return EXPP_ReturnIntError( PyExc_RuntimeError,
529                                         "null ipo!" );
530
531                 if( ipo->blocktype != ID_SEQ )
532                         return EXPP_ReturnIntError( PyExc_TypeError,
533                                         "Ipo is not a sequence data Ipo" );
534         }
535
536         /* if already linked to Ipo, delete link */
537
538         if ( oldipo ) {
539                 id = &oldipo->id;
540                 if( id->us > 0 )
541                         id->us--;
542         }
543
544         /* assign new Ipo and increment user count, or set to NULL if deleting */
545
546         self->seq->ipo = ipo;
547         if ( ipo )
548                 id_us_plus(&ipo->id);
549
550         return 0;
551 }
552
553 static PyObject *Sequence_getScene( BPy_Sequence * self )
554 {
555         struct Scene *scene;
556         
557         scene = self->seq->scene;
558
559         if( scene )
560                 return Scene_CreatePyObject( scene );
561         Py_RETURN_NONE;
562 }
563
564
565 static PyObject *Sequence_getImages( BPy_Sequence * self )
566 {
567         Strip *strip;
568         StripElem *se;
569         int i;
570         PyObject *list, *ret;
571         
572         if (self->seq->type != SEQ_IMAGE) {
573                 list = PyList_New(0);
574                 ret= Py_BuildValue( "sO", "", list);
575                 Py_DECREF(list);
576                 return ret;
577         }
578         
579                         /*return EXPP_ReturnPyObjError( PyExc_TypeError,
580                                         "Sequence is not an image type" );*/
581         
582         
583         strip = self->seq->strip;
584         se = strip->stripdata;
585         list = PyList_New(strip->len);
586         
587         for (i=0; i<strip->len; i++, se++) {
588                 PyList_SetItem( list, i, PyString_FromString(se->name) );
589         }
590         
591         ret= Py_BuildValue( "sO", strip->dir, list);
592         Py_DECREF(list);
593         return ret;
594 }
595
596 static int Sequence_setImages( BPy_Sequence * self, PyObject *value )
597 {
598         Strip *strip;
599         StripElem *se;
600         int i;
601         PyObject *list;
602         char *basepath, *name;
603         
604         if (self->seq->type != SEQ_IMAGE) {
605                 return EXPP_ReturnIntError( PyExc_TypeError,
606                                 "Sequence is not an image type" );
607         }
608         
609         if( !PyArg_ParseTuple
610             ( value, "sO!", &basepath, &PyList_Type, &list ) )
611                 return EXPP_ReturnIntError( PyExc_TypeError,
612                                               "expected string and optional list argument" );
613         
614         strip = self->seq->strip;
615         se = strip->stripdata;
616         
617         /* for now dont support different image list sizes */
618         if (PyList_Size(list) != strip->len) {
619                 return EXPP_ReturnIntError( PyExc_TypeError,
620                                 "at the moment only image lista with the same number of images as the strip are supported" );
621         }
622         
623         strncpy(strip->dir, basepath, sizeof(strip->dir));
624         
625         for (i=0; i<strip->len; i++, se++) {
626                 name = PyString_AsString(PyList_GetItem(list, i));
627                 if (name) {
628                         strncpy(se->name, name, sizeof(se->name));
629                 } else {
630                         PyErr_Clear();
631                 }
632         }
633         
634         return 0;
635 }
636
637 static PyObject *M_Sequence_BlendModesDict( void )
638 {
639         PyObject *M = PyConstant_New(  );
640
641         if( M ) {
642                 BPy_constant *d = ( BPy_constant * ) M;
643                 PyConstant_Insert( d, "CROSS", PyInt_FromLong( SEQ_CROSS ) );
644                 PyConstant_Insert( d, "ADD", PyInt_FromLong( SEQ_ADD ) );
645                 PyConstant_Insert( d, "SUBTRACT", PyInt_FromLong( SEQ_SUB ) );
646                 PyConstant_Insert( d, "ALPHAOVER", PyInt_FromLong( SEQ_ALPHAOVER ) );
647                 PyConstant_Insert( d, "ALPHAUNDER", PyInt_FromLong( SEQ_ALPHAUNDER ) );
648                 PyConstant_Insert( d, "GAMMACROSS", PyInt_FromLong( SEQ_GAMCROSS ) );
649                 PyConstant_Insert( d, "MULTIPLY", PyInt_FromLong( SEQ_MUL ) );
650                 PyConstant_Insert( d, "OVERDROP", PyInt_FromLong( SEQ_OVERDROP ) );
651                 PyConstant_Insert( d, "PLUGIN", PyInt_FromLong( SEQ_PLUGIN ) );
652                 PyConstant_Insert( d, "WIPE", PyInt_FromLong( SEQ_WIPE ) );
653                 PyConstant_Insert( d, "GLOW", PyInt_FromLong( SEQ_GLOW ) );
654                 PyConstant_Insert( d, "TRANSFORM", PyInt_FromLong( SEQ_TRANSFORM ) );
655                 PyConstant_Insert( d, "COLOR", PyInt_FromLong( SEQ_COLOR ) );
656                 PyConstant_Insert( d, "SPEED", PyInt_FromLong( SEQ_SPEED ) );
657         }
658         return M;
659 }
660
661 static PyObject *Sequence_getBlendMode( BPy_Sequence * self )
662 {
663         return PyInt_FromLong( self->seq->blend_mode );
664 }
665
666 static int Sequence_setBlendMode( BPy_Sequence * self, PyObject * value )
667 {
668         struct Sequence *seq= self->seq;
669         int number = PyInt_AsLong( value );
670         
671         if( number==-1 && PyErr_Occurred() )
672                 return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
673         
674         if ( !seq_can_blend(seq) )
675                 return EXPP_ReturnIntError( PyExc_AttributeError, "this sequence type dosnt support blending" );        
676         
677         if (number<SEQ_EFFECT || number>SEQ_EFFECT_MAX)
678                 return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
679         
680         seq->blend_mode=number;
681         
682         return 0;
683 }
684
685 /*
686  * get floating point attributes
687  */
688 static PyObject *getIntAttr( BPy_Sequence *self, void *type )
689 {
690         int param;
691         struct Sequence *seq= self->seq;
692         
693         /*printf("%i %i %i %i %i %i %i %i %i\n", seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->startdisp, seq->enddisp, seq->depth );*/
694         switch( GET_INT_FROM_POINTER(type) ) {
695         case EXPP_SEQ_ATTR_TYPE: 
696                 param = seq->type;
697                 break;
698         case EXPP_SEQ_ATTR_CHAN:
699                 param = seq->machine;
700                 break;
701         case EXPP_SEQ_ATTR_LENGTH:
702                 param = seq->len;
703                 break;
704         case EXPP_SEQ_ATTR_START:
705                 param = seq->start;
706                 break;
707         case EXPP_SEQ_ATTR_STARTOFS:
708                 param = seq->startofs;
709                 break;
710         case EXPP_SEQ_ATTR_ENDOFS:
711                 param = seq->endofs;
712                 break;
713         case EXPP_SEQ_ATTR_STARTSTILL:
714                 param = seq->startstill;
715                 break;
716         case EXPP_SEQ_ATTR_ENDSTILL:
717                 param = seq->endstill;
718                 break;
719         default:
720                 return EXPP_ReturnPyObjError( PyExc_RuntimeError, 
721                                 "undefined type in getIntAttr" );
722         }
723
724         return PyInt_FromLong( param );
725 }
726
727 /* internal functions for recursivly updating metastrip locatons */
728 static void intern_pos_update(Sequence * seq) {
729         /* update startdisp and enddisp */
730         calc_sequence_disp(seq);
731 }
732
733 void intern_recursive_pos_update(Sequence * seq, int offset) {
734         Sequence *iterseq;
735         intern_pos_update(seq);
736         if (seq->type != SEQ_META) return;
737         
738         for (iterseq = seq->seqbase.first; iterseq; iterseq= iterseq->next) {
739                 iterseq->start -= offset;
740                 intern_recursive_pos_update(iterseq, offset);
741         }
742 }
743
744
745 static int setIntAttrClamp( BPy_Sequence *self, PyObject *value, void *type )
746 {
747         struct Sequence *seq= self->seq;
748         int number, origval=0, regen_data;
749
750         if( !PyInt_Check( value ) )
751                 return EXPP_ReturnIntError( PyExc_TypeError, "expected an int value" );
752         
753         number = PyInt_AS_LONG( value );
754                 
755         switch( GET_INT_FROM_POINTER(type) ) {
756         case EXPP_SEQ_ATTR_CHAN:
757                 CLAMP(number, 1, 1024);
758                 seq->machine = number;
759                 regen_data = 0;
760                 break;
761         case EXPP_SEQ_ATTR_START:
762                 if (self->seq->type == SEQ_EFFECT)
763                         return EXPP_ReturnIntError( PyExc_RuntimeError,
764                                 "cannot set the location of an effect directly" );
765                 CLAMP(number, -MAXFRAME, MAXFRAME);
766                 origval = seq->start;
767                 seq->start = number;
768                 regen_data = 0;
769                 break;
770         
771         case EXPP_SEQ_ATTR_STARTOFS:
772                 if (self->seq->type == SEQ_EFFECT)
773                         return EXPP_ReturnIntError( PyExc_RuntimeError,
774                                 "This property dosnt apply to an effect" );
775                 CLAMP(number, 0, seq->len - seq->endofs);
776                 origval = seq->startofs;
777                 seq->startofs = number;
778                 regen_data = 1;
779                 break;
780         case EXPP_SEQ_ATTR_ENDOFS:
781                 if (self->seq->type == SEQ_EFFECT)
782                         return EXPP_ReturnIntError( PyExc_RuntimeError,
783                                 "This property dosnt apply to an effect" );
784                 CLAMP(number, 0, seq->len - seq->startofs);
785                 origval = seq->endofs;
786                 seq->endofs = number;
787                 regen_data = 1;
788                 break;
789         case EXPP_SEQ_ATTR_STARTSTILL:
790                 if (self->seq->type == SEQ_EFFECT)
791                         return EXPP_ReturnIntError( PyExc_RuntimeError,
792                                 "This property dosnt apply to an effect" );
793                 CLAMP(number, 1, MAXFRAME);
794                 origval = seq->startstill;
795                 seq->startstill = number;
796                 regen_data = 1;
797                 break;
798         case EXPP_SEQ_ATTR_ENDSTILL:
799                 if (self->seq->type == SEQ_EFFECT)
800                         return EXPP_ReturnIntError( PyExc_RuntimeError,
801                                 "This property dosnt apply to an effect" );
802                 CLAMP(number, seq->startstill+1, MAXFRAME);
803                 origval = seq->endstill;
804                 seq->endstill = number;
805                 regen_data = 1;
806                 break;
807         case EXPP_SEQ_ATTR_LENGTH:
808                 if (self->seq->type == SEQ_EFFECT)
809                         return EXPP_ReturnIntError( PyExc_RuntimeError,
810                                 "cannot set the length of an effect directly" );
811                 CLAMP(number, 1, MAXFRAME);
812                 origval = seq->len;
813                 seq->len = number;
814                 regen_data = 1;
815                 break;
816         default:
817                 return EXPP_ReturnIntError( PyExc_RuntimeError,
818                                 "undefined type in setFloatAttrClamp" );
819         }
820
821         if (number != origval) {
822                 intern_pos_update(seq);
823                 
824                 if (GET_INT_FROM_POINTER(type) == EXPP_SEQ_ATTR_START)
825                         intern_recursive_pos_update(seq, origval - seq->start);
826                 
827                 if (regen_data) {
828                         new_tstripdata(seq);
829                 }
830         }
831         return 0;
832 }
833
834
835 static PyObject *getFlagAttr( BPy_Sequence *self, void *type )
836 {
837         if (self->seq->flag & GET_INT_FROM_POINTER(type))
838                 Py_RETURN_TRUE;
839         else
840                 Py_RETURN_FALSE;
841 }
842
843
844 /*
845  * set floating point attributes which require clamping
846  */
847
848 static int setFlagAttr( BPy_Sequence *self, PyObject *value, void *type )
849 {
850         int t = GET_INT_FROM_POINTER(type);
851         int param = PyObject_IsTrue( value );
852         
853         if( param == -1 )
854                 return EXPP_ReturnIntError( PyExc_TypeError,
855                                 "expected True/False or 0/1" );
856         
857         if (param)
858                 self->seq->flag |= t;
859         else {
860                 /* dont allow leftsel and rightsel when its not selected */
861                 if (t == SELECT)
862                         t = t + SEQ_LEFTSEL + SEQ_RIGHTSEL;
863                 
864                 self->seq->flag &= ~t;
865         }
866         return 0;
867 }
868
869
870 /*****************************************************************************/
871 /* Python attributes get/set structure:                                      */
872 /*****************************************************************************/
873 static PyGetSetDef BPy_Sequence_getseters[] = {
874         {"name",
875          (getter)Sequence_getName, (setter)Sequence_setName,
876          "Sequence name",
877           NULL},
878         {"proxyDir",
879          (getter)Sequence_getProxyDir, (setter)Sequence_setProxyDir,
880          "Sequence proxy directory",
881           NULL},
882         {"ipo",
883          (getter)Sequence_getIpo, (setter)Sequence_setIpo,
884          "Sequence ipo",
885           NULL},
886
887         {"scene",
888          (getter)Sequence_getScene, (setter)NULL,
889          "Sequence scene",
890           NULL},
891         {"sound",
892          (getter)Sequence_getSound, (setter)NULL,
893          "Sequence name",
894           NULL},
895         {"images",
896          (getter)Sequence_getImages, (setter)Sequence_setImages,
897          "Sequence scene",
898           NULL},
899         {"blendMode",
900          (getter)Sequence_getBlendMode, (setter)Sequence_setBlendMode,
901          "Sequence Blend Mode",
902           NULL},
903
904         {"type",
905          (getter)getIntAttr, (setter)NULL,
906          "",
907          (void *) EXPP_SEQ_ATTR_TYPE},
908         {"channel",
909          (getter)getIntAttr, (setter)setIntAttrClamp,
910          "",
911          (void *) EXPP_SEQ_ATTR_CHAN},
912          
913         {"length",
914          (getter)getIntAttr, (setter)setIntAttrClamp,
915          "",
916          (void *) EXPP_SEQ_ATTR_LENGTH},
917         {"start",
918          (getter)getIntAttr, (setter)setIntAttrClamp,
919          "",
920          (void *) EXPP_SEQ_ATTR_START},
921         {"startOffset",
922          (getter)getIntAttr, (setter)setIntAttrClamp,
923          "",
924          (void *) EXPP_SEQ_ATTR_STARTOFS},
925         {"endOffset",
926          (getter)getIntAttr, (setter)setIntAttrClamp,
927          "",
928          (void *) EXPP_SEQ_ATTR_ENDOFS},
929         {"startStill",
930          (getter)getIntAttr, (setter)setIntAttrClamp,
931          "",
932          (void *) EXPP_SEQ_ATTR_STARTSTILL},
933         {"endStill",
934          (getter)getIntAttr, (setter)setIntAttrClamp,
935          "",
936          (void *) EXPP_SEQ_ATTR_ENDSTILL},
937          
938         {"sel",
939          (getter)getFlagAttr, (setter)setFlagAttr,
940          "Sequence audio mute option",
941          (void *)SELECT},
942         {"selLeft",
943          (getter)getFlagAttr, (setter)setFlagAttr,
944          "",
945          (void *)SEQ_LEFTSEL},
946         {"selRight",
947          (getter)getFlagAttr, (setter)setFlagAttr,
948          "",
949          (void *)SEQ_RIGHTSEL},
950         {"filtery",
951          (getter)getFlagAttr, (setter)setFlagAttr,
952          "",
953          (void *)SEQ_FILTERY},
954         {"flipX",
955          (getter)getFlagAttr, (setter)setFlagAttr,
956          "",
957          (void *)SEQ_FLIPX},
958         {"flipY",
959          (getter)getFlagAttr, (setter)setFlagAttr,
960          "",
961          (void *)SEQ_FLIPY},
962         {"mute",
963          (getter)getFlagAttr, (setter)setFlagAttr,
964          "",
965          (void *)SEQ_MUTE},
966         {"floatBuffer",
967          (getter)getFlagAttr, (setter)setFlagAttr,
968          "",
969          (void *)SEQ_MAKE_FLOAT},
970         {"lock",
971          (getter)getFlagAttr, (setter)setFlagAttr,
972          "",
973          (void *)SEQ_LOCK},
974         {"useProxy",
975          (getter)getFlagAttr, (setter)setFlagAttr,
976          "",
977          (void *)SEQ_USE_PROXY},
978         {"premul",
979          (getter)getFlagAttr, (setter)setFlagAttr,
980          "",
981          (void *)SEQ_MAKE_PREMUL},
982         {"reversed",
983          (getter)getFlagAttr, (setter)setFlagAttr,
984          "",
985          (void *)SEQ_REVERSE_FRAMES},
986         {"ipoLocked",
987          (getter)getFlagAttr, (setter)setFlagAttr,
988          "",
989          (void *)SEQ_IPO_FRAME_LOCKED},
990          
991         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
992 };
993
994 /*****************************************************************************/
995 /* Python attributes get/set structure:                                      */
996 /*****************************************************************************/
997 static PyGetSetDef BPy_SceneSeq_getseters[] = {
998         {"active",
999          (getter)SceneSeq_getActive, (setter)NULL,
1000          "the active strip",
1001           NULL},
1002         {"metastrip",
1003          (getter)SceneSeq_getMetaStrip, (setter)NULL,
1004          "The currently active metastrip the user is editing",
1005           NULL},
1006         {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
1007 };
1008
1009 /*****************************************************************************/
1010 /* Python TypeSequence structure definition:                                 */
1011 /*****************************************************************************/
1012 PyTypeObject Sequence_Type = {
1013         PyObject_HEAD_INIT( NULL )  /* required py macro */
1014         0,                          /* ob_size */
1015         /*  For printing, in format "<module>.<name>" */
1016         "Blender Sequence",             /* char *tp_name; */
1017         sizeof( BPy_Sequence ),         /* int tp_basicsize; */
1018         0,                          /* tp_itemsize;  For allocation */
1019
1020         /* Methods to implement standard operations */
1021
1022         NULL,/* destructor tp_dealloc; */
1023         NULL,                       /* printfunc tp_print; */
1024         NULL,                       /* getattrfunc tp_getattr; */
1025         NULL,                       /* setattrfunc tp_setattr; */
1026         ( cmpfunc ) Sequence_compare,   /* cmpfunc tp_compare; */
1027         ( reprfunc ) Sequence_repr,     /* reprfunc tp_repr; */
1028
1029         /* Method suites for standard classes */
1030
1031         NULL,                       /* PyNumberMethods *tp_as_number; */
1032         NULL,                       /* PySequenceMethods *tp_as_sequence; */
1033         NULL,                       /* PyMappingMethods *tp_as_mapping; */
1034
1035         /* More standard operations (here for binary compatibility) */
1036
1037         NULL,                       /* hashfunc tp_hash; */
1038         NULL,                       /* ternaryfunc tp_call; */
1039         NULL,                       /* reprfunc tp_str; */
1040         NULL,                       /* getattrofunc tp_getattro; */
1041         NULL,                       /* setattrofunc tp_setattro; */
1042
1043         /* Functions to access object as input/output buffer */
1044         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1045
1046   /*** Flags to define presence of optional/expanded features ***/
1047         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
1048
1049         NULL,                       /*  char *tp_doc;  Documentation string */
1050   /*** Assigned meaning in release 2.0 ***/
1051         /* call function for all accessible objects */
1052         NULL,                       /* traverseproc tp_traverse; */
1053
1054         /* delete references to contained objects */
1055         NULL,                       /* inquiry tp_clear; */
1056
1057   /***  Assigned meaning in release 2.1 ***/
1058   /*** rich comparisons ***/
1059         NULL,                       /* richcmpfunc tp_richcompare; */
1060
1061   /***  weak reference enabler ***/
1062         0,                          /* long tp_weaklistoffset; */
1063
1064   /*** Added in release 2.2 ***/
1065         /*   Iterators */
1066         ( getiterfunc ) Sequence_getIter,           /* getiterfunc tp_iter; */
1067         ( iternextfunc ) Sequence_nextIter,           /* iternextfunc tp_iternext; */
1068
1069   /*** Attribute descriptor and subclassing stuff ***/
1070         BPy_Sequence_methods,           /* struct PyMethodDef *tp_methods; */
1071         NULL,                       /* struct PyMemberDef *tp_members; */
1072         BPy_Sequence_getseters,         /* struct PyGetSetDef *tp_getset; */
1073         NULL,                       /* struct _typeobject *tp_base; */
1074         NULL,                       /* PyObject *tp_dict; */
1075         NULL,                       /* descrgetfunc tp_descr_get; */
1076         NULL,                       /* descrsetfunc tp_descr_set; */
1077         0,                          /* long tp_dictoffset; */
1078         NULL,                       /* initproc tp_init; */
1079         NULL,                       /* allocfunc tp_alloc; */
1080         NULL,                       /* newfunc tp_new; */
1081         /*  Low-level free-memory routine */
1082         NULL,                       /* freefunc tp_free;  */
1083         /* For PyObject_IS_GC */
1084         NULL,                       /* inquiry tp_is_gc;  */
1085         NULL,                       /* PyObject *tp_bases; */
1086         /* method resolution order */
1087         NULL,                       /* PyObject *tp_mro;  */
1088         NULL,                       /* PyObject *tp_cache; */
1089         NULL,                       /* PyObject *tp_subclasses; */
1090         NULL,                       /* PyObject *tp_weaklist; */
1091         NULL
1092 };
1093
1094
1095
1096 /*****************************************************************************/
1097 /* Python TypeSequence structure definition:                                 */
1098 /*****************************************************************************/
1099 PyTypeObject SceneSeq_Type = {
1100         PyObject_HEAD_INIT( NULL )  /* required py macro */
1101         0,                          /* ob_size */
1102         /*  For printing, in format "<module>.<name>" */
1103         "Blender SceneSeq",             /* char *tp_name; */
1104         sizeof( BPy_Sequence ),         /* int tp_basicsize; */
1105         0,                          /* tp_itemsize;  For allocation */
1106
1107         /* Methods to implement standard operations */
1108
1109         NULL,/* destructor tp_dealloc; */
1110         NULL,                       /* printfunc tp_print; */
1111         NULL,                       /* getattrfunc tp_getattr; */
1112         NULL,                       /* setattrfunc tp_setattr; */
1113         ( cmpfunc ) SceneSeq_compare,   /* cmpfunc tp_compare; */
1114         ( reprfunc ) SceneSeq_repr,     /* reprfunc tp_repr; */
1115
1116         /* Method suites for standard classes */
1117
1118         NULL,                       /* PyNumberMethods *tp_as_number; */
1119         NULL,                       /* PySequenceMethods *tp_as_sequence; */
1120         NULL,                       /* PyMappingMethods *tp_as_mapping; */
1121
1122         /* More standard operations (here for binary compatibility) */
1123
1124         NULL,                       /* hashfunc tp_hash; */
1125         NULL,                       /* ternaryfunc tp_call; */
1126         NULL,                       /* reprfunc tp_str; */
1127         NULL,                       /* getattrofunc tp_getattro; */
1128         NULL,                       /* setattrofunc tp_setattro; */
1129
1130         /* Functions to access object as input/output buffer */
1131         NULL,                       /* PyBufferProcs *tp_as_buffer; */
1132
1133   /*** Flags to define presence of optional/expanded features ***/
1134         Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
1135
1136         NULL,                       /*  char *tp_doc;  Documentation string */
1137   /*** Assigned meaning in release 2.0 ***/
1138         /* call function for all accessible objects */
1139         NULL,                       /* traverseproc tp_traverse; */
1140
1141         /* delete references to contained objects */
1142         NULL,                       /* inquiry tp_clear; */
1143
1144   /***  Assigned meaning in release 2.1 ***/
1145   /*** rich comparisons ***/
1146         NULL,                       /* richcmpfunc tp_richcompare; */
1147
1148   /***  weak reference enabler ***/
1149         0,                          /* long tp_weaklistoffset; */
1150
1151   /*** Added in release 2.2 ***/
1152         /*   Iterators */
1153         ( getiterfunc ) SceneSeq_getIter,           /* getiterfunc tp_iter; */
1154         ( iternextfunc ) SceneSeq_nextIter,           /* iternextfunc tp_iternext; */
1155
1156   /*** Attribute descriptor and subclassing stuff ***/
1157         BPy_SceneSeq_methods,           /* struct PyMethodDef *tp_methods; */
1158         NULL,                       /* struct PyMemberDef *tp_members; */
1159         BPy_SceneSeq_getseters,         /* struct PyGetSetDef *tp_getset; */
1160         NULL,                       /* struct _typeobject *tp_base; */
1161         NULL,                       /* PyObject *tp_dict; */
1162         NULL,                       /* descrgetfunc tp_descr_get; */
1163         NULL,                       /* descrsetfunc tp_descr_set; */
1164         0,                          /* long tp_dictoffset; */
1165         NULL,                       /* initproc tp_init; */
1166         NULL,                       /* allocfunc tp_alloc; */
1167         NULL,                       /* newfunc tp_new; */
1168         /*  Low-level free-memory routine */
1169         NULL,                       /* freefunc tp_free;  */
1170         /* For PyObject_IS_GC */
1171         NULL,                       /* inquiry tp_is_gc;  */
1172         NULL,                       /* PyObject *tp_bases; */
1173         /* method resolution order */
1174         NULL,                       /* PyObject *tp_mro;  */
1175         NULL,                       /* PyObject *tp_cache; */
1176         NULL,                       /* PyObject *tp_subclasses; */
1177         NULL,                       /* PyObject *tp_weaklist; */
1178         NULL
1179 };
1180
1181
1182 /*****************************************************************************/
1183 /* Function:      M_Sequence_Get                                                */
1184 /* Python equivalent:     Blender.Sequence.Get                          */
1185 /*****************************************************************************/
1186 /*
1187 PyObject *M_Sequence_Get( PyObject * self, PyObject * args )
1188 {
1189         return SceneSeq_CreatePyObject( G.scene, NULL );
1190 }
1191 */
1192
1193 /*****************************************************************************/
1194 /* Function:     initObject                                             */
1195 /*****************************************************************************/
1196 PyObject *Sequence_Init( void )
1197 {
1198         PyObject *BlendModesDict = M_Sequence_BlendModesDict( );
1199         PyObject *submodule;
1200         if( PyType_Ready( &Sequence_Type ) < 0 )
1201                 return NULL;
1202         if( PyType_Ready( &SceneSeq_Type ) < 0 )
1203                 return NULL;
1204         
1205         /* NULL was M_Sequence_methods*/
1206         submodule = Py_InitModule3( "Blender.Scene.Sequence", NULL,
1207 "The Blender Sequence module\n\n\
1208 This module provides access to **Sequence Data** in Blender.\n" );
1209
1210         if( BlendModesDict )
1211                 PyModule_AddObject( submodule, "BlendModes", BlendModesDict );
1212
1213         /*Add SUBMODULES to the module*/
1214         /*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
1215         return submodule;
1216 }
1217
1218
1219 /*****************************************************************************/
1220 /* Function:    Sequence_CreatePyObject                                  */
1221 /* Description: This function will create a new BlenObject from an existing  */
1222 /*              Object structure.                                        */
1223 /*****************************************************************************/
1224 PyObject *Sequence_CreatePyObject( struct Sequence * seq, struct Sequence * iter, struct Scene *sce)
1225 {
1226         BPy_Sequence *pyseq;
1227
1228         if( !seq )
1229                 Py_RETURN_NONE;
1230
1231         pyseq =
1232                 ( BPy_Sequence * ) PyObject_NEW( BPy_Sequence, &Sequence_Type );
1233
1234         if( pyseq == NULL ) {
1235                 return ( NULL );
1236         }
1237         pyseq->seq = seq;
1238         pyseq->iter = iter;
1239         pyseq->scene = sce;
1240         
1241         return ( ( PyObject * ) pyseq );
1242 }
1243
1244 /*****************************************************************************/
1245 /* Function:    SceneSeq_CreatePyObject                                  */
1246 /* Description: This function will create a new BlenObject from an existing  */
1247 /*              Object structure.                                        */
1248 /*****************************************************************************/
1249 PyObject *SceneSeq_CreatePyObject( struct Scene * scn, struct Sequence * iter)
1250 {
1251         BPy_SceneSeq *pysceseq;
1252
1253         if( !scn )
1254                 Py_RETURN_NONE;
1255
1256         if ( !scn->ed ) {
1257                 Editing *ed;
1258                 ed= scn->ed= MEM_callocN( sizeof(Editing), "addseq");
1259                 ed->seqbasep= &ed->seqbase;
1260         }
1261         
1262         pysceseq =
1263                 ( BPy_SceneSeq * ) PyObject_NEW( BPy_SceneSeq, &SceneSeq_Type );
1264
1265         if( pysceseq == NULL ) {
1266                 return ( NULL );
1267         }
1268         pysceseq->scene = scn;
1269         pysceseq->iter = iter;
1270         
1271         return ( ( PyObject * ) pysceseq );
1272 }
1273
1274 /*****************************************************************************/
1275 /* Function:    Sequence_FromPyObject                                    */
1276 /* Description: This function returns the Blender sequence from the given        */
1277 /*              PyObject.                                                */
1278 /*****************************************************************************/
1279 struct Sequence *Sequence_FromPyObject( PyObject * py_seq )
1280 {
1281         BPy_Sequence *blen_seq;
1282
1283         blen_seq = ( BPy_Sequence * ) py_seq;
1284         return ( blen_seq->seq );
1285 }
1286
1287 /*****************************************************************************/
1288 /* Function:    Sequence_compare                                                 */
1289 /* Description: This is a callback function for the BPy_Sequence type. It        */
1290 /*              compares two Sequence_Type objects. Only the "==" and "!="  */
1291 /*              comparisons are meaninful. Returns 0 for equality and -1 if  */
1292 /*              they don't point to the same Blender Object struct.      */
1293 /*              In Python it becomes 1 if they are equal, 0 otherwise.   */
1294 /*****************************************************************************/
1295 static int Sequence_compare( BPy_Sequence * a, BPy_Sequence * b )
1296 {
1297         Sequence *pa = a->seq, *pb = b->seq;
1298         return ( pa == pb ) ? 0 : -1;
1299 }
1300
1301 static int SceneSeq_compare( BPy_SceneSeq * a, BPy_SceneSeq * b )
1302 {
1303         
1304         Scene *pa = a->scene, *pb = b->scene;
1305         return ( pa == pb ) ? 0 : -1;
1306 }
1307
1308 /*****************************************************************************/
1309 /* Function:    Sequence_repr / SceneSeq_repr                                            */
1310 /* Description: This is a callback function for the BPy_Sequence type. It        */
1311 /*              builds a meaninful string to represent object objects.   */
1312 /*****************************************************************************/
1313 static PyObject *Sequence_repr( BPy_Sequence * self )
1314 {
1315         return PyString_FromFormat( "[Sequence Strip \"%s\"]",
1316                                         self->seq->name + 2 );
1317 }
1318 static PyObject *SceneSeq_repr( BPy_SceneSeq * self )
1319 {
1320         return PyString_FromFormat( "[Scene Sequence \"%s\"]",
1321                                 self->scene->id.name + 2 );
1322 }
1323