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