]> git.sesse.net Git - vlc/blob - bindings/python/vlcglue.c
FSF address change.
[vlc] / bindings / python / vlcglue.c
1 /*****************************************************************************
2  * vlcglue.c: VLC Module
3  *****************************************************************************
4  * Copyright (C) 1998-2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Olivier Aubert <oaubert at bat710.univ-lyon1.fr>
8  *          ClĂ©ment Stenac <zorglub@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24 #include "vlcglue.h"
25
26 /**************************************************************************
27  * VLC Module
28  **************************************************************************/
29
30 #ifndef vlcMODINIT_FUNC /* declarations for DLL import/export */
31 #define vlcMODINIT_FUNC void
32 #endif
33
34 static PyMethodDef vlc_methods[] = {
35     { NULL }  /* Sentinel */
36 };
37
38 /* Module globals */
39 PyObject* MediaControl_InternalException          = NULL;
40 PyObject* MediaControl_PositionKeyNotSupported    = NULL;
41 PyObject *MediaControl_PositionOriginNotSupported = NULL;
42 PyObject* MediaControl_InvalidPosition            = NULL;
43 PyObject *MediaControl_PlaylistException          = NULL;
44
45 vlcMODINIT_FUNC
46 initvlc( void )
47 {
48     PyObject* p_module;
49
50     PyPosition_Type.tp_new = PyType_GenericNew;
51     PyPosition_Type.tp_alloc = PyType_GenericAlloc;
52
53     p_module = Py_InitModule3( "vlc", vlc_methods,
54                                "VLC media player embedding module." );
55
56     if( !p_module )
57       return;
58
59     if( PyType_Ready( &PyPosition_Type ) < 0 )
60         return;
61     if( PyType_Ready( &MediaControl_Type ) < 0 )
62         return;
63     if( PyType_Ready( &vlcObject_Type ) < 0 )
64         return;
65
66     /* Exceptions */
67     MediaControl_InternalException =
68             PyErr_NewException( "vlc.InternalException", NULL, NULL );
69     Py_INCREF( MediaControl_InternalException );
70     PyModule_AddObject( p_module, "InternalException",
71                         MediaControl_InternalException );
72
73     MediaControl_PositionKeyNotSupported =
74             PyErr_NewException( "vlc.PositionKeyNotSupported", NULL, NULL );
75     Py_INCREF( MediaControl_PositionKeyNotSupported );
76     PyModule_AddObject( p_module, "PositionKeyNotSupported",
77                         MediaControl_PositionKeyNotSupported );
78
79     MediaControl_PositionOriginNotSupported=
80             PyErr_NewException( "vlc.InvalidPosition", NULL, NULL );
81     Py_INCREF( MediaControl_PositionOriginNotSupported );
82     PyModule_AddObject( p_module, "PositionOriginNotSupported",
83                         MediaControl_PositionOriginNotSupported );
84
85     MediaControl_InvalidPosition =
86             PyErr_NewException( "vlc.InvalidPosition", NULL, NULL );
87     Py_INCREF( MediaControl_InvalidPosition );
88     PyModule_AddObject( p_module, "InvalidPosition",
89                         MediaControl_InvalidPosition );
90
91     MediaControl_PlaylistException =
92             PyErr_NewException( "vlc.PlaylistException", NULL, NULL );
93     Py_INCREF( MediaControl_PlaylistException );
94     PyModule_AddObject( p_module, "PlaylistException",
95                         MediaControl_PlaylistException );
96
97     /* Types */
98     Py_INCREF( &PyPosition_Type );
99     PyModule_AddObject( p_module, "Position",
100                         ( PyObject * )&PyPosition_Type );
101
102     Py_INCREF( &MediaControl_Type );
103     PyModule_AddObject( p_module, "MediaControl",
104                         ( PyObject * )&MediaControl_Type );
105
106     Py_INCREF( &vlcObject_Type );
107     PyModule_AddObject( p_module, "Object",
108                         ( PyObject * )&vlcObject_Type );
109
110     /* Constants */
111     PyModule_AddIntConstant( p_module, "AbsolutePosition",
112                              mediacontrol_AbsolutePosition );
113     PyModule_AddIntConstant( p_module, "RelativePosition",
114                              mediacontrol_RelativePosition );
115     PyModule_AddIntConstant( p_module, "ModuloPosition",
116                              mediacontrol_ModuloPosition );
117
118     PyModule_AddIntConstant( p_module, "ByteCount",
119                              mediacontrol_ByteCount );
120     PyModule_AddIntConstant( p_module, "SampleCount",
121                              mediacontrol_SampleCount );
122     PyModule_AddIntConstant( p_module, "MediaTime",
123                              mediacontrol_MediaTime );
124     PyModule_AddIntConstant( p_module, "PlayingStatus",
125                              mediacontrol_PlayingStatus );
126     PyModule_AddIntConstant( p_module, "PauseStatus",
127                              mediacontrol_PauseStatus );
128     PyModule_AddIntConstant( p_module, "ForwardStatus",
129                              mediacontrol_ForwardStatus );
130     PyModule_AddIntConstant( p_module, "BackwardStatus",
131                              mediacontrol_BackwardStatus );
132     PyModule_AddIntConstant( p_module, "InitStatus",
133                              mediacontrol_InitStatus );
134     PyModule_AddIntConstant( p_module, "EndStatus",
135                              mediacontrol_EndStatus );
136     PyModule_AddIntConstant( p_module, "UndefinedStatus",
137                              mediacontrol_UndefinedStatus );
138 }
139
140
141 /* Make libpostproc happy... */
142 void * fast_memcpy( void * to, const void * from, size_t len )
143 {
144   return memcpy( to, from, len );
145 }
146
147
148 /*****************************************************************************
149  * VLCObject implementation
150  *****************************************************************************/
151
152 static PyObject
153 *vlcObject_new( PyTypeObject *p_type, PyObject *p_args, PyObject *p_kwds )
154 {
155     vlcObject *self;
156     vlc_object_t *p_object;
157     int i_id;
158
159     self = PyObject_New( vlcObject, &vlcObject_Type );
160
161     if( !PyArg_ParseTuple( p_args, "i", &i_id ) )
162       return NULL;
163
164     /* Maybe we were already initialized */
165     p_object = ( vlc_object_t* )vlc_current_object( i_id );
166
167     if( !p_object )
168     {
169         /* Try to initialize */
170         i_id = VLC_Create();
171         p_object = ( vlc_object_t* )vlc_current_object( i_id );
172     }
173
174     if( !p_object )
175     {
176         PyErr_SetString( PyExc_StandardError, "Unable to get object." );
177         return NULL;
178     }
179
180     self->p_object = p_object;
181     self->b_released = 0;
182
183     Py_INCREF(  self ); /* Ah bon ? */
184     return ( PyObject * )self;
185 }
186
187 static PyObject *
188 vlcObject_release(  PyObject *self, PyObject *p_args )
189 {
190     if( VLCSELF->b_released == 0 )
191     {
192         vlc_object_release( VLCSELF->p_object );
193         VLCSELF->b_released = 1;
194     }
195     Py_INCREF(  Py_None );
196     return Py_None;
197 }
198
199 static void
200 vlcObject_dealloc( PyObject *self )
201 {
202     vlcObject_release( self, NULL );
203     PyMem_DEL( self );
204 }
205
206 static PyObject *
207 vlcObject_find_object( PyObject *self, PyObject *args )
208 {
209     vlcObject *p_retval;
210     vlc_object_t *p_obj;
211     char *psz_name;
212     int i_object_type;
213
214     if( !PyArg_ParseTuple( args, "s", &psz_name ) )
215         return NULL;
216
217     /* psz_name is in
218        ( aout, decoder, input, httpd, intf, playlist, root, vlc, vout )
219     */
220     switch ( psz_name[0] )
221     {
222         case 'a':
223             i_object_type = VLC_OBJECT_AOUT;
224             break;
225         case 'd':
226             i_object_type = VLC_OBJECT_DECODER;
227             break;
228         case 'h':
229             i_object_type = VLC_OBJECT_HTTPD;
230             break;
231         case 'i':
232             if( strlen( psz_name ) < 3 )
233                     i_object_type = VLC_OBJECT_INTF;
234             else if( psz_name[2] == 't' )
235                     i_object_type = VLC_OBJECT_INTF;
236             else
237                     i_object_type = VLC_OBJECT_INPUT;
238             break;
239         case 'p':
240             i_object_type = VLC_OBJECT_PLAYLIST;
241             break;
242         case 'r':
243             i_object_type = VLC_OBJECT_ROOT;
244             break;
245         case 'v':
246             if( strlen( psz_name ) < 3 )
247                     i_object_type = VLC_OBJECT_VLC;
248             else if( psz_name[1] == 'l' )
249                     i_object_type = VLC_OBJECT_VLC;
250             else
251                     i_object_type = VLC_OBJECT_VOUT;
252             break;
253         default:
254             /* FIXME: raise an exception ? */
255             return Py_None;
256     }
257
258     p_obj = vlc_object_find( VLCSELF->p_object, i_object_type, FIND_ANYWHERE );
259
260     if( !p_obj )
261     {
262         Py_INCREF( Py_None );
263         return Py_None;
264     }
265
266     p_retval = PyObject_New( vlcObject, &vlcObject_Type );
267
268     p_retval->p_object = p_obj;
269
270     return ( PyObject * )p_retval;
271 }
272
273 static PyObject *
274 vlcObject_info( PyObject *self, PyObject *args )
275 {
276     PyObject *p_retval;
277     vlc_object_t *p_obj;
278
279     p_obj = VLCSELF->p_object;
280
281     /* Return information about the object as a dict. */
282     p_retval = PyDict_New();
283
284     PyDict_SetItemString( p_retval, "object-id",
285                           Py_BuildValue( "l", p_obj->i_object_id ) );
286     PyDict_SetItemString( p_retval, "object-type",
287                           Py_BuildValue( "s", p_obj->psz_object_type ) );
288     PyDict_SetItemString( p_retval, "object-name",
289                           Py_BuildValue( "s", p_obj->psz_object_name ) );
290     PyDict_SetItemString( p_retval, "thread",
291                           PyBool_FromLong( p_obj->b_thread ) );
292     PyDict_SetItemString( p_retval, "thread-id",
293                           PyLong_FromLongLong( p_obj->thread_id ) );
294     PyDict_SetItemString( p_retval, "refcount",
295                           PyInt_FromLong( p_obj->i_refcount ) );
296
297     return p_retval;
298 }
299
300 static PyObject *
301 vlcObject_find_id( PyObject *self, PyObject *args )
302 {
303     vlcObject *p_retval;
304     vlc_object_t* p_object;
305     int i_id;
306
307     if( !PyArg_ParseTuple( args, "i", &i_id ) )
308         return NULL;
309
310     p_object = ( vlc_object_t* )vlc_current_object( i_id );
311
312     if( !p_object )
313     {
314         Py_INCREF( Py_None );
315         return Py_None;
316     }
317
318     p_retval = PyObject_NEW( vlcObject, &vlcObject_Type );
319
320     p_retval->p_object = p_object;
321
322     return ( PyObject * )p_retval;
323 }
324
325 /* Do a var_Get call on the object. Parameter: the variable name. */
326 static PyObject *
327 vlcObject_var_get( PyObject *self, PyObject *args )
328 {
329     PyObject *p_retval;
330     vlc_value_t value;
331     char *psz_name;
332     int i_type;
333
334     if( !PyArg_ParseTuple( args, "s", &psz_name ) )
335         return NULL;
336
337     if( var_Get( VLCSELF->p_object, psz_name, &value ) != VLC_SUCCESS )
338     {
339         PyErr_SetString( PyExc_StandardError,
340                          "Error: variable does not exist.\n" );
341         return NULL;
342     }
343
344     i_type = var_Type ( VLCSELF->p_object, psz_name );
345
346     switch ( i_type )
347     {
348     case VLC_VAR_VOID      :
349         p_retval = PyString_FromString( "A void variable" );
350         break;
351     case VLC_VAR_BOOL      :
352         p_retval = PyBool_FromLong( value.b_bool );
353         break;
354     case VLC_VAR_INTEGER   :
355         p_retval = PyInt_FromLong( ( long )value.i_int );
356         break;
357     case VLC_VAR_HOTKEY    :
358         p_retval = PyString_FromFormat( "A hotkey variable ( %d )", value.i_int );
359         break;
360     case VLC_VAR_FILE      :
361     case VLC_VAR_STRING    :
362     case VLC_VAR_DIRECTORY :
363     case VLC_VAR_VARIABLE  :
364         p_retval = PyString_FromString( value.psz_string );
365         break;
366     case VLC_VAR_MODULE   :
367         p_retval = ( PyObject* )PyObject_New( vlcObject, &vlcObject_Type );
368         ( ( vlcObject* )p_retval )->p_object = value.p_object;
369         break;
370     case VLC_VAR_FLOAT     :
371         p_retval = PyFloat_FromDouble( ( double )value.f_float );
372         break;
373     case VLC_VAR_TIME      :
374         p_retval = PyLong_FromLongLong( value.i_time );
375         break;
376     case VLC_VAR_ADDRESS   :
377         p_retval = PyString_FromString( "A VLC address ( not handled yet )" );
378         break;
379     case VLC_VAR_LIST      :
380         p_retval = PyString_FromString( "A VLC list ( not handled yet )" );
381         break;
382     case VLC_VAR_MUTEX :
383         p_retval = PyString_FromString( "A mutex" );
384         break;
385     default:
386         p_retval = Py_None;
387     }
388
389     Py_INCREF( p_retval );
390     return p_retval;
391 }
392
393 static PyObject *
394 vlcObject_var_type( PyObject *self, PyObject *args )
395 {
396     char *psz_name;
397     PyObject *p_retval;
398     int i_type;
399
400     if( !PyArg_ParseTuple( args, "s", &psz_name ) )
401         return NULL;
402
403     i_type = var_Type( VLCSELF->p_object, psz_name );
404
405     switch ( i_type )
406     {
407     case VLC_VAR_VOID   :
408         p_retval = PyString_FromString( "Void" );
409         break;
410     case VLC_VAR_BOOL      :
411         p_retval = PyString_FromString( "Boolean" );
412         break;
413     case VLC_VAR_INTEGER   :
414         p_retval = PyString_FromString( "Integer" );
415         break;
416     case VLC_VAR_HOTKEY   :
417         p_retval = PyString_FromString( "Hotkey" );
418         break;
419     case VLC_VAR_FILE      :
420         p_retval = PyString_FromString( "File" );
421         break;
422     case VLC_VAR_STRING    :
423         p_retval = PyString_FromString( "String" );
424         break;
425     case VLC_VAR_DIRECTORY :
426         p_retval = PyString_FromString( "Directory" );
427         break;
428     case VLC_VAR_VARIABLE  :
429         p_retval = PyString_FromString( "Variable" );
430         break;
431     case VLC_VAR_MODULE   :
432         p_retval = PyString_FromString( "Module" );
433         break;
434     case VLC_VAR_FLOAT     :
435         p_retval = PyString_FromString( "Float" );
436         break;
437     case VLC_VAR_TIME      :
438         p_retval = PyString_FromString( "Time" );
439         break;
440     case VLC_VAR_ADDRESS   :
441         p_retval = PyString_FromString( "Address" );
442         break;
443     case VLC_VAR_LIST      :
444         p_retval = PyString_FromString( "List" );
445         break;
446     case VLC_VAR_MUTEX :
447         p_retval = PyString_FromString( "Mutex" );
448         break;
449     default:
450         p_retval = PyString_FromString( "Unknown" );
451     }
452     return p_retval;
453 }
454
455 /* Do a var_Set call on the object. Parameter: the variable name. */
456 static PyObject *
457 vlcObject_var_set( PyObject *self, PyObject *args )
458 {
459     vlc_value_t value;
460     char *psz_name;
461     PyObject *py_value;
462     int i_type;
463     vlc_object_t *p_obj;
464
465     if( !PyArg_ParseTuple( args, "sO", &psz_name, &py_value ) )
466         return NULL;
467
468     p_obj = VLCSELF->p_object;
469     i_type = var_Type( p_obj, psz_name );
470
471     switch ( i_type )
472     {
473     case VLC_VAR_VOID   :
474         break;
475     case VLC_VAR_BOOL      :
476         value.b_bool = PyInt_AsLong( py_value );
477         break;
478     case VLC_VAR_INTEGER   :
479     case VLC_VAR_HOTKEY   :
480         value.i_int = PyInt_AsLong( py_value );
481         break;
482     case VLC_VAR_FILE      :
483     case VLC_VAR_STRING    :
484     case VLC_VAR_DIRECTORY :
485     case VLC_VAR_VARIABLE  :
486         value.psz_string = strdup( PyString_AsString( py_value ) );
487         break;
488     case VLC_VAR_MODULE   :
489         /* FIXME: we should check the PyObject type and get its p_object */
490         value.p_object = ( ( vlcObject* )p_obj )->p_object;
491         break;
492     case VLC_VAR_FLOAT     :
493         value.f_float = PyFloat_AsDouble( py_value );
494         break;
495     case VLC_VAR_TIME      :
496         value.i_time = PyLong_AsLongLong( py_value );
497         break;
498     case VLC_VAR_ADDRESS   :
499         value.p_address = ( char* )PyLong_AsVoidPtr( py_value );
500         break;
501     case VLC_VAR_LIST      :
502         /* FIXME */
503         value.p_list = NULL;
504         break;
505     case VLC_VAR_MUTEX :
506         break;
507     }
508
509     var_Set( p_obj, psz_name, value );
510
511     Py_INCREF( Py_None );
512     return Py_None;
513 }
514
515 static PyObject *
516 vlcObject_var_list( PyObject *self, PyObject *args )
517 {
518     PyObject *p_retval;
519     int i_size;
520     int i_index;
521
522     i_size = VLCSELF->p_object->i_vars;
523     p_retval = PyTuple_New( i_size );
524
525     for ( i_index = 0 ; i_index < i_size ; i_index++ )
526     {
527         PyTuple_SetItem( p_retval, i_index,
528                          Py_BuildValue( "s", VLCSELF->p_object->p_vars[i_index].psz_name ) );
529     }
530
531     return p_retval;
532 }
533
534 /* Do a config_Get call on the object. Parameter: the variable name. */
535 static PyObject *
536 vlcObject_config_get( PyObject *self, PyObject *args )
537 {
538     PyObject *p_retval;
539     vlc_value_t value;
540     char *psz_name;
541     module_config_t *p_config;
542
543     if( !PyArg_ParseTuple( args, "s", &psz_name ) )
544         return NULL;
545
546     p_config = config_FindConfig( VLCSELF->p_object, psz_name );
547
548     if( !p_config )
549     {
550         PyErr_SetString( PyExc_StandardError,
551                          "Error: config variable does not exist.\n" );
552         return NULL;
553     }
554
555     switch ( p_config->i_type )
556     {
557     case CONFIG_ITEM_BOOL      :
558         p_retval = PyBool_FromLong( p_config->i_value );
559         break;
560     case CONFIG_ITEM_INTEGER   :
561         p_retval = PyInt_FromLong( ( long )p_config->i_value );
562         break;
563     case CONFIG_ITEM_KEY   :
564         p_retval = PyString_FromFormat( "A hotkey variable ( %d )", p_config->i_value );
565         break;
566     case CONFIG_ITEM_FILE      :
567     case CONFIG_ITEM_STRING    :
568     case CONFIG_ITEM_DIRECTORY :
569     case CONFIG_ITEM_MODULE    :
570         vlc_mutex_lock( p_config->p_lock );
571         if( p_config->psz_value )
572             p_retval = PyString_FromString( p_config->psz_value );
573         else
574             p_retval = PyString_FromString( "" );
575         vlc_mutex_unlock( p_config->p_lock );
576         break;
577         p_retval = ( PyObject* )PyObject_New( vlcObject, &vlcObject_Type );
578         ( ( vlcObject* )p_retval )->p_object = value.p_object;
579         break;
580     case CONFIG_ITEM_FLOAT     :
581         p_retval = PyFloat_FromDouble( ( double )p_config->f_value );
582         break;
583     default:
584         p_retval = Py_None;
585         Py_INCREF( p_retval );
586     }
587
588     return p_retval;
589 }
590
591 /* Do a config_put* call on the object. Parameter: the variable name. */
592 static PyObject *
593 vlcObject_config_set( PyObject *self, PyObject *args )
594 {
595     char *psz_name;
596     PyObject *py_value;
597     vlc_object_t *p_obj;
598     module_config_t *p_config;
599
600
601     if( !PyArg_ParseTuple( args, "sO", &psz_name, &py_value ) )
602         return NULL;
603
604     p_obj = VLCSELF->p_object;
605     p_config = config_FindConfig( p_obj, psz_name );
606     /* sanity checks */
607     if( !p_config )
608     {
609         PyErr_SetString( PyExc_StandardError,
610                          "Error: option does not exist.\n" );
611         return NULL;
612     }
613
614     switch ( p_config->i_type )
615     {
616     case CONFIG_ITEM_BOOL      :
617     case CONFIG_ITEM_INTEGER   :
618     case CONFIG_ITEM_KEY       :
619         config_PutInt( p_obj, psz_name, PyInt_AsLong( py_value ) );
620         break;
621     case CONFIG_ITEM_FILE      :
622     case CONFIG_ITEM_STRING    :
623     case CONFIG_ITEM_DIRECTORY :
624     case CONFIG_ITEM_MODULE   :
625         config_PutPsz( p_obj, psz_name, PyString_AsString( py_value ) );
626         break;
627     case CONFIG_ITEM_FLOAT     :
628         config_PutFloat( p_obj, psz_name, PyFloat_AsDouble( py_value ) );
629         break;
630     }
631     Py_INCREF( Py_None );
632     return Py_None;
633 }
634
635 static PyObject *
636 vlcObject_children( PyObject *self, PyObject *args )
637 {
638     PyObject *p_retval;
639     int i_size;
640     int i_index;
641
642     i_size = VLCSELF->p_object->i_children;
643     p_retval = PyTuple_New( i_size );
644
645     for ( i_index = 0 ; i_index < i_size ; i_index++ )
646     {
647         PyTuple_SetItem( p_retval, i_index,
648                          Py_BuildValue( "i",
649                                         VLCSELF->p_object->pp_children[i_index]->i_object_id ) );
650     }
651
652     return p_retval;
653 }
654
655
656 /* Method table */
657 static PyMethodDef vlcObject_methods[] =
658 {
659     { "get", vlcObject_var_get, METH_VARARGS,
660       "get( str ) -> value   Get a variable value."},
661     { "set", vlcObject_var_set, METH_VARARGS,
662       "set( str, value )     Set a variable value" },
663     { "config_get", vlcObject_config_get, METH_VARARGS,
664       "config_get( str ) -> value   Get a configuration option." },
665     { "config_set", vlcObject_config_set, METH_VARARGS,
666       "config_set( str, value )     Set a configuration option" },
667     { "type", vlcObject_var_type, METH_VARARGS,
668       "type( str ) -> str     Get a variable type" },
669     { "list", vlcObject_var_list, METH_NOARGS,
670       "list( )             List the available variables" },
671     { "children", vlcObject_children, METH_NOARGS,
672       "children( )             List the children ids" },
673     { "find_object", vlcObject_find_object, METH_VARARGS,
674       "find_object( str ) -> Object     Find the object of a given type.\n\nAvailable types are : aout, decoder, input, httpd, intf, playlist, root, vlc, vout"},
675     { "find_id", vlcObject_find_id, METH_VARARGS,
676       "find_id( int ) -> Object      Find an object by id" },
677     { "info", vlcObject_info, METH_NOARGS,
678        "info( ) -> dict    Return information about the object" },
679     { "release", vlcObject_release, METH_NOARGS,
680       "release( ) ->     Release the VLC Object" },
681     { NULL, NULL, 0, NULL },
682 };
683
684 static PyTypeObject vlcObject_Type =
685 {
686     PyObject_HEAD_INIT( NULL )
687     0,                         /*ob_size*/
688     "vlc.Object",       /*tp_name*/
689     sizeof( vlcObject_Type ), /*tp_basicsize*/
690     0,                         /*tp_itemsize*/
691     ( destructor )vlcObject_dealloc,      /*tp_dealloc*/
692     0,                         /*tp_print*/
693     0,                         /*tp_getattr*/
694     0,                         /*tp_setattr*/
695     0,                         /*tp_compare*/
696     0,                         /*tp_repr*/
697     0,                         /*tp_as_number*/
698     0,                         /*tp_as_sequence*/
699     0,                         /*tp_as_mapping*/
700     0,                         /*tp_hash */
701     0,                         /*tp_call*/
702     0,                         /*tp_str*/
703     0,                         /*tp_getattro*/
704     0,                         /*tp_setattro*/
705     0,                         /*tp_as_buffer*/
706     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
707     "Expose VLC object infrastructure.",  /* tp_doc */
708     0,                     /* tp_traverse */
709     0,                     /* tp_clear */
710     0,                     /* tp_richcompare */
711     0,                     /* tp_weaklistoffset */
712     0,                     /* tp_iter */
713     0,                     /* tp_iternext */
714     vlcObject_methods,             /* tp_methods */
715     0,             /* tp_members */
716     0,                         /* tp_getset */
717     0,                         /* tp_base */
718     0,                         /* tp_dict */
719     0,                         /* tp_descr_get */
720     0,                         /* tp_descr_set */
721     0,                         /* tp_dictoffset */
722     0,                         /* tp_init */
723     0,                         /* tp_alloc */
724     vlcObject_new,          /* tp_new */
725 };
726
727 /*****************************************************************************
728  * VLC MediaControl object implementation
729  *****************************************************************************/
730
731 static PyObject *
732 MediaControl_new( PyTypeObject *type, PyObject *args, PyObject *kwds )
733 {
734     MediaControl *self;
735     mediacontrol_Exception *exception = NULL;
736     PyObject* py_list = NULL;
737     char** ppsz_args = NULL;
738
739     self = PyObject_New( MediaControl, &MediaControl_Type );
740
741     if( PyArg_ParseTuple( args, "O", &py_list ) )
742     {
743         int i_size;
744         int i_index;
745
746         Py_INCREF( py_list );
747         if( ! PySequence_Check( py_list ) )
748         {
749             PyErr_SetString( PyExc_TypeError, "Parameter must be a sequence." );
750             return NULL;
751         }
752         i_size = PySequence_Size( py_list );
753         ppsz_args = malloc( i_size + 1 );
754         if( ! ppsz_args )
755         {
756             PyErr_SetString( PyExc_MemoryError, "Out of memory" );
757             return NULL;
758         }
759
760         for ( i_index = 0; i_index < i_size; i_index++ )
761         {
762             ppsz_args[i_index] =
763                 strdup( PyString_AsString( PyObject_Str(
764                                                PySequence_GetItem( py_list,
765                                                                    i_index ) ) ) );
766         }
767         ppsz_args[i_size] = NULL;
768         Py_DECREF( py_list );
769     }
770     else
771     {
772         /* No arguments were given. Clear the exception raised
773            by PyArg_ParseTuple. */
774         PyErr_Clear( );
775     }
776
777     Py_BEGIN_ALLOW_THREADS
778     MC_TRY;
779     self->mc = mediacontrol_new( ppsz_args, exception );
780     MC_EXCEPT;
781     Py_END_ALLOW_THREADS
782
783     Py_INCREF( self );
784     return ( PyObject * )self;
785 }
786
787 static void
788 MediaControl_dealloc( PyObject *self )
789 {
790     PyMem_DEL( self );
791 }
792
793 /**
794  *  Return the current position in the stream. The returned value can
795    be relative or absolute ( according to PositionOrigin ) and the unit
796    is set by PositionKey
797  */
798 static PyObject *
799 MediaControl_get_media_position( PyObject *self, PyObject *args )
800 {
801     mediacontrol_Position* pos;
802     mediacontrol_Exception* exception = NULL;
803     PyObject *py_origin;
804     PyObject *py_key;
805     PyObject *py_retval;
806     mediacontrol_PositionOrigin origin;
807     mediacontrol_PositionKey key;
808
809     if( !PyArg_ParseTuple( args, "OO", &py_origin, &py_key ) )
810         return NULL;
811
812     origin = positionOrigin_py_to_c( py_origin );
813     key    = positionKey_py_to_c( py_key );
814
815     Py_BEGIN_ALLOW_THREADS
816     MC_TRY;
817     pos = mediacontrol_get_media_position( SELF->mc, origin, key, exception );
818     Py_END_ALLOW_THREADS
819     MC_EXCEPT;
820
821     py_retval = ( PyObject* )position_c_to_py( pos );
822     free( pos );
823     return py_retval;
824 }
825
826 /** Set the media position */
827 static PyObject *
828 MediaControl_set_media_position( PyObject *self, PyObject *args )
829 {
830     mediacontrol_Exception* exception = NULL;
831     mediacontrol_Position *a_position;
832     PyObject *py_pos;
833
834     if( !PyArg_ParseTuple( args, "O", &py_pos ) )
835         return NULL;
836
837     a_position = position_py_to_c( py_pos );
838     if( !a_position )
839     {
840         PyErr_SetString( PyExc_MemoryError, "Out of memory" );
841         return NULL;
842     }
843
844     Py_BEGIN_ALLOW_THREADS
845     MC_TRY;
846     mediacontrol_set_media_position( SELF->mc, a_position, exception );
847     free( a_position );
848     Py_END_ALLOW_THREADS
849     MC_EXCEPT;
850
851     Py_INCREF( Py_None );
852     return Py_None;
853 }
854
855 static PyObject *
856 MediaControl_start( PyObject *self, PyObject *args )
857 {
858     mediacontrol_Position *a_position;
859     mediacontrol_Exception *exception = NULL;
860     PyObject *py_pos;
861
862     if( !PyArg_ParseTuple( args, "O", &py_pos ) )
863     {
864         /* No argument. Use a default 0 value. */
865         PyErr_Clear( );
866         py_pos = NULL;
867     }
868     a_position = position_py_to_c( py_pos );
869     if( !a_position )
870         return NULL;
871
872     Py_BEGIN_ALLOW_THREADS
873     MC_TRY;
874     mediacontrol_start( SELF->mc, a_position, exception );
875     free( a_position );
876     Py_END_ALLOW_THREADS
877     MC_EXCEPT;
878
879     Py_INCREF( Py_None );
880     return Py_None;
881 }
882
883 static PyObject *
884 MediaControl_pause( PyObject *self, PyObject *args )
885 {
886     mediacontrol_Position *a_position;
887     mediacontrol_Exception *exception = NULL;
888     PyObject *py_pos;
889
890     if( !PyArg_ParseTuple( args, "O", &py_pos ) )
891     {
892         /* No argument. Use a default 0 value. */
893         PyErr_Clear( );
894         py_pos = NULL;
895     }
896     a_position = position_py_to_c( py_pos );
897     if( !a_position )
898         return NULL;
899
900     Py_BEGIN_ALLOW_THREADS
901     MC_TRY;
902     mediacontrol_pause( SELF->mc, a_position, exception );
903     free( a_position );
904     Py_END_ALLOW_THREADS
905     MC_EXCEPT;
906
907   Py_INCREF( Py_None );
908   return Py_None;
909 }
910
911 static PyObject *
912 MediaControl_resume( PyObject *self, PyObject *args )
913 {
914     mediacontrol_Position *a_position;
915     mediacontrol_Exception *exception = NULL;
916     PyObject *py_pos;
917
918     if( !PyArg_ParseTuple( args, "O", &py_pos ) )
919     {
920         /* No argument. Use a default 0 value. */
921         PyErr_Clear( );
922         py_pos = NULL;
923     }
924     a_position = position_py_to_c( py_pos );
925     if( !a_position )
926         return NULL;
927
928     Py_BEGIN_ALLOW_THREADS
929     MC_TRY;
930     mediacontrol_start( SELF->mc, a_position, exception );
931     free( a_position );
932     Py_END_ALLOW_THREADS
933     MC_EXCEPT;
934
935     Py_INCREF( Py_None );
936     return Py_None;
937 }
938
939 static PyObject *
940 MediaControl_stop( PyObject *self, PyObject *args )
941 {
942     mediacontrol_Position *a_position;
943     mediacontrol_Exception *exception = NULL;
944     PyObject *py_pos;
945
946     if( !PyArg_ParseTuple( args, "O", &py_pos ) )
947     {
948         /* No argument. Use a default 0 value. */
949         PyErr_Clear( );
950         py_pos = NULL;
951     }
952     a_position = position_py_to_c( py_pos );
953     if( !a_position )
954         return NULL;
955
956     Py_BEGIN_ALLOW_THREADS
957     MC_TRY;
958     mediacontrol_stop( SELF->mc, a_position, exception );
959     free( a_position );
960     Py_END_ALLOW_THREADS
961     MC_EXCEPT;
962
963     Py_INCREF( Py_None );
964     return Py_None;
965 }
966
967 static PyObject *
968 MediaControl_exit( PyObject *self, PyObject *args )
969 {
970     mediacontrol_exit( SELF->mc );
971     Py_INCREF( Py_None );
972     return Py_None;
973 }
974
975 static PyObject *
976 MediaControl_playlist_add_item( PyObject *self, PyObject *args )
977 {
978     char *psz_file;
979     mediacontrol_Exception *exception = NULL;
980
981     if( !PyArg_ParseTuple( args, "s", &psz_file ) )
982       return NULL;
983
984     Py_BEGIN_ALLOW_THREADS
985     MC_TRY;
986     mediacontrol_playlist_add_item( SELF->mc, psz_file, exception );
987     Py_END_ALLOW_THREADS
988     MC_EXCEPT;
989
990     Py_INCREF( Py_None );
991     return Py_None;
992 }
993
994 static PyObject *
995 MediaControl_playlist_clear( PyObject *self, PyObject *args )
996 {
997     mediacontrol_Exception *exception = NULL;
998
999     Py_BEGIN_ALLOW_THREADS
1000     MC_TRY;
1001     mediacontrol_playlist_clear( SELF->mc, exception );
1002     Py_END_ALLOW_THREADS
1003     MC_EXCEPT;
1004
1005     Py_INCREF( Py_None );
1006     return Py_None;
1007 }
1008
1009 static PyObject *
1010 MediaControl_playlist_get_list( PyObject *self, PyObject *args )
1011 {
1012     PyObject *py_retval;
1013     mediacontrol_Exception *exception = NULL;
1014     mediacontrol_PlaylistSeq* pl;
1015     int i_index;
1016     int i_playlist_size;
1017
1018     Py_BEGIN_ALLOW_THREADS
1019     MC_TRY;
1020     pl = mediacontrol_playlist_get_list( SELF->mc, exception );
1021     Py_END_ALLOW_THREADS
1022     MC_EXCEPT;
1023
1024     i_playlist_size = pl->size;
1025
1026     py_retval = PyList_New( i_playlist_size );
1027
1028     for ( i_index = 0 ; i_index < i_playlist_size ; i_index++ )
1029     {
1030         PyList_SetItem( py_retval, i_index,
1031                         Py_BuildValue( "s", pl->data[i_index] ) );
1032     }
1033     mediacontrol_PlaylistSeq__free( pl );
1034
1035     return py_retval;
1036 }
1037
1038
1039 static PyObject *
1040 MediaControl_snapshot( PyObject *self, PyObject *args )
1041 {
1042     mediacontrol_RGBPicture *p_retval = NULL;
1043     mediacontrol_Exception* exception = NULL;
1044     mediacontrol_Position *a_position = NULL;
1045     PyObject *py_pos = NULL;
1046     PyObject *py_obj = NULL;
1047
1048     if( !PyArg_ParseTuple( args, "O", &py_pos ) )
1049       return NULL;
1050
1051     a_position = position_py_to_c( py_pos );
1052
1053     Py_BEGIN_ALLOW_THREADS
1054     MC_TRY;
1055     p_retval = mediacontrol_snapshot( SELF->mc, a_position, exception );
1056     free( a_position );
1057     Py_END_ALLOW_THREADS
1058     MC_EXCEPT;
1059
1060     if( !p_retval )
1061     {
1062         Py_INCREF( Py_None );
1063         return Py_None;
1064     }
1065
1066     /* FIXME: create a real RGBPicture object */
1067     py_obj = PyDict_New();
1068
1069     PyDict_SetItemString( py_obj, "width",
1070                           Py_BuildValue( "i", p_retval->width ) );
1071     PyDict_SetItemString( py_obj, "height",
1072                           Py_BuildValue( "i", p_retval->height ) );
1073     PyDict_SetItemString( py_obj, "type",
1074                           Py_BuildValue( "i", p_retval->type ) );
1075     PyDict_SetItemString( py_obj, "data",
1076                           Py_BuildValue( "s#", p_retval->data, p_retval->size ) );
1077
1078     return py_obj;
1079 }
1080
1081 static PyObject*
1082 MediaControl_display_text( PyObject *self, PyObject *args )
1083 {
1084     mediacontrol_Exception* exception = NULL;
1085     PyObject *py_begin, *py_end;
1086     char* message;
1087     mediacontrol_Position * begin;
1088     mediacontrol_Position * end;
1089
1090     if( !PyArg_ParseTuple( args, "sOO", &message, &py_begin, &py_end ) )
1091         return NULL;
1092
1093     begin = position_py_to_c( py_begin );
1094     end   = position_py_to_c( py_end );
1095
1096     Py_BEGIN_ALLOW_THREADS
1097     MC_TRY;
1098     mediacontrol_display_text( SELF->mc, message, begin, end, exception );
1099     Py_END_ALLOW_THREADS
1100     MC_EXCEPT;
1101
1102     free( begin );
1103     free( end );
1104
1105     Py_INCREF( Py_None );
1106     return Py_None;
1107 }
1108
1109 static PyObject*
1110 MediaControl_get_stream_information( PyObject *self, PyObject *args )
1111 {
1112     mediacontrol_StreamInformation *retval  = NULL;
1113     mediacontrol_Exception* exception = NULL;
1114     PyObject *py_obj;
1115
1116     Py_BEGIN_ALLOW_THREADS
1117     MC_TRY;
1118     retval = mediacontrol_get_stream_information(
1119         SELF->mc, mediacontrol_MediaTime, exception );
1120     Py_END_ALLOW_THREADS
1121     MC_EXCEPT;
1122
1123     py_obj = PyDict_New( );
1124
1125      /* FIXME: create a real StreamInformation object */
1126     PyDict_SetItemString( py_obj, "status",
1127                   Py_BuildValue( "i", retval->streamstatus ) );
1128     PyDict_SetItemString( py_obj, "url",
1129                   Py_BuildValue( "s", retval->url ) );
1130     PyDict_SetItemString( py_obj, "position",
1131                   Py_BuildValue( "L", retval->position ) );
1132     PyDict_SetItemString( py_obj, "length",
1133                   Py_BuildValue( "L", retval->length ) );
1134
1135     free( retval->url );
1136     free( retval );
1137
1138     return py_obj;
1139 }
1140
1141 static PyObject*
1142 MediaControl_sound_set_volume( PyObject *self, PyObject *args )
1143 {
1144     mediacontrol_Exception* exception = NULL;
1145     unsigned short volume;
1146
1147     if( !PyArg_ParseTuple( args, "H", &volume ) )
1148         return NULL;
1149
1150     Py_BEGIN_ALLOW_THREADS
1151     MC_TRY;
1152     mediacontrol_sound_set_volume( SELF->mc, volume, exception );
1153     Py_END_ALLOW_THREADS
1154     MC_EXCEPT;
1155
1156     Py_INCREF( Py_None );
1157     return Py_None;
1158 }
1159
1160 static PyObject*
1161 MediaControl_sound_get_volume( PyObject *self, PyObject *args )
1162 {
1163     mediacontrol_Exception* exception = NULL;
1164     PyObject *py_retval;
1165     unsigned short volume;
1166
1167     Py_BEGIN_ALLOW_THREADS
1168     MC_TRY;
1169     volume = mediacontrol_sound_get_volume( SELF->mc, exception );
1170     Py_END_ALLOW_THREADS
1171     MC_EXCEPT;
1172
1173     py_retval = Py_BuildValue( "H", volume );
1174     return py_retval;
1175 }
1176
1177 static PyObject*
1178 MediaControl_set_visual( PyObject *self, PyObject *args )
1179 {
1180     mediacontrol_Exception* exception = NULL;
1181     WINDOWHANDLE visual;
1182
1183     if( !PyArg_ParseTuple( args, "i", &visual ) )
1184        return NULL;
1185
1186     Py_BEGIN_ALLOW_THREADS
1187     MC_TRY;
1188     mediacontrol_set_visual( SELF->mc, visual, exception );
1189     Py_END_ALLOW_THREADS
1190     MC_EXCEPT;
1191
1192     Py_INCREF( Py_None );
1193     return Py_None;
1194 }
1195
1196 static PyMethodDef MediaControl_methods[] =
1197 {
1198     {"get_media_position", MediaControl_get_media_position, METH_VARARGS,
1199      "get_media_position( origin, key ) -> Position    Get current media position." },
1200     { "set_media_position", MediaControl_set_media_position, METH_VARARGS,
1201       "set_media_position( Position )            Set media position" },
1202     { "start", MediaControl_start, METH_VARARGS,
1203       "start( Position )         Start the player." },
1204     { "pause", MediaControl_pause, METH_VARARGS,
1205       "pause( Position )         Pause the player." },
1206     { "resume", MediaControl_resume, METH_VARARGS,
1207       "resume( Position )        Resume the player" },
1208     { "stop", MediaControl_stop, METH_VARARGS,
1209       "stop( Position )              Stop the player" },
1210     { "exit", MediaControl_exit, METH_VARARGS,
1211       "exit( )                     Exit the player" },
1212     { "playlist_add_item", MediaControl_playlist_add_item, METH_VARARGS,
1213       "playlist_add_item( str )               Add an item to the playlist" },
1214     { "playlist_get_list", MediaControl_playlist_get_list, METH_VARARGS,
1215       "playlist_get_list( ) -> list       Get the contents of the playlist" },
1216     { "playlist_clear", MediaControl_playlist_clear, METH_VARARGS,
1217       "clear( )         Clear the playlist." },
1218     { "snapshot", MediaControl_snapshot, METH_VARARGS,
1219       "snapshot( Position ) -> dict        Take a snapshot" },
1220     { "display_text", MediaControl_display_text, METH_VARARGS,
1221       "display_text( str, Position, Position )    Display a text on the video" },
1222     { "get_stream_information", MediaControl_get_stream_information,
1223       METH_VARARGS,
1224       "get_stream_information( ) -> dict      Get information about the stream"},
1225     { "sound_get_volume", MediaControl_sound_get_volume, METH_VARARGS,
1226       "sound_get_volume( ) -> int       Get the volume" },
1227     { "sound_set_volume", MediaControl_sound_set_volume, METH_VARARGS,
1228       "sound_set_volume( int )           Set the volume" },
1229     { "set_visual", MediaControl_set_visual, METH_VARARGS,
1230       "set_visual( int )           Set the embedding window visual ID" },
1231     { NULL, NULL, 0, NULL },
1232 };
1233
1234 static PyTypeObject MediaControl_Type =
1235 {
1236     PyObject_HEAD_INIT( NULL )
1237     0,                         /*ob_size*/
1238     "vlc.MediaControl",        /*tp_name*/
1239     sizeof( MediaControl_Type ), /*tp_basicsize*/
1240     0,                         /*tp_itemsize*/
1241     ( destructor )MediaControl_dealloc,      /*tp_dealloc*/
1242     0,                         /*tp_print*/
1243     0,                         /*tp_getattr*/
1244     0,                         /*tp_setattr*/
1245     0,                         /*tp_compare*/
1246     0,                         /*tp_repr*/
1247     0,                         /*tp_as_number*/
1248     0,                         /*tp_as_sequence*/
1249     0,                         /*tp_as_mapping*/
1250     0,                         /*tp_hash */
1251     0,                         /*tp_call*/
1252     0,                         /*tp_str*/
1253     0,                         /*tp_getattro*/
1254     0,                         /*tp_setattro*/
1255     0,                         /*tp_as_buffer*/
1256     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1257     "Control of a VLC instance.",  /* tp_doc */
1258     0,                     /* tp_traverse */
1259     0,                     /* tp_clear */
1260     0,                     /* tp_richcompare */
1261     0,                     /* tp_weaklistoffset */
1262     0,                     /* tp_iter */
1263     0,                     /* tp_iternext */
1264     MediaControl_methods,             /* tp_methods */
1265     0,             /* tp_members */
1266     0,                         /* tp_getset */
1267     0,                         /* tp_base */
1268     0,                         /* tp_dict */
1269     0,                         /* tp_descr_get */
1270     0,                         /* tp_descr_set */
1271     0,                         /* tp_dictoffset */
1272     0,                         /* tp_init */
1273     0,                         /* tp_alloc */
1274     MediaControl_new,          /* tp_new */
1275 };
1276
1277 /***********************************************************************
1278  * Position
1279  ***********************************************************************/
1280
1281
1282 static int
1283 PyPosition_init( PyPosition *self, PyObject *args, PyObject *kwds )
1284 {
1285     self->origin = mediacontrol_AbsolutePosition;
1286     self->key    = mediacontrol_MediaTime;
1287     self->value  = 0;
1288     return 0;
1289 }
1290
1291 mediacontrol_PositionKey
1292 positionKey_py_to_c( PyObject * py_key )
1293 {
1294     mediacontrol_PositionKey key_position = mediacontrol_MediaTime;
1295     int key;
1296
1297     if( !PyArg_Parse( py_key, "i", &key ) )
1298     {
1299         PyErr_SetString ( MediaControl_InternalException, "Invalid key value" );
1300         return key_position;
1301     }
1302
1303     switch ( key )
1304     {
1305     case 0: key = mediacontrol_ByteCount;   break;
1306     case 1: key = mediacontrol_SampleCount; break;
1307     case 2: key = mediacontrol_MediaTime;   break;
1308     }
1309     return key_position;
1310 }
1311
1312 mediacontrol_PositionOrigin
1313 positionOrigin_py_to_c( PyObject * py_origin )
1314 {
1315     mediacontrol_PositionOrigin  origin_position = mediacontrol_AbsolutePosition;
1316     int origin;
1317
1318     if( !PyArg_Parse( py_origin,"i", &origin ) )
1319     {
1320         PyErr_SetString( MediaControl_InternalException,
1321                          "Invalid origin value" );
1322         return origin_position;
1323     }
1324
1325     switch ( origin )
1326     {
1327     case 0: origin_position = mediacontrol_AbsolutePosition; break;
1328     case 1: origin_position = mediacontrol_RelativePosition; break;
1329     case 2: origin_position = mediacontrol_ModuloPosition;   break;
1330     }
1331
1332     return origin_position;
1333 }
1334
1335 /* Methods for transforming the Position Python object to Position structure*/
1336 mediacontrol_Position*
1337 position_py_to_c( PyObject * py_position )
1338 {
1339     mediacontrol_Position * a_position = NULL;
1340     PyPosition *pos = ( PyPosition* )py_position;
1341
1342     a_position = ( mediacontrol_Position* )malloc( sizeof( mediacontrol_Position ) );
1343     if( !a_position )
1344     {
1345         PyErr_SetString( PyExc_MemoryError, "Out of memory" );
1346         return NULL;
1347     }
1348
1349     if( !py_position )
1350     {
1351         /* If we give a NULL value, it will be considered as
1352            a 0 relative position in mediatime */
1353         a_position->origin = mediacontrol_RelativePosition;
1354         a_position->key    = mediacontrol_MediaTime;
1355         a_position->value  = 0;
1356     }
1357     else if( PyObject_IsInstance( py_position, ( PyObject* )&PyPosition_Type ) )
1358     {
1359         a_position->origin = pos->origin;
1360         a_position->key    = pos->key;
1361         a_position->value  = pos->value;
1362     }
1363     else
1364     {
1365         /* Feature: if we give an integer, it will be considered as
1366            a relative position in mediatime */
1367         a_position->origin = mediacontrol_RelativePosition;
1368         a_position->key    = mediacontrol_MediaTime;
1369         a_position->value  = PyLong_AsLongLong( py_position );
1370     }
1371     return a_position;
1372 }
1373
1374 PyPosition*
1375 position_c_to_py( mediacontrol_Position *position )
1376 {
1377     PyPosition* py_retval;
1378
1379     py_retval = PyObject_New( PyPosition, &PyPosition_Type );
1380     py_retval->origin = position->origin;
1381     py_retval->key    = position->key;
1382     py_retval->value  = position->value;
1383
1384     return py_retval;
1385 }
1386
1387 static PyMethodDef PyPosition_methods[] =
1388 {
1389     { NULL }  /* Sentinel */
1390 };
1391
1392 static PyMemberDef PyPosition_members[] =
1393 {
1394     { "origin", T_INT, offsetof( PyPosition, origin ), 0, "Position origin" },
1395     { "key",    T_INT, offsetof( PyPosition, key ),    0, "Position key" },
1396     { "value",  T_ULONG, offsetof( PyPosition, value ), 0, "Position value" },
1397     { NULL }  /* Sentinel */
1398 };
1399
1400 static PyTypeObject PyPosition_Type =
1401 {
1402     PyObject_HEAD_INIT( NULL )
1403     0,                         /*ob_size*/
1404     "vlc.Position",            /*tp_name*/
1405     sizeof( PyPosition_Type ),   /*tp_basicsize*/
1406     0,                         /*tp_itemsize*/
1407     0,                         /*tp_dealloc*/
1408     0,                         /*tp_print*/
1409     0,                         /*tp_getattr*/
1410     0,                         /*tp_setattr*/
1411     0,                         /*tp_compare*/
1412     0,                         /*tp_repr*/
1413     0,                         /*tp_as_number*/
1414     0,                         /*tp_as_sequence*/
1415     0,                         /*tp_as_mapping*/
1416     0,                         /*tp_hash */
1417     0,                         /*tp_call*/
1418     0,                         /*tp_str*/
1419     0,                         /*tp_getattro*/
1420     0,                         /*tp_setattro*/
1421     0,                         /*tp_as_buffer*/
1422     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
1423     "Represent a Position with origin, key and value",  /* tp_doc */
1424     0,                        /* tp_traverse */
1425     0,                        /* tp_clear */
1426     0,                         /* tp_richcompare */
1427     0,                         /* tp_weaklistoffset */
1428     0,                         /* tp_iter */
1429     0,                          /* tp_iternext */
1430     PyPosition_methods,             /* tp_methods */
1431     PyPosition_members,             /* tp_members */
1432     0,                         /* tp_getset */
1433     0,                         /* tp_base */
1434     0,                         /* tp_dict */
1435     0,                         /* tp_descr_get */
1436     0,                         /* tp_descr_set */
1437     0,                         /* tp_dictoffset */
1438     ( initproc )PyPosition_init, /* tp_init */
1439     0,                         /* tp_alloc */
1440     0,                         /* tp_new */
1441 };