]> git.sesse.net Git - vlc/blob - bindings/python/vlc_object.c
A bit of vlc/libvlc cleanup:
[vlc] / bindings / python / vlc_object.c
1 /*****************************************************************************
2  * vlc_object.c: vlc.Object
3  *****************************************************************************
4  * Copyright (C) 2006 the VideoLAN team
5  * $Id: $
6  *
7  * Authors: Olivier Aubert <oaubert at bat710.univ-lyon1.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /* We need to access some internal features of VLC */
25 /* Gruik ! */
26 #define __LIBVLC__
27
28 /* Even gruiker ! We access variable_t ! */
29 #include "../../src/misc/variables.h"
30
31 #include "vlcglue.h"
32
33 /*****************************************************************************
34  * VLCObject implementation
35  *****************************************************************************/
36
37 static PyObject
38 *vlcObject_new( PyTypeObject *p_type, PyObject *p_args, PyObject *p_kwds )
39 {
40     vlcObject *self;
41     vlc_object_t *p_object;
42     int i_id;
43
44     self = PyObject_New( vlcObject, &vlcObject_Type );
45
46     if( !PyArg_ParseTuple( p_args, "i", &i_id ) )
47       return NULL;
48
49     /* Maybe we were already initialized */
50     p_object = ( vlc_object_t* )vlc_current_object( i_id );
51
52     if( !p_object )
53     {
54         /* Try to initialize */
55         i_id = VLC_Create();
56         if( i_id < 0 )
57         {
58             PyErr_SetString( PyExc_StandardError, "Unable to create a VLC instance." );
59             return NULL;
60         }
61         p_object = ( vlc_object_t* )vlc_current_object( i_id );
62     }
63
64     if( !p_object )
65     {
66         PyErr_SetString( PyExc_StandardError, "Unable to get object." );
67         return NULL;
68     }
69
70     self->p_object = p_object;
71     self->b_released = 0;
72
73     Py_INCREF(  self ); /* Ah bon ? */
74     return ( PyObject * )self;
75 }
76
77 static PyObject *
78 vlcObject_release(  PyObject *self, PyObject *p_args )
79 {
80     if( VLCSELF->b_released == 0 )
81     {
82         vlc_object_release( VLCSELF->p_object );
83         VLCSELF->b_released = 1;
84     }
85     Py_INCREF(  Py_None );
86     return Py_None;
87 }
88
89 static void
90 vlcObject_dealloc( PyObject *self )
91 {
92     vlcObject_release( self, NULL );
93     PyMem_DEL( self );
94 }
95
96 static PyObject *
97 vlcObject_find_object( PyObject *self, PyObject *args )
98 {
99     vlcObject *p_retval;
100     vlc_object_t *p_obj;
101     char *psz_name;
102     int i_object_type;
103
104     if( !PyArg_ParseTuple( args, "s", &psz_name ) )
105         return NULL;
106
107     /* psz_name is in
108        ( aout, decoder, input, httpd, intf, playlist, root, vlc, vout )
109     */
110     if( !strncmp( psz_name, "aout", 4 ) )
111     {
112         i_object_type = VLC_OBJECT_AOUT;
113     }
114     else if (! strncmp( psz_name, "decoder", 7 ) )
115     {
116         i_object_type = VLC_OBJECT_DECODER;
117     }
118     else if (! strncmp( psz_name, "httpd", 5 ) )
119     {
120             i_object_type = VLC_OBJECT_HTTPD;
121     }
122     else if (! strncmp( psz_name, "intf", 4 ) )
123     {
124         i_object_type = VLC_OBJECT_INTF;
125     }
126     else if (! strncmp( psz_name, "input", 5 ) )
127     {
128         i_object_type = VLC_OBJECT_INPUT;
129     }
130     else if (! strncmp( psz_name, "playlist", 8 ) )
131     {
132         i_object_type = VLC_OBJECT_PLAYLIST;
133     }
134     else if (! strncmp( psz_name, "libvlc", 6 ) )
135     {
136         i_object_type = VLC_OBJECT_LIBVLC;
137     }
138     else if (! strncmp( psz_name, "vout", 4 ) )
139     {
140         i_object_type = VLC_OBJECT_VOUT;
141     }
142     else if (! strncmp( psz_name, "sout", 4 ) )
143     {
144         i_object_type = VLC_OBJECT_SOUT;
145     }
146     else if (! strncmp( psz_name, "global", 6 ) )
147     {
148         i_object_type = VLC_OBJECT_GLOBAL;
149     }
150     else if (! strncmp( psz_name, "packetizer", 10 ) )
151     {
152         i_object_type = VLC_OBJECT_PACKETIZER;
153     }
154     else if (! strncmp( psz_name, "encoder", 7 ) )
155     {
156         i_object_type = VLC_OBJECT_ENCODER;
157     }
158     else if (! strncmp( psz_name, "vlm", 3 ) )
159     {
160         i_object_type = VLC_OBJECT_VLM;
161     }
162     else if (! strncmp( psz_name, "announce", 8 ) )
163     {
164         i_object_type = VLC_OBJECT_ANNOUNCE;
165     }
166     else if (! strncmp( psz_name, "demux", 5 ) )
167     {
168         i_object_type = VLC_OBJECT_DEMUX;
169     }
170     else if (! strncmp( psz_name, "access", 6 ) )
171     {
172         i_object_type = VLC_OBJECT_ACCESS;
173     }
174     else if (! strncmp( psz_name, "stream", 6 ) )
175     {
176         i_object_type = VLC_OBJECT_STREAM;
177     }
178     else if (! strncmp( psz_name, "filter", 6 ) )
179     {
180         i_object_type = VLC_OBJECT_FILTER;
181     }
182     else if (! strncmp( psz_name, "vod", 3 ) )
183     {
184         i_object_type = VLC_OBJECT_VOD;
185     }
186     else if (! strncmp( psz_name, "xml", 3 ) )
187     {
188         i_object_type = VLC_OBJECT_XML;
189     }
190     else if (! strncmp( psz_name, "osdmenu", 7 ) )
191     {
192         i_object_type = VLC_OBJECT_OSDMENU;
193     }
194     else if (! strncmp( psz_name, "stats", 5 ) )
195     {
196         i_object_type = VLC_OBJECT_STATS;
197     }
198     else if (! strncmp( psz_name, "metaengine", 10 ) )
199     {
200         i_object_type = VLC_OBJECT_META_ENGINE;
201     }
202     else
203     {
204         /* FIXME: raise an exception ? */
205         Py_INCREF( Py_None );
206         return Py_None;
207     }
208
209     p_obj = vlc_object_find( VLCSELF->p_object, i_object_type, FIND_ANYWHERE );
210
211     if( !p_obj )
212     {
213         Py_INCREF( Py_None );
214         return Py_None;
215     }
216
217     p_retval = PyObject_New( vlcObject, &vlcObject_Type );
218
219     p_retval->p_object = p_obj;
220
221     return ( PyObject * )p_retval;
222 }
223
224 static PyObject *
225 vlcObject_info( PyObject *self, PyObject *args )
226 {
227     PyObject *p_retval;
228     vlc_object_t *p_obj;
229
230     p_obj = VLCSELF->p_object;
231
232     /* Return information about the object as a dict. */
233     p_retval = PyDict_New();
234
235     PyDict_SetItemString( p_retval, "object-id",
236                           Py_BuildValue( "l", p_obj->i_object_id ) );
237     PyDict_SetItemString( p_retval, "object-type",
238                           Py_BuildValue( "s", p_obj->psz_object_type ) );
239     PyDict_SetItemString( p_retval, "object-name",
240                           Py_BuildValue( "s", p_obj->psz_object_name ) );
241     PyDict_SetItemString( p_retval, "thread",
242                           PyBool_FromLong( p_obj->b_thread ) );
243     PyDict_SetItemString( p_retval, "thread-id",
244                           PyLong_FromLongLong( p_obj->thread_id ) );
245     PyDict_SetItemString( p_retval, "refcount",
246                           PyInt_FromLong( p_obj->i_refcount ) );
247
248     return p_retval;
249 }
250
251 static PyObject *
252 vlcObject_find_id( PyObject *self, PyObject *args )
253 {
254     vlcObject *p_retval;
255     vlc_object_t* p_object;
256     int i_id;
257
258     if( !PyArg_ParseTuple( args, "i", &i_id ) )
259         return NULL;
260
261     p_object = ( vlc_object_t* )vlc_current_object( i_id );
262
263     if( !p_object )
264     {
265         Py_INCREF( Py_None );
266         return Py_None;
267     }
268
269     p_retval = PyObject_NEW( vlcObject, &vlcObject_Type );
270
271     p_retval->p_object = p_object;
272
273     return ( PyObject * )p_retval;
274 }
275
276 /* Do a var_Get call on the object. Parameter: the variable name. */
277 static PyObject *
278 vlcObject_var_get( PyObject *self, PyObject *args )
279 {
280     PyObject *p_retval;
281     vlc_value_t value;
282     char *psz_name;
283     int i_type;
284
285     if( !PyArg_ParseTuple( args, "s", &psz_name ) )
286         return NULL;
287
288     if( var_Get( VLCSELF->p_object, psz_name, &value ) != VLC_SUCCESS )
289     {
290         PyErr_SetString( PyExc_StandardError,
291                          "Error: variable does not exist.\n" );
292         return NULL;
293     }
294
295     i_type = var_Type ( VLCSELF->p_object, psz_name );
296
297     switch ( i_type )
298     {
299     case VLC_VAR_VOID      :
300         p_retval = PyString_FromString( "A void variable" );
301         break;
302     case VLC_VAR_BOOL      :
303         p_retval = PyBool_FromLong( value.b_bool );
304         break;
305     case VLC_VAR_INTEGER   :
306         p_retval = PyInt_FromLong( ( long )value.i_int );
307         break;
308     case VLC_VAR_HOTKEY    :
309         p_retval = PyString_FromFormat( "A hotkey variable ( %d )", value.i_int );
310         break;
311     case VLC_VAR_FILE      :
312     case VLC_VAR_STRING    :
313     case VLC_VAR_DIRECTORY :
314     case VLC_VAR_VARIABLE  :
315         p_retval = PyString_FromString( value.psz_string );
316         break;
317     case VLC_VAR_MODULE   :
318         p_retval = ( PyObject* )PyObject_New( vlcObject, &vlcObject_Type );
319         ( ( vlcObject* )p_retval )->p_object = value.p_object;
320         break;
321     case VLC_VAR_FLOAT     :
322         p_retval = PyFloat_FromDouble( ( double )value.f_float );
323         break;
324     case VLC_VAR_TIME      :
325         p_retval = PyLong_FromLongLong( value.i_time );
326         break;
327     case VLC_VAR_ADDRESS   :
328         p_retval = PyString_FromString( "A VLC address ( not handled yet )" );
329         break;
330     case VLC_VAR_LIST      :
331         p_retval = PyString_FromString( "A VLC list ( not handled yet )" );
332         break;
333     case VLC_VAR_MUTEX :
334         p_retval = PyString_FromString( "A mutex" );
335         break;
336     default:
337         p_retval = Py_None;
338     }
339
340     Py_INCREF( p_retval );
341     return p_retval;
342 }
343
344 static PyObject *
345 vlcObject_var_type( PyObject *self, PyObject *args )
346 {
347     char *psz_name;
348     PyObject *p_retval;
349     int i_type;
350
351     if( !PyArg_ParseTuple( args, "s", &psz_name ) )
352         return NULL;
353
354     i_type = var_Type( VLCSELF->p_object, psz_name );
355
356     switch ( i_type )
357     {
358     case VLC_VAR_VOID   :
359         p_retval = PyString_FromString( "Void" );
360         break;
361     case VLC_VAR_BOOL      :
362         p_retval = PyString_FromString( "Boolean" );
363         break;
364     case VLC_VAR_INTEGER   :
365         p_retval = PyString_FromString( "Integer" );
366         break;
367     case VLC_VAR_HOTKEY   :
368         p_retval = PyString_FromString( "Hotkey" );
369         break;
370     case VLC_VAR_FILE      :
371         p_retval = PyString_FromString( "File" );
372         break;
373     case VLC_VAR_STRING    :
374         p_retval = PyString_FromString( "String" );
375         break;
376     case VLC_VAR_DIRECTORY :
377         p_retval = PyString_FromString( "Directory" );
378         break;
379     case VLC_VAR_VARIABLE  :
380         p_retval = PyString_FromString( "Variable" );
381         break;
382     case VLC_VAR_MODULE   :
383         p_retval = PyString_FromString( "Module" );
384         break;
385     case VLC_VAR_FLOAT     :
386         p_retval = PyString_FromString( "Float" );
387         break;
388     case VLC_VAR_TIME      :
389         p_retval = PyString_FromString( "Time" );
390         break;
391     case VLC_VAR_ADDRESS   :
392         p_retval = PyString_FromString( "Address" );
393         break;
394     case VLC_VAR_LIST      :
395         p_retval = PyString_FromString( "List" );
396         break;
397     case VLC_VAR_MUTEX :
398         p_retval = PyString_FromString( "Mutex" );
399         break;
400     default:
401         p_retval = PyString_FromString( "Unknown" );
402     }
403     return p_retval;
404 }
405
406 /* Do a var_Set call on the object. Parameter: the variable name. */
407 static PyObject *
408 vlcObject_var_set( PyObject *self, PyObject *args )
409 {
410     vlc_value_t value;
411     char *psz_name;
412     PyObject *py_value;
413     int i_type;
414     vlc_object_t *p_obj;
415
416     if( !PyArg_ParseTuple( args, "sO", &psz_name, &py_value ) )
417         return NULL;
418
419     p_obj = VLCSELF->p_object;
420     i_type = var_Type( p_obj, psz_name );
421
422     switch ( i_type )
423     {
424     case VLC_VAR_VOID   :
425         break;
426     case VLC_VAR_BOOL      :
427         value.b_bool = PyInt_AsLong( py_value );
428         break;
429     case VLC_VAR_INTEGER   :
430     case VLC_VAR_HOTKEY   :
431         value.i_int = PyInt_AsLong( py_value );
432         break;
433     case VLC_VAR_FILE      :
434     case VLC_VAR_STRING    :
435     case VLC_VAR_DIRECTORY :
436     case VLC_VAR_VARIABLE  :
437         value.psz_string = strdup( PyString_AsString( py_value ) );
438         break;
439     case VLC_VAR_MODULE   :
440         /* FIXME: we should check the PyObject type and get its p_object */
441         value.p_object = ( ( vlcObject* )p_obj )->p_object;
442         break;
443     case VLC_VAR_FLOAT     :
444         value.f_float = PyFloat_AsDouble( py_value );
445         break;
446     case VLC_VAR_TIME      :
447         value.i_time = PyLong_AsLongLong( py_value );
448         break;
449     case VLC_VAR_ADDRESS   :
450         value.p_address = ( char* )PyLong_AsVoidPtr( py_value );
451         break;
452     case VLC_VAR_LIST      :
453         /* FIXME */
454         value.p_list = NULL;
455         break;
456     case VLC_VAR_MUTEX :
457         break;
458     }
459
460     var_Set( p_obj, psz_name, value );
461
462     Py_INCREF( Py_None );
463     return Py_None;
464 }
465
466 static PyObject *
467 vlcObject_var_list( PyObject *self, PyObject *args )
468 {
469     PyObject *p_retval;
470     int i_size;
471     int i_index;
472
473     i_size = VLCSELF->p_object->i_vars;
474     p_retval = PyTuple_New( i_size );
475
476     for ( i_index = 0 ; i_index < i_size ; i_index++ )
477     {
478         PyTuple_SetItem( p_retval, i_index,
479                          Py_BuildValue( "s", VLCSELF->p_object->p_vars[i_index].psz_name ) );
480     }
481
482     return p_retval;
483 }
484
485 /* Do a config_Get call on the object. Parameter: the variable name. */
486 static PyObject *
487 vlcObject_config_get( PyObject *self, PyObject *args )
488 {
489     PyObject *p_retval;
490     vlc_value_t value;
491     char *psz_name;
492     module_config_t *p_config;
493
494     if( !PyArg_ParseTuple( args, "s", &psz_name ) )
495         return NULL;
496
497     p_config = config_FindConfig( VLCSELF->p_object, psz_name );
498
499     if( !p_config )
500     {
501         PyErr_SetString( PyExc_StandardError,
502                          "Error: config variable does not exist.\n" );
503         return NULL;
504     }
505
506     switch ( p_config->i_type )
507     {
508     case CONFIG_ITEM_BOOL      :
509         p_retval = PyBool_FromLong( p_config->value.i );
510         break;
511     case CONFIG_ITEM_INTEGER   :
512         p_retval = PyInt_FromLong( ( long )p_config->value.i );
513         break;
514     case CONFIG_ITEM_KEY   :
515         p_retval = PyString_FromFormat( "A hotkey variable ( %d )", p_config->value.i );
516         break;
517     case CONFIG_ITEM_FILE      :
518     case CONFIG_ITEM_STRING    :
519     case CONFIG_ITEM_DIRECTORY :
520     case CONFIG_ITEM_MODULE    :
521         vlc_mutex_lock( p_config->p_lock );
522         if( p_config->value.psz )
523             p_retval = PyString_FromString( p_config->value.psz );
524         else
525             p_retval = PyString_FromString( "" );
526         vlc_mutex_unlock( p_config->p_lock );
527         break;
528         p_retval = ( PyObject* )PyObject_New( vlcObject, &vlcObject_Type );
529         ( ( vlcObject* )p_retval )->p_object = value.p_object;
530         break;
531     case CONFIG_ITEM_FLOAT     :
532         p_retval = PyFloat_FromDouble( ( double )p_config->value.f );
533         break;
534     default:
535         p_retval = Py_None;
536         Py_INCREF( p_retval );
537     }
538
539     return p_retval;
540 }
541
542 /* Do a config_put* call on the object. Parameter: the variable name. */
543 static PyObject *
544 vlcObject_config_set( PyObject *self, PyObject *args )
545 {
546     char *psz_name;
547     PyObject *py_value;
548     vlc_object_t *p_obj;
549     module_config_t *p_config;
550
551
552     if( !PyArg_ParseTuple( args, "sO", &psz_name, &py_value ) )
553         return NULL;
554
555     p_obj = VLCSELF->p_object;
556     p_config = config_FindConfig( p_obj, psz_name );
557     /* sanity checks */
558     if( !p_config )
559     {
560         PyErr_SetString( PyExc_StandardError,
561                          "Error: option does not exist.\n" );
562         return NULL;
563     }
564
565     switch ( p_config->i_type )
566     {
567     case CONFIG_ITEM_BOOL      :
568     case CONFIG_ITEM_INTEGER   :
569     case CONFIG_ITEM_KEY       :
570         config_PutInt( p_obj, psz_name, PyInt_AsLong( py_value ) );
571         break;
572     case CONFIG_ITEM_FILE      :
573     case CONFIG_ITEM_STRING    :
574     case CONFIG_ITEM_DIRECTORY :
575     case CONFIG_ITEM_MODULE   :
576         config_PutPsz( p_obj, psz_name, PyString_AsString( py_value ) );
577         break;
578     case CONFIG_ITEM_FLOAT     :
579         config_PutFloat( p_obj, psz_name, PyFloat_AsDouble( py_value ) );
580         break;
581     }
582     Py_INCREF( Py_None );
583     return Py_None;
584 }
585
586 static PyObject *
587 vlcObject_children( PyObject *self, PyObject *args )
588 {
589     PyObject *p_retval;
590     int i_size;
591     int i_index;
592
593     i_size = VLCSELF->p_object->i_children;
594     p_retval = PyTuple_New( i_size );
595
596     for ( i_index = 0 ; i_index < i_size ; i_index++ )
597     {
598         PyTuple_SetItem( p_retval, i_index,
599                          Py_BuildValue( "i",
600                                         VLCSELF->p_object->pp_children[i_index]->i_object_id ) );
601     }
602
603     return p_retval;
604 }
605
606
607 /* Method table */
608 static PyMethodDef vlcObject_methods[] =
609 {
610     { "get", vlcObject_var_get, METH_VARARGS,
611       "get( str ) -> value   Get a variable value."},
612     { "set", vlcObject_var_set, METH_VARARGS,
613       "set( str, value )     Set a variable value" },
614     { "config_get", vlcObject_config_get, METH_VARARGS,
615       "config_get( str ) -> value   Get a configuration option." },
616     { "config_set", vlcObject_config_set, METH_VARARGS,
617       "config_set( str, value )     Set a configuration option" },
618     { "type", vlcObject_var_type, METH_VARARGS,
619       "type( str ) -> str     Get a variable type" },
620     { "list", vlcObject_var_list, METH_NOARGS,
621       "list( )             List the available variables" },
622     { "children", vlcObject_children, METH_NOARGS,
623       "children( )             List the children ids" },
624     { "find_object", vlcObject_find_object, METH_VARARGS,
625       "find_object( str ) -> Object     Find the object of a given type.\n\nAvailable types are : aout, decoder, input, httpd, intf, playlist, root, vlc, vout"},
626     { "find_id", vlcObject_find_id, METH_VARARGS,
627       "find_id( int ) -> Object      Find an object by id" },
628     { "info", vlcObject_info, METH_NOARGS,
629        "info( ) -> dict    Return information about the object" },
630     { "release", vlcObject_release, METH_NOARGS,
631       "release( ) ->     Release the VLC Object" },
632     { NULL, NULL, 0, NULL },
633 };
634
635 static PyTypeObject vlcObject_Type =
636 {
637     PyObject_HEAD_INIT( NULL )
638     0,                         /*ob_size*/
639     "vlc.Object",       /*tp_name*/
640     sizeof( vlcObject_Type ), /*tp_basicsize*/
641     0,                         /*tp_itemsize*/
642     ( destructor )vlcObject_dealloc,      /*tp_dealloc*/
643     0,                         /*tp_print*/
644     0,                         /*tp_getattr*/
645     0,                         /*tp_setattr*/
646     0,                         /*tp_compare*/
647     0,                         /*tp_repr*/
648     0,                         /*tp_as_number*/
649     0,                         /*tp_as_sequence*/
650     0,                         /*tp_as_mapping*/
651     0,                         /*tp_hash */
652     0,                         /*tp_call*/
653     0,                         /*tp_str*/
654     0,                         /*tp_getattro*/
655     0,                         /*tp_setattro*/
656     0,                         /*tp_as_buffer*/
657     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
658     "Expose VLC object infrastructure.\n\nConstructor: vlc.Object(object_id)",  /* tp_doc */
659     0,                     /* tp_traverse */
660     0,                     /* tp_clear */
661     0,                     /* tp_richcompare */
662     0,                     /* tp_weaklistoffset */
663     0,                     /* tp_iter */
664     0,                     /* tp_iternext */
665     vlcObject_methods,             /* tp_methods */
666     0,             /* tp_members */
667     0,                         /* tp_getset */
668     0,                         /* tp_base */
669     0,                         /* tp_dict */
670     0,                         /* tp_descr_get */
671     0,                         /* tp_descr_set */
672     0,                         /* tp_dictoffset */
673     0,                         /* tp_init */
674     0,                         /* tp_alloc */
675     vlcObject_new,          /* tp_new */
676 };