~ubuntu-branches/ubuntu/precise/gst0.10-python/precise

« back to all changes in this revision

Viewing changes to gst/pygstminiobject.c

  • Committer: Bazaar Package Importer
  • Author(s): Loic Minier
  • Date: 2006-06-25 19:37:45 UTC
  • Revision ID: james.westby@ubuntu.com-20060625193745-9yeg0wq56r24n57x
Tags: upstream-0.10.4
ImportĀ upstreamĀ versionĀ 0.10.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; c-basic-offset: 4 -*-
 
2
 * pygtk- Python bindings for the GTK toolkit.
 
3
 * Copyright (C) 1998-2003  James Henstridge
 
4
 *
 
5
 *   pygobject.c: wrapper for the GObject type.
 
6
 *
 
7
 * This library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * This library is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with this library; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 
20
 * USA
 
21
 */
 
22
 
 
23
#include "pygstminiobject.h"
 
24
#include <gst/gst.h>
 
25
 
 
26
static const gchar *pygstminiobject_class_id     = "PyGstMiniObject::class";
 
27
static GQuark       pygstminiobject_class_key    = 0;
 
28
/* static const gchar *pygstminiobject_wrapper_id   = "PyGstMiniObject::wrapper"; */
 
29
/* static GQuark       pygstminiobject_wrapper_key  = 0; */
 
30
 
 
31
static void pygstminiobject_dealloc(PyGstMiniObject *self);
 
32
/* static int  pygstminiobject_traverse(PyGstMiniObject *self, visitproc visit, void *arg); */
 
33
/* static int  pygstminiobject_clear(PyGstMiniObject *self); */
 
34
 
 
35
GST_DEBUG_CATEGORY_EXTERN (pygst_debug);
 
36
#define GST_CAT_DEFAULT pygst_debug
 
37
 
 
38
/**
 
39
 * pygstminiobject_lookup_class:
 
40
 * @gtype: the GType of the GstMiniObject subclass.
 
41
 *
 
42
 * This function looks up the wrapper class used to represent
 
43
 * instances of a GstMiniObject represented by @gtype.  If no wrapper class
 
44
 * or interface has been registered for the given GType, then a new
 
45
 * type will be created.
 
46
 *
 
47
 * Returns: The wrapper class for the GstMiniObject or NULL if the
 
48
 *          GType has no registered type and a new type couldn't be created
 
49
 */
 
50
PyTypeObject *
 
51
pygstminiobject_lookup_class(GType gtype)
 
52
{
 
53
    PyTypeObject *py_type = NULL;
 
54
    GType       ctype = gtype;
 
55
 
 
56
    while (!py_type && ctype) {
 
57
        py_type = g_type_get_qdata(ctype, pygstminiobject_class_key);
 
58
        ctype = g_type_parent(ctype);
 
59
    }
 
60
    if (!ctype)
 
61
        g_error ("Couldn't find a good base type!!");
 
62
    
 
63
    return py_type;
 
64
}
 
65
 
 
66
/**
 
67
 * pygstminiobject_register_class:
 
68
 * @dict: the module dictionary.  A reference to the type will be stored here.
 
69
 * @type_name: not used ?
 
70
 * @gtype: the GType of the Gstminiobject subclass.
 
71
 * @type: the Python type object for this wrapper.
 
72
 * @bases: a tuple of Python type objects that are the bases of this type.
 
73
 *
 
74
 * This function is used to register a Python type as the wrapper for
 
75
 * a particular Gstminiobject subclass.  It will also insert a reference to
 
76
 * the wrapper class into the module dictionary passed as a reference,
 
77
 * which simplifies initialisation.
 
78
 */
 
79
void
 
80
pygstminiobject_register_class(PyObject *dict, const gchar *type_name,
 
81
                         GType gtype, PyTypeObject *type,
 
82
                         PyObject *bases)
 
83
{
 
84
    PyObject *o;
 
85
    const char *class_name, *s;
 
86
 
 
87
    if (!pygstminiobject_class_key)
 
88
        pygstminiobject_class_key = g_quark_from_static_string(pygstminiobject_class_id);
 
89
 
 
90
    class_name = type->tp_name;
 
91
    s = strrchr(class_name, '.');
 
92
    if (s != NULL)
 
93
        class_name = s + 1;
 
94
    
 
95
    type->ob_type = &PyType_Type;
 
96
    type->tp_alloc = PyType_GenericAlloc;
 
97
    type->tp_new = PyType_GenericNew;
 
98
    if (bases) {
 
99
        type->tp_bases = bases;
 
100
        type->tp_base = (PyTypeObject *)PyTuple_GetItem(bases, 0);
 
101
    }
 
102
 
 
103
    if (PyType_Ready(type) < 0) {
 
104
        g_warning ("couldn't make the type `%s' ready", type->tp_name);
 
105
        return;
 
106
    }
 
107
 
 
108
    if (gtype) {
 
109
        o = pyg_type_wrapper_new(gtype);
 
110
        PyDict_SetItemString(type->tp_dict, "__gtype__", o);
 
111
        Py_DECREF(o);
 
112
 
 
113
        /* stash a pointer to the python class with the GType */
 
114
        Py_INCREF(type);
 
115
        g_type_set_qdata(gtype, pygstminiobject_class_key, type);
 
116
    }
 
117
 
 
118
    PyDict_SetItemString(dict, (char *)class_name, (PyObject *)type);
 
119
}
 
120
 
 
121
void
 
122
pygstminiobject_register_wrapper (PyObject *self)
 
123
{
 
124
}
 
125
 
 
126
 
 
127
/**
 
128
 * pygstminiobject_new:
 
129
 * @obj: a GstMiniObject instance.
 
130
 *
 
131
 * This function gets a reference to a wrapper for the given GstMiniObject
 
132
 * instance.  A new wrapper will always be created.
 
133
 *
 
134
 * Returns: a reference to the wrapper for the GstMiniObject.
 
135
 */
 
136
PyObject *
 
137
pygstminiobject_new (GstMiniObject *obj)
 
138
{
 
139
    PyGstMiniObject *self = NULL;
 
140
    PyGILState_STATE state;
 
141
    PyTypeObject *tp = NULL;
 
142
 
 
143
    if (obj == NULL) {
 
144
        Py_INCREF (Py_None);
 
145
        return Py_None;
 
146
    }
 
147
 
 
148
    /* since mini objects cannot notify us when they get destroyed, we
 
149
     * can't use a global hash to map GMO to PyO, and have to create a new
 
150
     * Python object every time we see it */
 
151
    tp = pygstminiobject_lookup_class (G_OBJECT_TYPE (obj));
 
152
    GST_DEBUG ("have to create wrapper for object %p", obj);
 
153
    if (!tp)
 
154
        g_warning ("Couldn't get class for type object : %p", obj);
 
155
    if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) {
 
156
        GST_INFO ("Increment refcount %p", tp);
 
157
        Py_INCREF (tp);
 
158
    }
 
159
    state = pyg_gil_state_ensure();
 
160
    self = PyObject_New (PyGstMiniObject, tp);
 
161
    pyg_gil_state_release(state);
 
162
 
 
163
    if (self == NULL)
 
164
        return NULL;
 
165
    self->obj = gst_mini_object_ref (obj);
 
166
 
 
167
    self->inst_dict = NULL;
 
168
    self->weakreflist = NULL;
 
169
 
 
170
    GST_DEBUG ("created Python object %p for GstMiniObject %p [ref:%d]",
 
171
        self, obj, GST_MINI_OBJECT_REFCOUNT_VALUE (obj));
 
172
    return (PyObject *) self;
 
173
}
 
174
 
 
175
static void
 
176
pygstminiobject_dealloc(PyGstMiniObject *self)
 
177
{
 
178
    g_return_if_fail (self != NULL);
 
179
 
 
180
    PyGILState_STATE state;
 
181
 
 
182
    GST_DEBUG ("At the beginning %p", self);
 
183
    state = pyg_gil_state_ensure();
 
184
 
 
185
    if (self->obj) {
 
186
        GST_DEBUG ("PyO %p unreffing GstMiniObject %p [ref:%d]", self,
 
187
             self->obj, GST_MINI_OBJECT_REFCOUNT_VALUE (self->obj));
 
188
        gst_mini_object_unref(self->obj);
 
189
        GST_DEBUG ("setting self %p -> obj to NULL", self);
 
190
        self->obj = NULL;
 
191
    }
 
192
 
 
193
    if (self->inst_dict) {
 
194
        Py_DECREF(self->inst_dict);
 
195
        self->inst_dict = NULL;
 
196
    }
 
197
 
 
198
    self->ob_type->tp_free((PyObject *) self);
 
199
    pyg_gil_state_release(state);
 
200
    GST_DEBUG ("At the end %p", self);
 
201
}
 
202
 
 
203
static int
 
204
pygstminiobject_compare(PyGstMiniObject *self, PyGstMiniObject *v)
 
205
{
 
206
    if (self->obj == v->obj) return 0;
 
207
    if (self->obj > v->obj)  return -1;
 
208
    return 1;
 
209
}
 
210
 
 
211
static long
 
212
pygstminiobject_hash(PyGstMiniObject *self)
 
213
{
 
214
    return (long)self->obj;
 
215
}
 
216
 
 
217
static PyObject *
 
218
pygstminiobject_repr(PyGstMiniObject *self)
 
219
{
 
220
    gchar buf[256];
 
221
 
 
222
    g_snprintf(buf, sizeof(buf),
 
223
               "<%s mini-object (%s) at 0x%lx>",
 
224
               self->ob_type->tp_name,
 
225
               self->obj ? G_OBJECT_TYPE_NAME(self->obj) : "uninitialized",
 
226
               (long)self);
 
227
    return PyString_FromString(buf);
 
228
}
 
229
 
 
230
 
 
231
static void
 
232
pygstminiobject_free(PyObject *op)
 
233
{
 
234
    PyObject_FREE(op);
 
235
}
 
236
 
 
237
 
 
238
/* ---------------- PyGstMiniObject methods ----------------- */
 
239
 
 
240
static int
 
241
pygstminiobject_init(PyGstMiniObject *self, PyObject *args, PyObject *kwargs)
 
242
{
 
243
    GType object_type;
 
244
    GstMiniObjectClass *class;
 
245
 
 
246
    if (!PyArg_ParseTuple(args, ":GstMiniObject.__init__", &object_type))
 
247
        return -1;
 
248
 
 
249
    object_type = pyg_type_from_object((PyObject *)self);
 
250
    if (!object_type)
 
251
        return -1;
 
252
 
 
253
    if (G_TYPE_IS_ABSTRACT(object_type)) {
 
254
        PyErr_Format(PyExc_TypeError, "cannot create instance of abstract "
 
255
                     "(non-instantiable) type `%s'", g_type_name(object_type));
 
256
        return -1;
 
257
    }
 
258
 
 
259
    if ((class = g_type_class_ref (object_type)) == NULL) {
 
260
        PyErr_SetString(PyExc_TypeError,
 
261
                        "could not get a reference to type class");
 
262
        return -1;
 
263
    }
 
264
 
 
265
    self->obj = gst_mini_object_new(object_type);
 
266
    if (self->obj == NULL)
 
267
        PyErr_SetString (PyExc_RuntimeError, "could not create object");
 
268
           
 
269
    g_type_class_unref(class);
 
270
    
 
271
    return (self->obj) ? 0 : -1;
 
272
}
 
273
 
 
274
static PyObject *
 
275
pygstminiobject__gstminiobject_init__(PyGstMiniObject *self, PyObject *args, PyObject *kwargs)
 
276
{
 
277
    if (pygstminiobject_init(self, args, kwargs) < 0)
 
278
        return NULL;
 
279
    Py_INCREF(Py_None);
 
280
    return Py_None;
 
281
}
 
282
 
 
283
static PyObject *
 
284
pygstminiobject_copy(PyGstMiniObject *self, PyObject *args)
 
285
{
 
286
    return pygstminiobject_new(gst_mini_object_copy(self->obj));
 
287
}
 
288
 
 
289
static PyMethodDef pygstminiobject_methods[] = {
 
290
    { "__gstminiobject_init__", (PyCFunction)pygstminiobject__gstminiobject_init__,
 
291
      METH_VARARGS|METH_KEYWORDS },
 
292
    { "copy", (PyCFunction)pygstminiobject_copy, METH_VARARGS, "Copies the miniobject"},
 
293
    { NULL, NULL, 0 }
 
294
};
 
295
 
 
296
static PyObject *
 
297
pygstminiobject_get_dict(PyGstMiniObject *self, void *closure)
 
298
{
 
299
    if (self->inst_dict == NULL) {
 
300
        self->inst_dict = PyDict_New();
 
301
        if (self->inst_dict == NULL)
 
302
            return NULL;
 
303
    }
 
304
    Py_INCREF(self->inst_dict);
 
305
    return self->inst_dict;
 
306
}
 
307
 
 
308
static PyObject *
 
309
pygstminiobject_get_refcount(PyGstMiniObject *self, void *closure)
 
310
{
 
311
    return PyInt_FromLong(GST_MINI_OBJECT_REFCOUNT_VALUE(self->obj));
 
312
}
 
313
 
 
314
static PyObject *
 
315
pygstminiobject_get_flags(PyGstMiniObject *self, void *closure)
 
316
{
 
317
    return PyInt_FromLong(GST_MINI_OBJECT_FLAGS(self->obj));
 
318
}
 
319
 
 
320
static PyGetSetDef pygstminiobject_getsets[] = {
 
321
    { "__dict__", (getter)pygstminiobject_get_dict, (setter)0 },
 
322
    { "__grefcount__", (getter)pygstminiobject_get_refcount, (setter)0, },
 
323
    { "flags", (getter)pygstminiobject_get_flags, (setter)0, },
 
324
    { NULL, 0, 0 }
 
325
};
 
326
 
 
327
PyTypeObject PyGstMiniObject_Type = {
 
328
    PyObject_HEAD_INIT(NULL)
 
329
    0,                                  /* ob_size */
 
330
    "gst.MiniObject",                   /* tp_name */
 
331
    sizeof(PyGstMiniObject),                    /* tp_basicsize */
 
332
    0,                                  /* tp_itemsize */
 
333
    /* methods */
 
334
    (destructor)pygstminiobject_dealloc,        /* tp_dealloc */
 
335
    (printfunc)0,                       /* tp_print */
 
336
    (getattrfunc)0,                     /* tp_getattr */
 
337
    (setattrfunc)0,                     /* tp_setattr */
 
338
    (cmpfunc)pygstminiobject_compare,           /* tp_compare */
 
339
    (reprfunc)pygstminiobject_repr,             /* tp_repr */
 
340
    0,                                  /* tp_as_number */
 
341
    0,                                  /* tp_as_sequence */
 
342
    0,                                  /* tp_as_mapping */
 
343
    (hashfunc)pygstminiobject_hash,             /* tp_hash */
 
344
    (ternaryfunc)0,                     /* tp_call */
 
345
    (reprfunc)0,                        /* tp_str */
 
346
    (getattrofunc)0,                    /* tp_getattro */
 
347
    (setattrofunc)0,                    /* tp_setattro */
 
348
    0,                                  /* tp_as_buffer */
 
349
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,           /* tp_flags */
 
350
    NULL, /* Documentation string */
 
351
    (traverseproc)0,    /* tp_traverse */
 
352
    (inquiry)0,         /* tp_clear */
 
353
    (richcmpfunc)0,                     /* tp_richcompare */
 
354
    offsetof(PyGstMiniObject, weakreflist),     /* tp_weaklistoffset */
 
355
    (getiterfunc)0,                     /* tp_iter */
 
356
    (iternextfunc)0,                    /* tp_iternext */
 
357
    pygstminiobject_methods,                    /* tp_methods */
 
358
    0,                                  /* tp_members */
 
359
    pygstminiobject_getsets,                    /* tp_getset */
 
360
    (PyTypeObject *)0,                  /* tp_base */
 
361
    (PyObject *)0,                      /* tp_dict */
 
362
    0,                                  /* tp_descr_get */
 
363
    0,                                  /* tp_descr_set */
 
364
    offsetof(PyGstMiniObject, inst_dict),       /* tp_dictoffset */
 
365
    (initproc)pygstminiobject_init,             /* tp_init */
 
366
    (allocfunc)0,                       /* tp_alloc */
 
367
    (newfunc)0,                         /* tp_new */
 
368
    (freefunc)pygstminiobject_free,             /* tp_free */
 
369
    (inquiry)0,                         /* tp_is_gc */
 
370
    (PyObject *)0,                      /* tp_bases */
 
371
};
 
372