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