gst/: Let's split up gst.override,
authorEdward Hervey <bilboed@bilboed.com>
Wed, 28 Sep 2005 14:34:52 +0000 (14:34 +0000)
committerEdward Hervey <bilboed@bilboed.com>
Wed, 28 Sep 2005 14:34:52 +0000 (14:34 +0000)
Original commit message from CVS:
* gst/Makefile.am:
* gst/gst.override:
* gst/gsttaglist.override:
* gst/gstobject.override:
Let's split up gst.override,
Added gsttaglist.override and gstobject.override
* gst/arg-types.py:
* gst/gst-argtypes.c:
Cleanup, removed deprecated GstData related functions
* gst/gst-extrafuncs.defs:
* gst/gst.defs:
Moved debug functions to gst-extrafuncs.defs

ChangeLog
gst/Makefile.am
gst/arg-types.py
gst/gst-argtypes.c
gst/gst-extrafuncs.defs
gst/gst.defs
gst/gst.override
gst/gstobject.override [new file with mode: 0644]
gst/gsttaglist.override [new file with mode: 0644]

index 43f2991..1018361 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2005-09-28  Edward Hervey  <edward@fluendo.com>
+
+       * gst/Makefile.am:
+       * gst/gst.override:
+       * gst/gsttaglist.override:
+       * gst/gstobject.override:
+       Let's split up gst.override,
+       Added gsttaglist.override and gstobject.override
+       
+       * gst/arg-types.py:
+       * gst/gst-argtypes.c:
+       Cleanup, removed deprecated GstData related functions
+       * gst/gst-extrafuncs.defs:
+       * gst/gst.defs:
+       Moved debug functions to gst-extrafuncs.defs
+
 2005-09-28  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        * gst/gst.defs:
index 1b1453b..b2951bb 100644 (file)
@@ -44,9 +44,11 @@ GST_OVERRIDES =              \
        gstcaps.override        \
        gstelement.override     \
        gstmessage.override     \
+       gstobject.override      \
        gstquery.override       \
        gstpad.override         \
        gststructure.override   \
+       gsttaglist.override     \
        gstlibs.override
 
 GST_DEFS = gst.defs gst-types.defs gst-extrafuncs.defs libs.defs
index f6b9d54..1b45c2c 100644 (file)
 
 from argtypes import UInt64Arg, Int64Arg, PointerArg, ArgMatcher, ArgType, matcher
 
-class GstDataPtrArg(ArgType):
-    normal = ('    if (!pygst_data_from_pyobject(py_%(name)s, &%(name)s))\n'
-              '        return NULL;\n'
-              '    gst_data_ref (%(name)s);\n')
-    null =   ('    if (py_%(name)s == Py_None)\n'
-              '        %(name)s = NULL;\n'
-              '    else if (pyst_data_from_pyobject(py_%(name)s, %(name)s_rect))\n'
-              '        %(name)s = &%(name)s_rect;\n'
-              '    else\n'
-              '            return NULL;\n'
-              '    gst_data_ref (%(name)s);\n')
-    def write_param(self, ptype, pname, pdflt, pnull, info):
-        if pnull:
-            info.varlist.add('GstData', pname + '_data')
-            info.varlist.add('GstData', '*' + pname)
-            info.varlist.add('PyObject', '*py_' + pname + ' = Py_None')
-            info.add_parselist('O', ['&py_' + pname], [pname])
-            info.arglist.append(pname)
-            info.codebefore.append(self.null % {'name':  pname})
-        else:
-            info.varlist.add('GstData*', pname)
-            info.varlist.add('PyObject', '*py_' + pname)
-            info.add_parselist('O', ['&py_' + pname], [pname])
-            info.arglist.append(pname)
-            info.codebefore.append(self.normal % {'name':  pname})
-
 class XmlNodeArg(ArgType):
        """libxml2 node generator"""
        
@@ -155,7 +129,6 @@ class GstCapsArg(ArgType):
             raise RuntimeError, "write_return not implemented for %s" % ptype
                info.codeafter.append('    return pyg_boxed_new (GST_TYPE_CAPS, ret, '+copyval+', TRUE);')
                        
-matcher.register('GstData*', GstDataPtrArg())
 matcher.register('GstClockTime', UInt64Arg())
 matcher.register('GstClockTimeDiff', Int64Arg())
 matcher.register('xmlNodePtr', XmlNodeArg())
index e24a716..c35acc5 100644 (file)
 #include <gst/gst.h>
 #include "common.h"
 
-/* gboolean */
-/* pygst_data_from_pyobject(PyObject *object, GstData **data) */
-/* { */
-/*   if (pyg_boxed_check(object, GST_TYPE_DATA)) { */
-/*     *data = pyg_boxed_get(object, GstData); */
-/*     return TRUE; */
-/*   } else if (pyg_boxed_check(object, GST_TYPE_BUFFER)) { */
-/*     *data = GST_DATA (pyg_boxed_get(object, GstBuffer)); */
-/*     return TRUE; */
-/*   } else if (pyg_boxed_check(object, GST_TYPE_EVENT)) { */
-/*     *data = GST_DATA (pyg_boxed_get(object, GstEvent)); */
-/*     return TRUE; */
-/*   } */
-  
-/*   PyErr_Clear(); */
-/*   PyErr_SetString(PyExc_TypeError, "could not convert to GstData"); */
-/*   return FALSE; */
-/* } */
-
-/* static PyObject * */
-/* PyGstData_from_value(const GValue *value) */
-/* { */
-/*   GstData *data = (GstData *)g_value_get_boxed(value); */
-
-/*   return pyg_boxed_new(GST_TYPE_DATA, data, TRUE, TRUE); */
-/* } */
-
-/* static int */
-/* PyGstData_to_value(GValue *value, PyObject *object) */
-/* { */
-/*   GstData* data; */
-
-/*   if (!pygst_data_from_pyobject(object, &data)) */
-/*     return -1; */
-  
-/*   g_value_set_boxed(value, data); */
-/*   return 0; */
-/* } */
-
 /* This function will return a copy, unless the following is all TRUE:
  * - The given PyObject contains a GstCaps already
  * - The copy parameter is non-NULL
@@ -103,10 +64,3 @@ pygst_caps_from_pyobject (PyObject *object, gboolean *copy)
   return NULL;
 }
 
-/* void */
-/* _pygst_register_boxed_types(PyObject *moddict) */
-/* { */
-/*     pyg_register_boxed_custom(GST_TYPE_DATA, */
-/*                           PyGstData_from_value, */
-/*                           PyGstData_to_value); */
-/* } */
index c9e10b8..82d55e9 100644 (file)
   (parameters
    '("GstObjectFlags" "flag")
    )
-)
\ No newline at end of file
+)
+
+;; DEBUGGING FUNCTIONS FROM PYTHON
+;; The c functions don't actually exist
+
+(define-function log
+  (c-name "gst_log")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+(define-function debug
+  (c-name "gst_debug")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+(define-function info
+  (c-name "gst_info")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+(define-function warning
+  (c-name "gst_warning")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+(define-function error
+  (c-name "gst_error")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+;; OBJECT DEBUGGING FUNCTIONS FROM PYTHON
+;; The c functions don't actually exist
+
+(define-method log
+  (of-object "GstObject")
+  (c-name "gst_object_log")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+(define-method debug
+  (of-object "GstObject")
+  (c-name "gst_object_debug")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+(define-method info
+  (of-object "GstObject")
+  (c-name "gst_object_info")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+(define-method warning
+  (of-object "GstObject")
+  (c-name "gst_object_warning")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
+
+(define-method error
+  (of-object "GstObject")
+  (c-name "gst_object_error")
+  (return-type "none")
+  (parameters
+   '("gchar *" "msg")
+   )
+)
index 978368a..d921d3b 100644 (file)
   )
 )
 
-;; DEBUGGING FUNCTIONS FROM PYTHON
-;; The c functions don't actually exist
-
-(define-function log
-  (c-name "gst_log")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
-(define-function debug
-  (c-name "gst_debug")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
-(define-function info
-  (c-name "gst_info")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
-(define-function warning
-  (c-name "gst_warning")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
-(define-function error
-  (c-name "gst_error")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
 ;; From ../gstreamer/gst/gstinterface.h
 
 (define-function gst_implements_interface_get_type
   )
 )
 
-;; OBJECT DEBUGGING FUNCTIONS FROM PYTHON
-;; The c functions don't actually exist
-
-(define-method log
-  (of-object "GstObject")
-  (c-name "gst_object_log")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
-(define-method debug
-  (of-object "GstObject")
-  (c-name "gst_object_debug")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
-(define-method info
-  (of-object "GstObject")
-  (c-name "gst_object_info")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
-(define-method warning
-  (of-object "GstObject")
-  (c-name "gst_object_warning")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
-(define-method error
-  (of-object "GstObject")
-  (c-name "gst_object_error")
-  (return-type "none")
-  (parameters
-   '("gchar *" "msg")
-   )
-)
-
 ;; From ../gstreamer/gst/gstpad.h
 
 (define-function gst_pad_get_type
index f1df5f5..1d93e8f 100644 (file)
@@ -253,14 +253,16 @@ pygst_debug_log (PyObject *pyobject, PyObject *string, GstDebugLevel level,
 include
   gstbin.override
   gstbuffer.override
-  gstevent.override
-  gstcaps.override
   gstbus.override
+  gstcaps.override
   gstelement.override
+  gstevent.override
   gstmessage.override
-  gstquery.override
+  gstobject.override
   gstpad.override
+  gstquery.override
   gststructure.override
+  gsttaglist.override
   gstlibs.override
 %%
 init
@@ -292,398 +294,14 @@ ignore-glob
   gst_class_*
   gst_init*
   gst_interface_*
-  gst_tag_list_get_*
   gst_value_*
 %%
 ignore
   gst_alloc_trace_list
   gst_alloc_trace_get
   gst_error_get_message
-  gst_object_default_deep_notify
-  gst_object_check_uniqueness
-  gst_object_replace
   gst_parse_launchv
-  gst_tag_list_add
-  gst_tag_list_add_values
-  gst_tag_list_add_valist_values
-  gst_tag_list_copy_value
   gst_trace_read_tsc
-
-
-%%
-define GstTagList.keys noargs
-void
-tag_foreach_func_dict (const GstTagList *list,
-                      const gchar      *tag,
-                      PyObject         *dict)
-{
-       int count;
-       guint i;
-       const GValue *gvalue;
-       PyObject *value;
-       gchar *key;
-    
-       count = gst_tag_list_get_tag_size(GST_TAG_LIST(list), tag);
-
-       for (i = 0; i < count; i++) {
-               gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(list), tag, i);
-               value = pygst_value_as_pyobject(gvalue, TRUE);
-               key = g_strdup (tag);
-               PyDict_SetItemString(dict, key, value);
-               g_free (key);
-               Py_DECREF(value);
-       }
-}
-void
-tag_foreach_func_list (const GstTagList *list,
-                      const gchar      *tag,
-                      PyObject         *py_list)
-{
-       int count;
-    
-       count = gst_tag_list_get_tag_size(GST_TAG_LIST(list), tag);
-       if (count == 0)
-               PyErr_SetString(PyExc_KeyError, tag);
-       else if (count == 1)
-               PyList_Append(py_list, PyString_FromString(tag));
-#if 0  
-       else if (count > 1)
-               PyErr_SetString(PyExc_TypeError, "lists are currently unspported");
-#endif
-       
-}
-
-static PyObject*
-_wrap_gst_tag_list_keys(PyGObject *self)
-{
-       PyObject *dict;
-
-       dict = PyList_New(0);
-    
-       gst_tag_list_foreach(GST_TAG_LIST(self->obj),
-                            (GstTagForeachFunc)tag_foreach_func_list,
-                            (gpointer)dict);
-       return dict;
-}
-%%
-override-slot GstTagList.tp_as_mapping
-static int
-_wrap_gst_tag_list_length(PyGObject *self)
-{
-       return gst_structure_n_fields((GstStructure*)self->obj);
-}
-
-static PyObject *
-_wrap_gst_tag_list_subscript(PyGObject *self, PyObject *py_key)
-{
-       PyObject *v = NULL;
-       char *key = PyString_AsString(py_key);
-       
-       int count = gst_tag_list_get_tag_size(GST_TAG_LIST(self->obj), key);
-       if (count == 0) {
-               PyErr_SetObject(PyExc_KeyError, py_key);
-       } else if (count == 1) {
-               const GValue *gvalue;
-               gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
-               v = pygst_value_as_pyobject(gvalue, TRUE);
-       } else {
-               PyErr_SetString(PyExc_TypeError, "lists are currently unspported");
-       }
-               
-       if (v != NULL)
-               Py_INCREF(v);
-       return v;
-}
-
-static PySequenceMethods _wrap_gst_tag_list_tp_as_mapping = {
-       (inquiry)_wrap_gst_tag_list_length,         /* mp_length */
-       (binaryfunc)_wrap_gst_tag_list_subscript,   /* mp_subscript */
-       NULL,
-};
-
-%%
-define GstTagList.has_key args
-static PyObject*
-_wrap_gst_tag_list_has_key(PyGObject *self, PyObject *args)
-{
-       gchar *key;
-       const GValue *gvalue;
-    
-       if (!PyArg_ParseTuple(args, "s:GstTagList.has_key", &key))
-               return NULL;
-
-       gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
-
-       return PyInt_FromLong(gvalue != NULL);
-}    
-%%
-define GstTagList.get
-static PyObject *
-_wrap_gst_tag_list_get(PyGObject *self, PyObject *args)
-{
-       char *key;
-       PyObject *failobj = Py_None;
-       PyObject *val = NULL;
-       const GValue *gvalue;
-       
-       if (!PyArg_ParseTuple(args, "s|O:GstTagList.get", &key, &failobj))
-               return NULL;
-
-       gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
-       if (gvalue != NULL) {
-               int count = gst_tag_list_get_tag_size(GST_TAG_LIST(self->obj), key);
-               if (count == 0) {
-                       PyErr_SetString(PyExc_KeyError, key);
-               } else if (count == 1) {
-                       gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
-                       val = pygst_value_as_pyobject(gvalue, TRUE);
-               } else {
-                       PyErr_SetString(PyExc_TypeError, "lists are currently unspported");
-               }
-       }
-
-       if (val == NULL)
-               val = failobj;
-       Py_INCREF(val);
-       return val;
-}
-%%
-override gst_tag_list_foreach kwargs
-static gboolean
-pygst_tag_list_foreach_marshal(GstTagList *list,
-                              const gchar *tag,
-                              gpointer user_data)
-{
-       PyGstCustomNotify *cunote = user_data;
-       PyObject *py_list;
-       PyObject *py_key, *retobj;
-       gboolean retval = TRUE;
-       PyGILState_STATE state;
-       
-       g_assert(cunote->func);
-
-       state = pyg_gil_state_ensure();
-
-       py_list = pyg_boxed_new(GST_TYPE_TAG_LIST, list, TRUE, TRUE);
-       py_key = Py_BuildValue("s", tag);
-       if (cunote->data)
-               retobj = PyEval_CallFunction(cunote->func, "(NNO)",
-                                            py_list,
-                                            py_key,
-                                            cunote->data);
-       else
-               retobj = PyEval_CallFunction(cunote->func, "(NN)",
-                                            py_list,
-                                            py_key);
-
-       if (PyErr_Occurred () || (retobj == NULL) || (retobj == Py_None)) {
-               PyErr_Print ();
-               retval = FALSE;
-       } else if (retobj != Py_None) {
-               retval = PyInt_AsLong(retobj);
-       }
-
-       Py_XDECREF(retobj);
-
-       pyg_gil_state_release(state);
-       
-       return retval;
-}
-
-static PyObject *
-_wrap_gst_tag_list_foreach (PyGObject *self,
-                           PyObject *args,
-                           PyObject *kwargs)
-{
-       static char *kwlist[] = { "foreach_function", "args", NULL };
-       PyObject *pyfunc, *pyarg = NULL;
-       PyGstCustomNotify cunote;
-
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-                                        "O|O:GstTagList.foreach",
-                                        kwlist, &pyfunc, &pyarg))
-               return NULL;
-
-       if (!PyCallable_Check(pyfunc)) {
-               PyErr_SetString(PyExc_TypeError, "foreach_function not callable");
-               return NULL;
-       }
-
-       cunote.func = pyfunc;
-       cunote.data = pyarg;
-       gst_tag_list_foreach(pyg_boxed_get(self, GstTagList),
-                            (GstTagForeachFunc)pygst_tag_list_foreach_marshal,
-                            &cunote);
-
-       Py_INCREF(Py_None);
-       return Py_None;
-}
-%%
-override gst_tag_list_get_value_index kwargs
-static PyObject *
-_wrap_gst_tag_list_get_value_index (PyGObject *self,
-                                   PyObject *args,
-                                   PyObject *kwargs)
-{
-       static char *kwlist[] = { "tag", "index", NULL };
-       char *tag;
-       int index;
-       const GValue *gvalue;
-
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-                                        "si:GstTagList.get_value_index",
-                                        kwlist, &tag, &index))
-               return NULL;
-
-       gvalue = gst_tag_list_get_value_index(pyg_boxed_get(self, GstTagList),
-                                             tag,
-                                             index);
-
-       return pygst_value_as_pyobject(gvalue, FALSE);
-}
-
-/* keep this attribute around even after 2.8 for compatibility reasons */
-%%
-override-attr GstObject.__gstrefcount__
-static PyObject *
-_wrap_gst_object__get___gstrefcount__(PyGObject *self, void *closure)
-{
-    return PyInt_FromLong(GST_OBJECT_REFCOUNT_VALUE(self->obj));
-}
-
-
-/* < GLib 2.8 */
-
-/* because of our gst_object_ref/_unref, we do our own GC-related
- * functions:
- * our own tp_traverse that checks the GstObject refcount,
- * and reuse _dealloc and _clear from gobject.GObject for ours
- * compare with pygtk/gobject/pygobject.c
- */
-
-
-/* a define is a little evil, but it seems to generate the right code
- * to allow us to do our garbage collection routines */
-%%
-override-slot GstObject.tp_flags
-#define _wrap_gst_object_tp_flags Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC 
-
-%%
-override-slot GstObject.tp_traverse
-static int
-_wrap_gst_object_tp_traverse(PyGObject *self, visitproc visit, void *arg)
-{
-    int ret = 0;
-    GSList *tmp;
-
-    if (self->inst_dict) ret = visit(self->inst_dict, arg);
-    if (ret != 0) return ret;
-
-    for (tmp = self->closures; tmp != NULL; tmp = tmp->next) {
-        PyGClosure *closure = tmp->data;
-
-        if (closure->callback) ret = visit(closure->callback, arg);
-        if (ret != 0) return ret;
-
-        if (closure->extra_args) ret = visit(closure->extra_args, arg);
-        if (ret != 0) return ret;
-
-        if (closure->swap_data) ret = visit(closure->swap_data, arg);
-        if (ret != 0) return ret;
-    }
-
-    if (self->obj && GST_OBJECT_REFCOUNT_VALUE(self->obj) == 1) {
-        GST_DEBUG_OBJECT(self->obj,
-            "gst.Object.tp_traverse: GstObject refcount of %p is 1, visit",
-            self->obj);
-        ret = visit((PyObject *)self, arg);
-    }
-
-    return ret;
-}
-
-%%
-override-slot GstObject.tp_clear
-int
-_wrap_gst_object_tp_clear(PyGObject *self)
-{
-    int ret;
-    GObject *obj = self->obj;
-
-    /* if we're a GstObject, we want to monkeypatch the GObject.tp_clear's
-     * g_object_unref and "replace" it with a gst_object_unref */
-    if (! GST_IS_OBJECT (obj))
-        obj = NULL;
-    else {
-        GST_DEBUG_OBJECT (obj, "gst.Object.tp_clear");
-        g_object_ref (obj);
-    }
-
-    ret = PyGObject_Type.tp_clear((PyObject *) self);
-
-    if (obj)
-        gst_object_unref (obj);
-
-    return ret;
-}
-
-%%
-override-slot GstObject.tp_dealloc
-void
-_wrap_gst_object_tp_dealloc(PyGObject *self)
-{
-    GObject *obj = self->obj;
-
-    /* if we're a GstObject, we want to monkeypatch the GObject.tp_dealloc's
-     * g_object_unref and "replace" it with a gst_object_unref */
-    if (! GST_IS_OBJECT (obj))
-        obj = NULL;
-    else {
-        GST_DEBUG_OBJECT (obj, "gst.Object.tp_dealloc");
-        g_object_ref (obj);
-    }
-
-    PyGObject_Type.tp_dealloc((PyObject *) self);
-
-    if (obj)
-        gst_object_unref (obj);
-}
-
-%%
-override-slot GstObject.tp_repr
-static PyObject *
-_wrap_gst_object_tp_repr(PyObject *self)
-{
-    gchar *repr;
-    PyObject *ret;
-    GstObject *object = GST_OBJECT (pygobject_get (self));
-
-    repr = g_strdup_printf ("<%s object (%s) at 0x%lx>",
-              self->ob_type->tp_name,
-              GST_OBJECT_NAME(object) ? GST_OBJECT_NAME(object) : "unnamed",
-              (long)self);
-    ret = PyString_FromString(repr);
-    g_free (repr);
-    return ret;
-}
-
-%%
-override-slot GstObject.tp_str
-static PyObject *
-_wrap_gst_object_tp_str(PyObject *self)
-{
-    gchar *repr, *path;
-    PyObject *ret;
-    GstObject *object = GST_OBJECT (pygobject_get (self));
-
-    path = gst_object_get_path_string (object);
-    repr = g_strdup_printf ("%s (%s)",
-              path, self->ob_type->tp_name);
-    ret = PyString_FromString(repr);
-    g_free (repr);
-    g_free (path);
-    return ret;
-}
 %%
 override-slot GstPluginFeature.tp_repr
 static PyObject *
diff --git a/gst/gstobject.override b/gst/gstobject.override
new file mode 100644 (file)
index 0000000..3db64c6
--- /dev/null
@@ -0,0 +1,171 @@
+/* -*- Mode: C; ; c-file-style: "python" -*- */
+/* gst-python
+ * Copyright (C) 2005 Edward Hervey
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * 
+ * Author: Edward Hervey <edward@fluendo.com>
+ */
+
+%%
+ignore
+  gst_object_default_deep_notify
+  gst_object_check_uniqueness
+  gst_object_replace
+
+%%
+override-attr GstObject.__gstrefcount__
+
+/* keep this attribute around even after 2.8 for compatibility reasons */
+static PyObject *
+_wrap_gst_object__get___gstrefcount__(PyGObject *self, void *closure)
+{
+    return PyInt_FromLong(GST_OBJECT_REFCOUNT_VALUE(self->obj));
+}
+
+
+/* < GLib 2.8 */
+
+/* because of our gst_object_ref/_unref, we do our own GC-related
+ * functions:
+ * our own tp_traverse that checks the GstObject refcount,
+ * and reuse _dealloc and _clear from gobject.GObject for ours
+ * compare with pygtk/gobject/pygobject.c
+ */
+
+
+/* a define is a little evil, but it seems to generate the right code
+ * to allow us to do our garbage collection routines */
+%%
+override-slot GstObject.tp_flags
+#define _wrap_gst_object_tp_flags Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC 
+
+%%
+override-slot GstObject.tp_traverse
+static int
+_wrap_gst_object_tp_traverse(PyGObject *self, visitproc visit, void *arg)
+{
+    int ret = 0;
+    GSList *tmp;
+
+    if (self->inst_dict) ret = visit(self->inst_dict, arg);
+    if (ret != 0) return ret;
+
+    for (tmp = self->closures; tmp != NULL; tmp = tmp->next) {
+        PyGClosure *closure = tmp->data;
+
+        if (closure->callback) ret = visit(closure->callback, arg);
+        if (ret != 0) return ret;
+
+        if (closure->extra_args) ret = visit(closure->extra_args, arg);
+        if (ret != 0) return ret;
+
+        if (closure->swap_data) ret = visit(closure->swap_data, arg);
+        if (ret != 0) return ret;
+    }
+
+    if (self->obj && GST_OBJECT_REFCOUNT_VALUE(self->obj) == 1) {
+        GST_DEBUG_OBJECT(self->obj,
+            "gst.Object.tp_traverse: GstObject refcount of %p is 1, visit",
+            self->obj);
+        ret = visit((PyObject *)self, arg);
+    }
+
+    return ret;
+}
+
+%%
+override-slot GstObject.tp_clear
+int
+_wrap_gst_object_tp_clear(PyGObject *self)
+{
+    int ret;
+    GObject *obj = self->obj;
+
+    /* if we're a GstObject, we want to monkeypatch the GObject.tp_clear's
+     * g_object_unref and "replace" it with a gst_object_unref */
+    if (! GST_IS_OBJECT (obj))
+        obj = NULL;
+    else {
+        GST_DEBUG_OBJECT (obj, "gst.Object.tp_clear");
+        g_object_ref (obj);
+    }
+
+    ret = PyGObject_Type.tp_clear((PyObject *) self);
+
+    if (obj)
+        gst_object_unref (obj);
+
+    return ret;
+}
+
+%%
+override-slot GstObject.tp_dealloc
+void
+_wrap_gst_object_tp_dealloc(PyGObject *self)
+{
+    GObject *obj = self->obj;
+
+    /* if we're a GstObject, we want to monkeypatch the GObject.tp_dealloc's
+     * g_object_unref and "replace" it with a gst_object_unref */
+    if (! GST_IS_OBJECT (obj))
+        obj = NULL;
+    else {
+        GST_DEBUG_OBJECT (obj, "gst.Object.tp_dealloc");
+        g_object_ref (obj);
+    }
+
+    PyGObject_Type.tp_dealloc((PyObject *) self);
+
+    if (obj)
+        gst_object_unref (obj);
+}
+
+%%
+override-slot GstObject.tp_repr
+static PyObject *
+_wrap_gst_object_tp_repr(PyObject *self)
+{
+    gchar *repr;
+    PyObject *ret;
+    GstObject *object = GST_OBJECT (pygobject_get (self));
+
+    repr = g_strdup_printf ("<%s object (%s) at 0x%lx>",
+              self->ob_type->tp_name,
+              GST_OBJECT_NAME(object) ? GST_OBJECT_NAME(object) : "unnamed",
+              (long)self);
+    ret = PyString_FromString(repr);
+    g_free (repr);
+    return ret;
+}
+
+%%
+override-slot GstObject.tp_str
+static PyObject *
+_wrap_gst_object_tp_str(PyObject *self)
+{
+    gchar *repr, *path;
+    PyObject *ret;
+    GstObject *object = GST_OBJECT (pygobject_get (self));
+
+    path = gst_object_get_path_string (object);
+    repr = g_strdup_printf ("%s (%s)",
+              path, self->ob_type->tp_name);
+    ret = PyString_FromString(repr);
+    g_free (repr);
+    g_free (path);
+    return ret;
+}
diff --git a/gst/gsttaglist.override b/gst/gsttaglist.override
new file mode 100644 (file)
index 0000000..6932328
--- /dev/null
@@ -0,0 +1,263 @@
+/* -*- Mode: C; ; c-file-style: "python" -*- */
+/* gst-python
+ * Copyright (C) 2005 Edward Hervey
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * 
+ * Author: Edward Hervey <edward@fluendo.com>
+ */
+
+%%
+ignore-glob
+  gst_tag_list_get_*
+%%
+ignore
+  gst_tag_list_add
+  gst_tag_list_add_values
+  gst_tag_list_add_valist_values
+  gst_tag_list_copy_value
+%%
+define GstTagList.keys noargs
+void
+tag_foreach_func_dict (const GstTagList *list,
+                      const gchar      *tag,
+                      PyObject         *dict)
+{
+       int count;
+       guint i;
+       const GValue *gvalue;
+       PyObject *value;
+       gchar *key;
+    
+       count = gst_tag_list_get_tag_size(GST_TAG_LIST(list), tag);
+
+       for (i = 0; i < count; i++) {
+               gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(list), tag, i);
+               value = pygst_value_as_pyobject(gvalue, TRUE);
+               key = g_strdup (tag);
+               PyDict_SetItemString(dict, key, value);
+               g_free (key);
+               Py_DECREF(value);
+       }
+}
+void
+tag_foreach_func_list (const GstTagList *list,
+                      const gchar      *tag,
+                      PyObject         *py_list)
+{
+       int count;
+    
+       count = gst_tag_list_get_tag_size(GST_TAG_LIST(list), tag);
+       if (count == 0)
+               PyErr_SetString(PyExc_KeyError, tag);
+       else if (count == 1)
+               PyList_Append(py_list, PyString_FromString(tag));
+#if 0  
+       else if (count > 1)
+               PyErr_SetString(PyExc_TypeError, "lists are currently unspported");
+#endif
+       
+}
+
+static PyObject*
+_wrap_gst_tag_list_keys(PyGObject *self)
+{
+       PyObject *dict;
+
+       dict = PyList_New(0);
+    
+       gst_tag_list_foreach(GST_TAG_LIST(self->obj),
+                            (GstTagForeachFunc)tag_foreach_func_list,
+                            (gpointer)dict);
+       return dict;
+}
+%%
+override-slot GstTagList.tp_as_mapping
+static int
+_wrap_gst_tag_list_length(PyGObject *self)
+{
+       return gst_structure_n_fields((GstStructure*)self->obj);
+}
+
+static PyObject *
+_wrap_gst_tag_list_subscript(PyGObject *self, PyObject *py_key)
+{
+       PyObject *v = NULL;
+       char *key = PyString_AsString(py_key);
+       
+       int count = gst_tag_list_get_tag_size(GST_TAG_LIST(self->obj), key);
+       if (count == 0) {
+               PyErr_SetObject(PyExc_KeyError, py_key);
+       } else if (count == 1) {
+               const GValue *gvalue;
+               gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
+               v = pygst_value_as_pyobject(gvalue, TRUE);
+       } else {
+               PyErr_SetString(PyExc_TypeError, "lists are currently unspported");
+       }
+               
+       if (v != NULL)
+               Py_INCREF(v);
+       return v;
+}
+
+static PySequenceMethods _wrap_gst_tag_list_tp_as_mapping = {
+       (inquiry)_wrap_gst_tag_list_length,         /* mp_length */
+       (binaryfunc)_wrap_gst_tag_list_subscript,   /* mp_subscript */
+       NULL,
+};
+
+%%
+define GstTagList.has_key args
+static PyObject*
+_wrap_gst_tag_list_has_key(PyGObject *self, PyObject *args)
+{
+       gchar *key;
+       const GValue *gvalue;
+    
+       if (!PyArg_ParseTuple(args, "s:GstTagList.has_key", &key))
+               return NULL;
+
+       gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
+
+       return PyInt_FromLong(gvalue != NULL);
+}    
+%%
+define GstTagList.get
+static PyObject *
+_wrap_gst_tag_list_get(PyGObject *self, PyObject *args)
+{
+       char *key;
+       PyObject *failobj = Py_None;
+       PyObject *val = NULL;
+       const GValue *gvalue;
+       
+       if (!PyArg_ParseTuple(args, "s|O:GstTagList.get", &key, &failobj))
+               return NULL;
+
+       gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
+       if (gvalue != NULL) {
+               int count = gst_tag_list_get_tag_size(GST_TAG_LIST(self->obj), key);
+               if (count == 0) {
+                       PyErr_SetString(PyExc_KeyError, key);
+               } else if (count == 1) {
+                       gvalue = gst_tag_list_get_value_index(GST_TAG_LIST(self->obj), key, 0);
+                       val = pygst_value_as_pyobject(gvalue, TRUE);
+               } else {
+                       PyErr_SetString(PyExc_TypeError, "lists are currently unspported");
+               }
+       }
+
+       if (val == NULL)
+               val = failobj;
+       Py_INCREF(val);
+       return val;
+}
+%%
+override gst_tag_list_foreach kwargs
+static gboolean
+pygst_tag_list_foreach_marshal(GstTagList *list,
+                              const gchar *tag,
+                              gpointer user_data)
+{
+       PyGstCustomNotify *cunote = user_data;
+       PyObject *py_list;
+       PyObject *py_key, *retobj;
+       gboolean retval = TRUE;
+       PyGILState_STATE state;
+       
+       g_assert(cunote->func);
+
+       state = pyg_gil_state_ensure();
+
+       py_list = pyg_boxed_new(GST_TYPE_TAG_LIST, list, TRUE, TRUE);
+       py_key = Py_BuildValue("s", tag);
+       if (cunote->data)
+               retobj = PyEval_CallFunction(cunote->func, "(NNO)",
+                                            py_list,
+                                            py_key,
+                                            cunote->data);
+       else
+               retobj = PyEval_CallFunction(cunote->func, "(NN)",
+                                            py_list,
+                                            py_key);
+
+       if (PyErr_Occurred () || (retobj == NULL) || (retobj == Py_None)) {
+               PyErr_Print ();
+               retval = FALSE;
+       } else if (retobj != Py_None) {
+               retval = PyInt_AsLong(retobj);
+       }
+
+       Py_XDECREF(retobj);
+
+       pyg_gil_state_release(state);
+       
+       return retval;
+}
+
+static PyObject *
+_wrap_gst_tag_list_foreach (PyGObject *self,
+                           PyObject *args,
+                           PyObject *kwargs)
+{
+       static char *kwlist[] = { "foreach_function", "args", NULL };
+       PyObject *pyfunc, *pyarg = NULL;
+       PyGstCustomNotify cunote;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                        "O|O:GstTagList.foreach",
+                                        kwlist, &pyfunc, &pyarg))
+               return NULL;
+
+       if (!PyCallable_Check(pyfunc)) {
+               PyErr_SetString(PyExc_TypeError, "foreach_function not callable");
+               return NULL;
+       }
+
+       cunote.func = pyfunc;
+       cunote.data = pyarg;
+       gst_tag_list_foreach(pyg_boxed_get(self, GstTagList),
+                            (GstTagForeachFunc)pygst_tag_list_foreach_marshal,
+                            &cunote);
+
+       Py_INCREF(Py_None);
+       return Py_None;
+}
+%%
+override gst_tag_list_get_value_index kwargs
+static PyObject *
+_wrap_gst_tag_list_get_value_index (PyGObject *self,
+                                   PyObject *args,
+                                   PyObject *kwargs)
+{
+       static char *kwlist[] = { "tag", "index", NULL };
+       char *tag;
+       int index;
+       const GValue *gvalue;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+                                        "si:GstTagList.get_value_index",
+                                        kwlist, &tag, &index))
+               return NULL;
+
+       gvalue = gst_tag_list_get_value_index(pyg_boxed_get(self, GstTagList),
+                                             tag,
+                                             index);
+
+       return pygst_value_as_pyobject(gvalue, FALSE);
+}
+