From: Edward Hervey Date: Sun, 26 Jun 2005 12:35:07 +0000 (+0000) Subject: codegen/: Updated codegen to support miniobject X-Git-Tag: 1.19.3~485^2~1171 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=038f11fafb3a0c72ec4e10248a774fd5375c5c21;p=platform%2Fupstream%2Fgstreamer.git codegen/: Updated codegen to support miniobject Original commit message from CVS: * codegen/argtypes.py: * codegen/codegen.py: * codegen/definitions.py: * codegen/defsparser.py: * codegen/docgen.py: Updated codegen to support miniobject * gst/Makefile.am: Use the included (and modified) codegen for code generation. * gst/pygstminiobject.c: * gst/pygstminiobject.h: * gst/pygstminiobject-private.h: New GstMiniObject inspired from pygobject.[ch] code * gst/common.h: * gst/gst-types.defs: * gst/gst.override: * gst/gstbuffer.override: * gst/gstcaps.override: * gst/gstmodule.c: * gst/gstpad.override: Modifications to support MiniObject * gst/gst.defs: Allow null second parameter for ElementFactory.create() and gst.element_factory_make() --- diff --git a/ChangeLog b/ChangeLog index 81626c1..12e55fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2005-06-26 Edward Hervey + + * codegen/argtypes.py: + * codegen/codegen.py: + * codegen/definitions.py: + * codegen/defsparser.py: + * codegen/docgen.py: + Updated codegen to support miniobject + + * gst/Makefile.am: + Use the included (and modified) codegen for code generation. + + * gst/pygstminiobject.c: + * gst/pygstminiobject.h: + * gst/pygstminiobject-private.h: + New GstMiniObject inspired from pygobject.[ch] code + + * gst/common.h: + * gst/gst-types.defs: + * gst/gst.override: + * gst/gstbuffer.override: + * gst/gstcaps.override: + * gst/gstmodule.c: + * gst/gstpad.override: + Modifications to support MiniObject + + * gst/gst.defs: + Allow null second parameter for ElementFactory.create() + and gst.element_factory_make() + 2005-06-20 Edward Hervey * gst/arg-types.py: diff --git a/codegen/argtypes.py b/codegen/argtypes.py index ca1e67c..19bd832 100644 --- a/codegen/argtypes.py +++ b/codegen/argtypes.py @@ -423,6 +423,71 @@ class ObjectArg(ArgType): info.codeafter.append(' /* pygobject_new handles NULL checking */\n' + ' return pygobject_new((GObject *)ret);') +class MiniObjectArg(ArgType): + # should change these checks to more typesafe versions that check + # a little further down in the class heirachy. + nulldflt = (' if ((PyObject *)py_%(name)s == Py_None)\n' + ' %(name)s = NULL;\n' + ' else if (py_%(name)s) && pygstminiobject_check(py_%(name)s, &Py%(type)s_Type))\n' + ' %(name)s = %(cast)s(py_%(name)s->obj);\n' + ' else if (py_%(name)s) {\n' + ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n' + ' return NULL;\n' + ' }\n') + null = (' if (py_%(name)s && pygstminiobject_check(py_%(name)s, &Py%(type)s_Type))\n' + ' %(name)s = %(cast)s(py_%(name)s->obj);\n' + ' else if ((PyObject *)py_%(name)s != Py_None) {\n' + ' PyErr_SetString(PyExc_TypeError, "%(name)s should be a %(type)s or None");\n' + ' return NULL;\n' + ' }\n') + dflt = ' if (py_%(name)s)\n' \ + ' %(name)s = %(cast)s(py_%(name)s->obj);\n' + def __init__(self, objname, parent, typecode): + self.objname = objname + self.cast = string.replace(typecode, '_TYPE_', '_', 1) + self.parent = parent + def write_param(self, ptype, pname, pdflt, pnull, info): + if pnull: + if pdflt: + info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt) + info.varlist.add('PyGstMiniObject', '*py_' + pname + ' = NULL') + info.codebefore.append(self.nulldflt % {'name':pname, + 'cast':self.cast, + 'type':self.objname}) + else: + info.varlist.add(self.objname, '*' + pname + ' = NULL') + info.varlist.add('PyGstMiniObject', '*py_' + pname) + info.codebefore.append(self.null % {'name':pname, + 'cast':self.cast, + 'type':self.objname}) + info.arglist.append(pname) + info.add_parselist('O', ['&py_' + pname], [pname]) + else: + if pdflt: + info.varlist.add(self.objname, '*' + pname + ' = ' + pdflt) + info.varlist.add('PyGstMiniObject', '*py_' + pname + ' = NULL') + info.codebefore.append(self.dflt % {'name':pname, + 'cast':self.cast}) + info.arglist.append(pname) + info.add_parselist('O', ['&Py%s_Type' % self.objname, + '&py_' + pname], [pname]) + else: + info.varlist.add('PyGstMiniObject', '*' + pname) + info.arglist.append('%s(%s->obj)' % (self.cast, pname)) + info.add_parselist('O!', ['&Py%s_Type' % self.objname, + '&' + pname], [pname]) + def write_return(self, ptype, ownsreturn, info): + if ptype[-1] == '*': ptype = ptype[:-1] + info.varlist.add(ptype, '*ret') + if ownsreturn: + info.varlist.add('PyObject', '*py_ret') + info.codeafter.append(' py_ret = pygstminiobject_new((GstMiniObject *)ret);\n' + ' gst_mini_object_unref(ret);\n' + ' return py_ret;') + else: + info.codeafter.append(' /* pygobject_new handles NULL checking */\n' + + ' return pygstminiobject_new((GstMiniObject *)ret);') + class BoxedArg(ArgType): # haven't done support for default args. Is it needed? check = (' if (pyg_boxed_check(py_%(name)s, %(typecode)s))\n' @@ -715,6 +780,9 @@ class ArgMatcher: # hack to handle GdkBitmap synonym. self.register('GdkBitmap', oa) self.register('GdkBitmap*', oa) + def register_miniobject(self, ptype, parent, typecode): + oa = MiniObjectArg(ptype, parent, typecode) + self.register(ptype+'*', oa) def register_boxed(self, ptype, typecode): if self.argtypes.has_key(ptype): return arg = BoxedArg(ptype, typecode) @@ -841,5 +909,6 @@ matcher.register('PyObject*', PyObjectArg()) matcher.register('GdkNativeWindow', ULongArg()) matcher.register_object('GObject', None, 'G_TYPE_OBJECT') +matcher.register_miniobject('GstMiniObject', None, 'GST_TYPE_MINI_OBJECT') del arg diff --git a/codegen/codegen.py b/codegen/codegen.py index 0c9fdfe..c8ad6cf 100644 --- a/codegen/codegen.py +++ b/codegen/codegen.py @@ -543,6 +543,65 @@ class GObjectWrapper(Wrapper): substdict['cast'] = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1) return substdict +## TODO : Add GstMiniObjectWrapper(Wrapper) +class GstMiniObjectWrapper(Wrapper): + constructor_tmpl = \ + 'static int\n' \ + '_wrap_%(cname)s(PyGstMiniObject *self%(extraparams)s)\n' \ + '{\n' \ + '%(varlist)s' \ + '%(parseargs)s' \ + '%(codebefore)s' \ + ' self->obj = (GstMiniObject *)%(cname)s(%(arglist)s);\n' \ + '%(codeafter)s\n' \ + ' if (!self->obj) {\n' \ + ' PyErr_SetString(PyExc_RuntimeError, "could not create %(typename)s miniobject");\n' \ + ' return -1;\n' \ + ' }\n' \ + '%(aftercreate)s' \ + ' return 0;\n' \ + '}\n\n' + method_tmpl = \ + 'static PyObject *\n' \ + '_wrap_%(cname)s(PyGstMiniObject *self%(extraparams)s)\n' \ + '{\n' \ + '%(varlist)s' \ + '%(parseargs)s' \ + '%(codebefore)s' \ + ' %(setreturn)s%(cname)s(%(cast)s(self->obj)%(arglist)s);\n' \ + '%(codeafter)s\n' \ + '}\n\n' + + + def __init__(self, parser, objinfo, overrides, fp=FileOutput(sys.stdout)): + Wrapper.__init__(self, parser, objinfo, overrides, fp) + if self.objinfo: + self.castmacro = string.replace(self.objinfo.typecode, + '_TYPE_', '_', 1) + + def get_initial_class_substdict(self): + return { 'tp_basicsize' : 'PyGstMiniObject', + 'tp_weaklistoffset' : 'offsetof(PyGstMiniObject, weakreflist)', + 'tp_dictoffset' : 'offsetof(PyGstMiniObject, inst_dict)' } + + def get_field_accessor(self, fieldname): + castmacro = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1) + return '%s(pygstminiobject_get(self))->%s' % (castmacro, fieldname) + + def get_initial_constructor_substdict(self, constructor): + substdict = Wrapper.get_initial_constructor_substdict(self, constructor) + if not constructor.caller_owns_return: + substdict['aftercreate'] = " g_object_ref(self->obj);\n" + else: + substdict['aftercreate'] = '' + return substdict + + def get_initial_method_substdict(self, method): + substdict = Wrapper.get_initial_method_substdict(self, method) + substdict['cast'] = string.replace(self.objinfo.typecode, '_TYPE_', '_', 1) + return substdict + + class GInterfaceWrapper(GObjectWrapper): def get_initial_class_substdict(self): return { 'tp_basicsize' : 'PyObject', @@ -663,6 +722,8 @@ def write_type_declarations(parser, fp): fp.write('PyTypeObject Py' + obj.c_name + '_Type;\n') for obj in parser.objects: fp.write('PyTypeObject Py' + obj.c_name + '_Type;\n') + for obj in parser.miniobjects: + fp.write('PyTypeObject Py' + obj.c_name + '_Type;\n') for interface in parser.interfaces: fp.write('PyTypeObject Py' + interface.c_name + '_Type;\n') fp.write('\n') @@ -671,6 +732,7 @@ def write_classes(parser, overrides, fp): for klass, items in ((GBoxedWrapper, parser.boxes), (GPointerWrapper, parser.pointers), (GObjectWrapper, parser.objects), + (GstMiniObjectWrapper, parser.miniobjects), (GInterfaceWrapper, parser.interfaces)): for item in items: instance = klass(parser, item, overrides, fp) @@ -763,6 +825,24 @@ def write_registers(parser, fp): fp.write(' pygobject_register_class(d, "' + obj.c_name + '", ' + obj.typecode + ', &Py' + obj.c_name + '_Type, NULL);\n') + #TODO: register mini-objects + miniobjects = parser.miniobjects[:] + for obj in miniobjects: + bases = [] + if obj.parent != None: + bases.append(obj.parent) + bases = bases + obj.implements + if bases: + fp.write(' pygstminiobject_register_class(d, "' + obj.c_name + + '", ' + obj.typecode + ', &Py' + obj.c_name + + '_Type, Py_BuildValue("(' + 'O' * len(bases) + ')", ' + + string.join(map(lambda s: '&Py'+s+'_Type', bases), ', ') + + '));\n') + else: + fp.write(' pygstminiobject_register_class(d, "' + obj.c_name + + '", ' + obj.typecode + ', &Py' + obj.c_name + + '_Type, NULL);\n') + fp.write('}\n') def write_source(parser, overrides, prefix, fp=FileOutput(sys.stdout)): @@ -785,6 +865,8 @@ def register_types(parser): argtypes.matcher.register_pointer(pointer.c_name, pointer.typecode) for obj in parser.objects: argtypes.matcher.register_object(obj.c_name, obj.parent, obj.typecode) + for obj in parser.miniobjects: + argtypes.matcher.register_miniobject(obj.c_name, obj.parent, obj.typecode) for obj in parser.interfaces: argtypes.matcher.register_object(obj.c_name, None, obj.typecode) for enum in parser.enums: diff --git a/codegen/definitions.py b/codegen/definitions.py index e609ac8..b65f2d7 100644 --- a/codegen/definitions.py +++ b/codegen/definitions.py @@ -63,6 +63,57 @@ class ObjectDef(Definition): fp.write(' )\n') fp.write(')\n\n') +class MiniObjectDef(Definition): + def __init__(self, name, *args): + self.name = name + self.module = None + self.parent = None + self.c_name = None + self.typecode = None + self.fields = [] + self.implements = [] + for arg in args: + if type(arg) != type(()) or len(arg) < 2: + continue + if arg[0] == 'in-module': + self.module = arg[1] + elif arg[0] == 'parent': + self.parent = arg[1] + elif arg[0] == 'c-name': + self.c_name = arg[1] + elif arg[0] == 'gtype-id': + self.typecode = arg[1] + elif arg[0] == 'fields': + for parg in arg[1:]: + self.fields.append((parg[0], parg[1])) + elif arg[0] == 'implements': + self.implements.append(arg[1]) + def merge(self, old): + # currently the .h parser doesn't try to work out what fields of + # an object structure should be public, so we just copy the list + # from the old version ... + self.fields = old.fields + self.implements = old.implements + def write_defs(self, fp=sys.stdout): + fp.write('(define-object ' + self.name + '\n') + if self.module: + fp.write(' (in-module "' + self.module + '")\n') + if self.parent != (None, None): + fp.write(' (parent "' + self.parent + '")\n') + for interface in self.implements: + fp.write(' (implements "' + interface + '")\n') + if self.c_name: + fp.write(' (c-name "' + self.c_name + '")\n') + if self.typecode: + fp.write(' (gtype-id "' + self.typecode + '")\n') + if self.fields: + fp.write(' (fields\n') + for (ftype, fname) in self.fields: + fp.write(' \'("' + ftype + '" "' + fname + '")\n') + fp.write(' )\n') + fp.write(')\n\n') + + class InterfaceDef(Definition): def __init__(self, name, *args): self.name = name diff --git a/codegen/defsparser.py b/codegen/defsparser.py index 0060c7f..3453467 100644 --- a/codegen/defsparser.py +++ b/codegen/defsparser.py @@ -19,6 +19,7 @@ class DefsParser(IncludeParser): def __init__(self, arg, defines={}): IncludeParser.__init__(self, arg) self.objects = [] + self.miniobjects = [] self.interfaces = [] self.enums = [] # enums and flags self.boxes = [] # boxed types @@ -32,6 +33,11 @@ class DefsParser(IncludeParser): odef = apply(ObjectDef, args) self.objects.append(odef) self.c_name[odef.c_name] = odef + # TODO: define_mini_object + def define_miniobject(self, *args): + odef = apply(MiniObjectDef, args) + self.miniobjects.append(odef) + self.c_name[odef.c_name] = odef def define_interface(self, *args): idef = apply(InterfaceDef, args) self.interfaces.append(idef) @@ -78,6 +84,9 @@ class DefsParser(IncludeParser): def write_defs(self, fp=sys.stdout): for obj in self.objects: obj.write_defs(fp) + # TODO: Add miniobject + for obj in self.miniobjects: + obj.write_defs(fp) for enum in self.enums: enum.write_defs(fp) for boxed in self.boxes: diff --git a/codegen/docgen.py b/codegen/docgen.py index 7a56308..5c7cde7 100644 --- a/codegen/docgen.py +++ b/codegen/docgen.py @@ -37,6 +37,8 @@ def build_object_tree(parser): parent_node.add_child(node) nodes[node.name] = node + # TODO: Add mini-object + if parser.interfaces: interfaces = Node('gobject.GInterface') root.add_child(interfaces) diff --git a/gst/Makefile.am b/gst/Makefile.am index 807cd26..5ab44c3 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -26,7 +26,7 @@ defs_DATA = gst-types.defs \ gst-extrafuncs.defs defsdir = $(pkgdatadir)/2.0/defs -noinst_HEADERS = common.h pygstvalue.h +noinst_HEADERS = common.h pygstvalue.h pygstminiobject.h INCLUDES = $(PYTHON_INCLUDES) EXTRA_DIST = $(defs_DATA) common.h arg-types.py @@ -37,7 +37,7 @@ GEN_FILES = arg-types.py gst-types.defs _gst_la_CFLAGS = $(common_cflags) _gst_la_LIBADD = $(common_libadd) _gst_la_LDFLAGS = $(common_ldflags) -export-symbols-regex init_gst -_gst_la_SOURCES = gst-argtypes.c gstmodule.c pygstvalue.c +_gst_la_SOURCES = gst-argtypes.c gstmodule.c pygstvalue.c pygstminiobject.c nodist__gst_la_SOURCES = gst.c GST_OVERRIDES = \ gst.override \ @@ -80,7 +80,7 @@ interfaces.c: $(INTERFACES_DEFS) $(INTERFACES_OVERRIDES) $(GEN_FILES) .defs.c: (cd $(srcdir) \ - && $(PYGTK_CODEGEN) \ + && python $(top_srcdir)/codegen/codegen.py \ --load-types $(srcdir)/arg-types.py \ --register $(srcdir)/gst-types.defs \ --override $*.override \ diff --git a/gst/common.h b/gst/common.h index 83f1ed6..a123fa2 100644 --- a/gst/common.h +++ b/gst/common.h @@ -23,21 +23,24 @@ #define __COMMON_H__ #include +#include +#include #include #include "pygobject.h" +#include "pygstminiobject.h" #if (defined HAVE_OLD_PYGTK && (PY_VERSION_HEX < 0x02030000)) typedef destructor freefunc; #endif typedef struct { - PyGObject *pad; - GClosure *link_function; - GClosure *event_function; - GClosure *chain_function; - GClosure *get_function; - GClosure *getcaps_function; + PyGObject *pad; + GClosure *link_function; + GClosure *event_function; + GClosure *chain_function; + GClosure *get_function; + GClosure *getcaps_function; } PyGstPadPrivate; typedef struct { diff --git a/gst/gst-types.defs b/gst/gst-types.defs index 63f96f0..d5649ab 100644 --- a/gst/gst-types.defs +++ b/gst/gst-types.defs @@ -146,34 +146,28 @@ ;; MiniObject types ;; -(define-boxed MiniObject - (in-module "Gst") - (c-name "GstMiniObject") - (gtype-id "GST_TYPE_MINI_OBJECT") -) - -(define-object Buffer +(define-miniobject Buffer (in-module "Gst") (parent "GstMiniObject") (c-name "GstBuffer") (gtype-id "GST_TYPE_BUFFER") ) -(define-object Event +(define-miniobject Event (in-module "Gst") (parent "GstMiniObject") (c-name "GstEvent") (gtype-id "GST_TYPE_EVENT") ) -(define-object Message +(define-miniobject Message (in-module "Gst") (parent "GstMiniObject") (c-name "GstMessage") (gtype-id "GST_TYPE_MESSAGE") ) -(define-object Query +(define-miniobject Query (in-module "Gst") (parent "GstMiniObject") (c-name "GstQuery") diff --git a/gst/gst.defs b/gst/gst.defs index 30474ae..77cdb07 100644 --- a/gst/gst.defs +++ b/gst/gst.defs @@ -1231,7 +1231,7 @@ (c-name "gst_element_factory_create") (return-type "GstElement*") (parameters - '("const-gchar*" "name") + '("const-gchar*" "name" (null-ok) (default "NULL")) ) ) @@ -1240,7 +1240,7 @@ (return-type "GstElement*") (parameters '("const-gchar*" "factoryname") - '("const-gchar*" "name") + '("const-gchar*" "name" (null-ok) (default "NULL")) ) ) diff --git a/gst/gst.override b/gst/gst.override index 76f46a2..1abdf12 100644 --- a/gst/gst.override +++ b/gst/gst.override @@ -41,6 +41,7 @@ headers #include #include "pygstvalue.h" +#include "pygstminiobject.h" /* These headers have been included directly to get around multiple * GetAttrString calls */ diff --git a/gst/gstbuffer.override b/gst/gstbuffer.override index 6656445..657498a 100644 --- a/gst/gstbuffer.override +++ b/gst/gstbuffer.override @@ -23,15 +23,15 @@ %% headers -static int gst_buffer_getreadbuffer (PyGObject *self, +static int gst_buffer_getreadbuffer (PyGstMiniObject *self, int index, const void **ptr); -static int gst_buffer_getwritebuf (PyGObject *self, +static int gst_buffer_getwritebuf (PyGstMiniObject *self, int index, const void **ptr); -static int gst_buffer_getsegcount (PyGObject *self, +static int gst_buffer_getsegcount (PyGstMiniObject *self, int *lenp); -static int gst_buffer_getcharbuf (PyGObject *self, +static int gst_buffer_getcharbuf (PyGstMiniObject *self, int index, const char **ptr); %% @@ -120,49 +120,49 @@ _wrap_gst_buffer_set_data(PyObject *self, PyObject *args, PyObject *kwargs) %% override-attr GstBuffer.data_type static PyObject* -_wrap_gst_buffer__get_data_type(PyGObject *self, void *closure) +_wrap_gst_buffer__get_data_type(PyGstMiniObject *self, void *closure) { return pyg_type_wrapper_new(GST_DATA_TYPE(self->obj)); } %% override-attr GstBuffer.flags static PyObject* -_wrap_gst_buffer__get_flags(PyGObject *self, void *closure) +_wrap_gst_buffer__get_flags(PyGstMiniObject *self, void *closure) { return PyInt_FromLong(GST_DATA_FLAGS(self->obj)); } %% override-attr GstBuffer.size static PyObject * -_wrap_gst_buffer__get_size(PyGObject *self, void *closure) +_wrap_gst_buffer__get_size(PyGstMiniObject *self, void *closure) { return PyInt_FromLong(GST_BUFFER_SIZE(self->obj)); } %% override-attr GstBuffer.maxsize static PyObject * -_wrap_gst_buffer__get_maxsize(PyGObject *self, void *closure) +_wrap_gst_buffer__get_maxsize(PyGstMiniObject *self, void *closure) { return PyInt_FromLong(GST_BUFFER_MAXSIZE(self->obj)); } %% override-attr GstBuffer.offset static PyObject * -_wrap_gst_buffer__get_offset(PyGObject *self, void *closure) +_wrap_gst_buffer__get_offset(PyGstMiniObject *self, void *closure) { return PyInt_FromLong(GST_BUFFER_OFFSET(self->obj)); } %% override-attr GstBuffer.offset_end static PyObject * -_wrap_gst_buffer__get_offset_end(PyGObject *self, void *closure) +_wrap_gst_buffer__get_offset_end(PyGstMiniObject *self, void *closure) { return PyInt_FromLong(GST_BUFFER_OFFSET_END(self->obj)); } %% override-attr GstBuffer.timestamp static PyObject * -_wrap_gst_buffer__get_timestamp(PyGObject *self, void *closure) +_wrap_gst_buffer__get_timestamp(PyGstMiniObject *self, void *closure) { return PyInt_FromLong(GST_BUFFER(self->obj)->timestamp); } @@ -181,7 +181,7 @@ _wrap_gst_buffer__set_timestamp(PyGBoxed *self, PyObject *value, void *closure) %% override-attr GstBuffer.duration static PyObject * -_wrap_gst_buffer__get_duration(PyGObject *self, void *closure) +_wrap_gst_buffer__get_duration(PyGstMiniObject *self, void *closure) { return PyInt_FromLong(GST_BUFFER(self->obj)->duration); } @@ -200,7 +200,7 @@ _wrap_gst_buffer__set_duration(PyGBoxed *self, PyObject *value, void *closure) %% override-slot GstBuffer.tp_str static PyObject * -_wrap_gst_buffer_tp_str(PyGObject *self) +_wrap_gst_buffer_tp_str(PyGstMiniObject *self) { GstBuffer *buf = pyg_boxed_get(self, GstBuffer); @@ -217,7 +217,7 @@ static PyBufferProcs _wrap_gst_buffer_tp_as_buffer = { }; static int -gst_buffer_getreadbuffer(PyGObject *self, int index, const void **ptr) +gst_buffer_getreadbuffer(PyGstMiniObject *self, int index, const void **ptr) { GstBuffer *buf = pyg_boxed_get(self, GstBuffer); @@ -232,7 +232,7 @@ gst_buffer_getreadbuffer(PyGObject *self, int index, const void **ptr) } static int -gst_buffer_getsegcount(PyGObject *self, int *lenp) +gst_buffer_getsegcount(PyGstMiniObject *self, int *lenp) { GstBuffer *buf = pyg_boxed_get(self, GstBuffer); @@ -242,13 +242,13 @@ gst_buffer_getsegcount(PyGObject *self, int *lenp) } static int -gst_buffer_getcharbuf(PyGObject *self, int index, const char **ptr) +gst_buffer_getcharbuf(PyGstMiniObject *self, int index, const char **ptr) { return gst_buffer_getreadbuffer (self, index, (const void **) ptr); } static int -gst_buffer_getwritebuf(PyGObject *self, int index, const void **ptr) +gst_buffer_getwritebuf(PyGstMiniObject *self, int index, const void **ptr) { GstBuffer *buf = pyg_boxed_get(self, GstBuffer); diff --git a/gst/gstcaps.override b/gst/gstcaps.override index 1091679..17a4116 100644 --- a/gst/gstcaps.override +++ b/gst/gstcaps.override @@ -40,32 +40,32 @@ pygst_caps_map_add (PyObject *structure, PyObject *caps) g_hash_table_insert (structure_caps_map, structure, caps); } -static void -pygst_caps_map_remove_structure (PyObject *structure) -{ - g_hash_table_remove (structure_caps_map, structure); -} +/* static void */ +/* pygst_caps_map_remove_structure (PyObject *structure) */ +/* { */ +/* g_hash_table_remove (structure_caps_map, structure); */ +/* } */ -static gboolean -pygst_caps_map_foreach (gpointer structure, gpointer caps, gpointer match) -{ - PyGBoxed *boxed = structure; +/* static gboolean */ +/* pygst_caps_map_foreach (gpointer structure, gpointer caps, gpointer match) */ +/* { */ +/* PyGBoxed *boxed = structure; */ - if (match != caps) - return FALSE; +/* if (match != caps) */ +/* return FALSE; */ - /* we can't have free_on_dealloc stuff in here */ - g_assert (boxed->free_on_dealloc == FALSE); - boxed->boxed = gst_structure_copy (boxed->boxed); - boxed->free_on_dealloc = TRUE; - return TRUE; -} +/* /\* we can't have free_on_dealloc stuff in here *\/ */ +/* g_assert (boxed->free_on_dealloc == FALSE); */ +/* boxed->boxed = gst_structure_copy (boxed->boxed); */ +/* boxed->free_on_dealloc = TRUE; */ +/* return TRUE; */ +/* } */ -static void -pygst_caps_map_modified (PyObject *caps) -{ - g_hash_table_foreach_remove (structure_caps_map, pygst_caps_map_foreach, caps); -} +/* static void */ +/* pygst_caps_map_modified (PyObject *caps) */ +/* { */ +/* g_hash_table_foreach_remove (structure_caps_map, pygst_caps_map_foreach, caps); */ +/* } */ %% init diff --git a/gst/gstmodule.c b/gst/gstmodule.c index 7cc9d59..b307275 100644 --- a/gst/gstmodule.c +++ b/gst/gstmodule.c @@ -143,6 +143,7 @@ init_gst (void) NULL); PyDict_SetItemString(d, "LinkError", PyGstExc_LinkError); + pygst_register_classes (d); pygst_add_constants (m, "GST_"); diff --git a/gst/gstpad.override b/gst/gstpad.override index 283ca44..6fa3ada 100644 --- a/gst/gstpad.override +++ b/gst/gstpad.override @@ -411,7 +411,7 @@ _wrap_gst_pad_link(PyGObject *self, PyObject *args, PyObject *kwargs) &PyGstPad_Type, &sinkpad)) return NULL; ret = gst_pad_link(GST_PAD(self->obj), GST_PAD(sinkpad->obj)); - if (!ret) { + if (ret) { PyErr_SetString(PyGstExc_LinkError, "link failed"); return NULL; } @@ -442,7 +442,7 @@ _wrap_gst_pad_link_filtered(PyGObject *self, PyObject *args, PyObject *kwargs) ret = gst_pad_link_filtered(GST_PAD(self->obj), GST_PAD(sinkpad->obj), filtercaps); - if (!ret) { + if (ret) { PyErr_SetString(PyGstExc_LinkError, "link failed"); return NULL; } diff --git a/gst/pygstminiobject-private.h b/gst/pygstminiobject-private.h new file mode 100644 index 0000000..c5852e8 --- /dev/null +++ b/gst/pygstminiobject-private.h @@ -0,0 +1,169 @@ +#ifndef _PYGOBJECT_PRIVATE_H_ +#define _PYGOBJECT_PRIVATE_H_ + +#ifdef _PYGOBJECT_H_ +# error "include pygobject.h or pygobject-private.h, but not both" +#endif + +#define _INSIDE_PYGOBJECT_ +#include "pygobject.h" + +/* from gobjectmodule.c */ +extern struct _PyGObject_Functions pygobject_api_functions; +#define pyg_block_threads() G_STMT_START { \ + if (pygobject_api_functions.block_threads != NULL) \ + (* pygobject_api_functions.block_threads)(); \ + } G_STMT_END +#define pyg_unblock_threads() G_STMT_START { \ + if (pygobject_api_functions.unblock_threads != NULL) \ + (* pygobject_api_functions.unblock_threads)(); \ + } G_STMT_END + +#define pyg_threads_enabled (pygobject_api_functions.threads_enabled) + + +#define pyg_gil_state_ensure() (pygobject_api_functions.threads_enabled? (pygobject_api_functions.gil_state_ensure()) : 0) +#define pyg_gil_state_release(state) G_STMT_START { \ + if (pygobject_api_functions.threads_enabled) \ + pygobject_api_functions.gil_state_release(state); \ + } G_STMT_END + +#define pyg_begin_allow_threads \ + G_STMT_START { \ + PyThreadState *_save = NULL; \ + if (pygobject_api_functions.threads_enabled) \ + _save = PyEval_SaveThread(); +#define pyg_end_allow_threads \ + if (pygobject_api_functions.threads_enabled) \ + PyEval_RestoreThread(_save); \ + } G_STMT_END + + +extern GType PY_TYPE_OBJECT; + +void pyg_destroy_notify (gpointer user_data); + +/* from pygtype.h */ +extern PyTypeObject PyGTypeWrapper_Type; + +PyObject *pyg_type_wrapper_new (GType type); +GType pyg_type_from_object (PyObject *obj); + +gint pyg_enum_get_value (GType enum_type, PyObject *obj, gint *val); +gint pyg_flags_get_value (GType flag_type, PyObject *obj, gint *val); +int pyg_pyobj_to_unichar_conv (PyObject* py_obj, void* ptr); + +typedef PyObject *(* fromvaluefunc)(const GValue *value); +typedef int (*tovaluefunc)(GValue *value, PyObject *obj); + +void pyg_register_boxed_custom(GType boxed_type, + fromvaluefunc from_func, + tovaluefunc to_func); +int pyg_value_from_pyobject(GValue *value, PyObject *obj); +PyObject *pyg_value_as_pyobject(const GValue *value, gboolean copy_boxed); +int pyg_param_gvalue_from_pyobject(GValue* value, + PyObject* py_obj, + const GParamSpec* pspec); +PyObject *pyg_param_gvalue_as_pyobject(const GValue* gvalue, + gboolean copy_boxed, + const GParamSpec* pspec); + +GClosure *pyg_closure_new(PyObject *callback, PyObject *extra_args, PyObject *swap_data); +GClosure *pyg_signal_class_closure_get(void); + +PyObject *pyg_object_descr_doc_get(void); + + +/* from pygobject.h */ +extern PyTypeObject PyGObject_Type; +extern PyTypeObject PyGInterface_Type; +extern GQuark pyginterface_type_key; + +void pygobject_register_class (PyObject *dict, + const gchar *type_name, + GType gtype, PyTypeObject *type, + PyObject *bases); +void pygobject_register_wrapper (PyObject *self); +PyObject * pygobject_new (GObject *obj); +PyTypeObject *pygobject_lookup_class (GType gtype); +void pygobject_watch_closure (PyObject *self, GClosure *closure); +void pygobject_register_sinkfunc(GType type, + void (* sinkfunc)(GObject *object)); + +/* from pygboxed.c */ +extern PyTypeObject PyGBoxed_Type; + +void pyg_register_boxed (PyObject *dict, const gchar *class_name, + GType boxed_type, PyTypeObject *type); +PyObject * pyg_boxed_new (GType boxed_type, gpointer boxed, + gboolean copy_boxed, gboolean own_ref); + +extern PyTypeObject PyGPointer_Type; + +void pyg_register_pointer (PyObject *dict, const gchar *class_name, + GType pointer_type, PyTypeObject *type); +PyObject * pyg_pointer_new (GType pointer_type, gpointer pointer); + +extern char * pyg_constant_strip_prefix(gchar *name, const gchar *strip_prefix); + +/* pygflags */ +typedef struct { + PyIntObject parent; + GType gtype; +} PyGFlags; + +extern PyTypeObject PyGFlags_Type; + +#define PyGFlags_Check(x) (g_type_is_a(((PyGFlags*)x)->gtype, G_TYPE_FLAGS)) + +extern PyObject * pyg_flags_add (PyObject * module, + const char * typename, + const char * strip_prefix, + GType gtype); +extern PyObject * pyg_flags_from_gtype (GType gtype, + int value); + +/* pygenum */ +#define PyGEnum_Check(x) (g_type_is_a(((PyGFlags*)x)->gtype, G_TYPE_ENUM)) + +typedef struct { + PyIntObject parent; + GType gtype; +} PyGEnum; + +extern PyTypeObject PyGEnum_Type; + +extern PyObject * pyg_enum_add (PyObject * module, + const char * typename, + const char * strip_prefix, + GType gtype); +extern PyObject * pyg_enum_from_gtype (GType gtype, + int value); + +/* pygmainloop */ + +typedef struct { + PyObject_HEAD + GMainLoop *loop; + GSource *signal_source; +} PyGMainLoop; + +extern PyTypeObject PyGMainLoop_Type; + +/* pygmaincontext */ + +typedef struct { + PyObject_HEAD + GMainContext *context; +} PyGMainContext; + +extern PyTypeObject PyGMainContext_Type; + +/* pygparamspec */ + +extern PyTypeObject PyGParamSpec_Type; +PyObject * pyg_param_spec_new (GParamSpec *pspec); + + + +#endif diff --git a/gst/pygstminiobject.c b/gst/pygstminiobject.c new file mode 100644 index 0000000..05a17cc --- /dev/null +++ b/gst/pygstminiobject.c @@ -0,0 +1,393 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- + * pygtk- Python bindings for the GTK toolkit. + * Copyright (C) 1998-2003 James Henstridge + * + * pygobject.c: wrapper for the GObject type. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + */ +#include +#include "pygstminiobject.h" + +static const gchar *pygstminiobject_class_id = "PyGstMiniObject::class"; +static GQuark pygstminiobject_class_key = 0; +static const gchar *pygstminiobject_wrapper_id = "PyGstMiniObject::wrapper"; +static GQuark pygstminiobject_wrapper_key = 0; + +static void pygstminiobject_dealloc(PyGstMiniObject *self); +static int pygstminiobject_traverse(PyGstMiniObject *self, visitproc visit, void *arg); +static int pygstminiobject_clear(PyGstMiniObject *self); + + +/** + * pygstminiobject_lookup_class: + * @gtype: the GType of the GstMiniObject subclass. + * + * This function looks up the wrapper class used to represent + * instances of a GstMiniObject represented by @gtype. If no wrapper class + * or interface has been registered for the given GType, then a new + * type will be created. + * + * Returns: The wrapper class for the GstMiniObject or NULL if the + * GType has no registered type and a new type couldn't be created + */ +PyTypeObject * +pygstminiobject_lookup_class(GType gtype) +{ + PyTypeObject *py_type; + + py_type = g_type_get_qdata(gtype, pygstminiobject_class_key); + + return py_type; +} + +/** + * pygstminiobject_register_class: + * @dict: the module dictionary. A reference to the type will be stored here. + * @type_name: not used ? + * @gtype: the GType of the Gstminiobject subclass. + * @type: the Python type object for this wrapper. + * @bases: a tuple of Python type objects that are the bases of this type. + * + * This function is used to register a Python type as the wrapper for + * a particular Gstminiobject subclass. It will also insert a reference to + * the wrapper class into the module dictionary passed as a reference, + * which simplifies initialisation. + */ +void +pygstminiobject_register_class(PyObject *dict, const gchar *type_name, + GType gtype, PyTypeObject *type, + PyObject *bases) +{ + PyObject *o; + const char *class_name, *s; + + if (!pygstminiobject_class_key) + pygstminiobject_class_key = g_quark_from_static_string(pygstminiobject_class_id); + + class_name = type->tp_name; + s = strrchr(class_name, '.'); + if (s != NULL) + class_name = s + 1; + + type->ob_type = &PyType_Type; + if (bases) { + type->tp_bases = bases; + type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0); + } + + if (PyType_Ready(type) < 0) { + g_warning ("couldn't make the type `%s' ready", type->tp_name); + return; + } + + if (gtype) { + o = pyg_type_wrapper_new(gtype); + PyDict_SetItemString(type->tp_dict, "__gtype__", o); + Py_DECREF(o); + + /* stash a pointer to the python class with the GType */ + Py_INCREF(type); + g_type_set_qdata(gtype, pygstminiobject_class_key, type); + } + + /* set up __doc__ descriptor on type */ +/* PyDict_SetItemString(type->tp_dict, "__doc__", */ +/* pyg_object_descr_doc_get()); */ + + PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type); +} + +/** + * pygstminiobject_new: + * @obj: a GstMiniObject instance. + * + * This function gets a reference to a wrapper for the given GstMiniObject + * instance. If a wrapper has already been created, a new reference + * to that wrapper will be returned. Otherwise, a wrapper instance + * will be created. + * + * Returns: a reference to the wrapper for the GstMiniObject. + */ +PyObject * +pygstminiobject_new(GstMiniObject *obj) +{ + PyGstMiniObject *self; + + if (!pygstminiobject_wrapper_key) + pygstminiobject_wrapper_key = g_quark_from_static_string(pygstminiobject_wrapper_id); + + if (obj == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + + /* create wrapper */ + PyTypeObject *tp = pygstminiobject_lookup_class(G_OBJECT_TYPE(obj)); + /* need to bump type refcount if created with + pygstminiobject_new_with_interfaces(). fixes bug #141042 */ + if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) + Py_INCREF(tp); + self = PyObject_GC_New(PyGstMiniObject, tp); + if (self == NULL) + return NULL; + self->obj = gst_mini_object_ref(obj); + + self->inst_dict = NULL; + self->weakreflist = NULL; + /* save wrapper pointer so we can access it later */ + Py_INCREF(self); + /* g_object_set_qdata_full(obj, pygstminiobject_wrapper_key, self, */ +/* pyg_destroy_notify); */ + + PyObject_GC_Track((PyObject *)self); + + return (PyObject *)self; +} + +static void +pygstminiobject_dealloc(PyGstMiniObject *self) +{ + PyObject_ClearWeakRefs((PyObject *)self); + + PyObject_GC_UnTrack((PyObject *)self); + + if (self->obj) { + gst_mini_object_unref(self->obj); + } + self->obj = NULL; + + if (self->inst_dict) { + Py_DECREF(self->inst_dict); + } + self->inst_dict = NULL; + + /* the following causes problems with subclassed types */ + /* self->ob_type->tp_free((PyObject *)self); */ + PyObject_GC_Del(self); +} + +static int +pygstminiobject_compare(PyGstMiniObject *self, PyGstMiniObject *v) +{ + if (self->obj == v->obj) return 0; + if (self->obj > v->obj) return -1; + return 1; +} + +static long +pygstminiobject_hash(PyGstMiniObject *self) +{ + return (long)self->obj; +} + +static PyObject * +pygstminiobject_repr(PyGstMiniObject *self) +{ + gchar buf[256]; + + g_snprintf(buf, sizeof(buf), + "<%s mini-object (%s) at 0x%lx>", + self->ob_type->tp_name, + self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized", + (long)self); + return PyString_FromString(buf); +} + +static int +pygstminiobject_traverse(PyGstMiniObject *self, visitproc visit, void *arg) +{ + int ret = 0; + + if (self->inst_dict) ret = visit(self->inst_dict, arg); + if (ret != 0) return ret; + + if (self->obj && self->obj->refcount == 1) + ret = visit((PyObject *)self, arg); + if (ret != 0) return ret; + + return 0; +} + +static int +pygstminiobject_clear(PyGstMiniObject *self) +{ + + if (self->inst_dict) { + Py_DECREF(self->inst_dict); + } + self->inst_dict = NULL; + + if (self->obj) { + gst_mini_object_unref(self->obj); + } + self->obj = NULL; + + return 0; +} + +static void +pygstminiobject_free(PyObject *op) +{ + PyObject_GC_Del(op); +} + + +/* ---------------- PyGstMiniObject methods ----------------- */ + +static int +pygstminiobject_init(PyGstMiniObject *self, PyObject *args, PyObject *kwargs) +{ + GType object_type; + GstMiniObjectClass *class; + + if (!PyArg_ParseTuple(args, ":GstMiniObject.__init__", &object_type)) + return -1; + + object_type = pyg_type_from_object((PyObject *)self); + if (!object_type) + return -1; + + if (G_TYPE_IS_ABSTRACT(object_type)) { + PyErr_Format(PyExc_TypeError, "cannot create instance of abstract " + "(non-instantiable) type `%s'", g_type_name(object_type)); + return -1; + } + + if ((class = g_type_class_ref (object_type)) == NULL) { + PyErr_SetString(PyExc_TypeError, + "could not get a reference to type class"); + return -1; + } + + self->obj = gst_mini_object_new(object_type); + if (self->obj == NULL) + PyErr_SetString (PyExc_RuntimeError, "could not create object"); + + g_type_class_unref(class); + + return (self->obj) ? 0 : -1; +} + +static PyObject * +pygstminiobject__gstminiobject_init__(PyGstMiniObject *self, PyObject *args, PyObject *kwargs) +{ + if (pygstminiobject_init(self, args, kwargs) < 0) + return NULL; + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +pygstminiobject_copy(PyGstMiniObject *self, PyObject *args) +{ + return pygstminiobject_new(gst_mini_object_copy(self->obj)); +} + +static PyObject * +pygstminiobject_ref(PyGstMiniObject *self, PyObject *args) +{ + return pygstminiobject_new(gst_mini_object_ref(self->obj)); +} + +static PyObject * +pygstminiobject_unref(PyGstMiniObject *self, PyObject *args) +{ + gst_mini_object_ref(self->obj); + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef pygstminiobject_methods[] = { + { "__gstminiobject_init__", (PyCFunction)pygstminiobject__gstminiobject_init__, + METH_VARARGS|METH_KEYWORDS }, + { "copy", (PyCFunction)pygstminiobject_copy, METH_VARARGS}, + { "ref", (PyCFunction)pygstminiobject_ref, METH_VARARGS}, + { "unref", (PyCFunction)pygstminiobject_unref, METH_VARARGS}, + { NULL, NULL, 0 } +}; + +static PyObject * +pygstminiobject_get_dict(PyGstMiniObject *self, void *closure) +{ + if (self->inst_dict == NULL) { + self->inst_dict = PyDict_New(); + if (self->inst_dict == NULL) + return NULL; + } + Py_INCREF(self->inst_dict); + return self->inst_dict; +} + +static PyObject * +pygstminiobject_get_refcount(PyGstMiniObject *self, void *closure) +{ + return PyInt_FromLong(GST_MINI_OBJECT_REFCOUNT_VALUE(self->obj)); +} + +static PyGetSetDef pygstminiobject_getsets[] = { + { "__dict__", (getter)pygstminiobject_get_dict, (setter)0 }, + { "__grefcount__", (getter)pygstminiobject_get_refcount, (setter)0, }, + { NULL, 0, 0 } +}; + +PyTypeObject PyGstMiniObject_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "gst.GstMiniObject", /* tp_name */ + sizeof(PyGstMiniObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)pygstminiobject_dealloc, /* tp_dealloc */ + (printfunc)0, /* tp_print */ + (getattrfunc)0, /* tp_getattr */ + (setattrfunc)0, /* tp_setattr */ + (cmpfunc)pygstminiobject_compare, /* tp_compare */ + (reprfunc)pygstminiobject_repr, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + (hashfunc)pygstminiobject_hash, /* tp_hash */ + (ternaryfunc)0, /* tp_call */ + (reprfunc)0, /* tp_str */ + (getattrofunc)0, /* tp_getattro */ + (setattrofunc)0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC, /* tp_flags */ + NULL, /* Documentation string */ + (traverseproc)pygstminiobject_traverse, /* tp_traverse */ + (inquiry)pygstminiobject_clear, /* tp_clear */ + (richcmpfunc)0, /* tp_richcompare */ + offsetof(PyGstMiniObject, weakreflist), /* tp_weaklistoffset */ + (getiterfunc)0, /* tp_iter */ + (iternextfunc)0, /* tp_iternext */ + pygstminiobject_methods, /* tp_methods */ + 0, /* tp_members */ + pygstminiobject_getsets, /* tp_getset */ + (PyTypeObject *)0, /* tp_base */ + (PyObject *)0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + offsetof(PyGstMiniObject, inst_dict), /* tp_dictoffset */ + (initproc)pygstminiobject_init, /* tp_init */ + (allocfunc)0, /* tp_alloc */ + (newfunc)0, /* tp_new */ + (freefunc)pygstminiobject_free, /* tp_free */ + (inquiry)0, /* tp_is_gc */ + (PyObject *)0, /* tp_bases */ +}; + diff --git a/gst/pygstminiobject.h b/gst/pygstminiobject.h new file mode 100644 index 0000000..efabbd9 --- /dev/null +++ b/gst/pygstminiobject.h @@ -0,0 +1,69 @@ +/* -*- Mode: C; c-basic-offset: 4 -*- */ + +#ifndef _PYGSTMINIOBJECT_H_ +#define _PYGSTMINIOBJECT_H_ + +#include + +#include +#include + +#include "common.h" + +G_BEGIN_DECLS + +/* Work around bugs in PyGILState api fixed in 2.4.0a4 */ +#if PY_VERSION_HEX < 0x020400A4 +#define PYGIL_API_IS_BUGGY TRUE +#else +#define PYGIL_API_IS_BUGGY FALSE +#endif + +typedef struct { + PyObject_HEAD + GstMiniObject *obj; + PyObject *inst_dict; /* the instance dictionary -- must be last */ + PyObject *weakreflist; /* list of weak references */ +} PyGstMiniObject; + +PyObject * +pygstminiobject_new(GstMiniObject *obj); + +#define pygstminiobject_get(v) (((PyGstMiniObject *)(v))->obj) +#define pygstminiobject_check(v,base) (PyObject_TypeCheck(v,base)) + +void +pygstminiobject_register_class(PyObject *dict, const gchar *type_name, + GType gtype, PyTypeObject *type, + PyObject *bases); + +#ifndef _INSIDE_PYGSTMINIOBJECT_ + +struct _PyGObject_Functions *_PyGObject_API; + +extern PyTypeObject PyGstMiniObject_Type; + +#define init_pygstminiobject() { \ + PyObject *gstminiobject = PyImport_ImportModule("gstminiobject"); \ + if (gstminiobject != NULL) { \ + PyObject *mdict = PyModule_GetDict(gstminiobject); \ + PyObject *cobject = PyDict_GetItemString(mdict, "_PyGstMiniObject_API"); \ + if (PyCObject_Check(cobject)) \ + _PyGstMiniObject_API = (struct _PyGstMiniObject_Functions *)PyCObject_AsVoidPtr(cobject); \ + else { \ + PyErr_SetString(PyExc_RuntimeError, \ + "could not find _PyGstMiniObject_API object"); \ + return; \ + } \ + } else { \ + PyErr_SetString(PyExc_ImportError, \ + "could not import gst"); \ + return; \ + } \ +} + +#endif /* !_INSIDE_PYGSTMINIOBJECT_ */ + +G_END_DECLS + +#endif /* !_PYGSTMINIOBJECT_H_ */