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()
This commit is contained in:
Edward Hervey 2005-06-26 12:35:07 +00:00
parent 78143798a7
commit 038f11fafb
18 changed files with 935 additions and 62 deletions

View file

@ -1,3 +1,33 @@
2005-06-26 Edward Hervey <edward@fluendo.com>
* 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 <edward@fluendo.com>
* gst/arg-types.py:

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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:

View file

@ -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)

View file

@ -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 \

View file

@ -23,21 +23,24 @@
#define __COMMON_H__
#include <Python.h>
#include <glib.h>
#include <glib-object.h>
#include <gst/gst.h>
#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 {

View file

@ -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")

View file

@ -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"))
)
)

View file

@ -41,6 +41,7 @@ headers
#include <gst/gstprobe.h>
#include "pygstvalue.h"
#include "pygstminiobject.h"
/* These headers have been included directly to get around multiple
* GetAttrString calls */

View file

@ -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);

View file

@ -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

View file

@ -143,6 +143,7 @@ init_gst (void)
NULL);
PyDict_SetItemString(d, "LinkError", PyGstExc_LinkError);
pygst_register_classes (d);
pygst_add_constants (m, "GST_");

View file

@ -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;
}

View file

@ -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

393
gst/pygstminiobject.c Normal file
View file

@ -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 <gst/gst.h>
#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 */
};

69
gst/pygstminiobject.h Normal file
View file

@ -0,0 +1,69 @@
/* -*- Mode: C; c-basic-offset: 4 -*- */
#ifndef _PYGSTMINIOBJECT_H_
#define _PYGSTMINIOBJECT_H_
#include <Python.h>
#include <glib.h>
#include <glib-object.h>
#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_ */