diff src/bufferproxy.c @ 860:41b22371307e

Changes from Marcus. Added get_buffer() methods to Surface, and Sound. Added a BufferProxy - which is a buffer interface only class. Remember to change your Setup file - maybe just delete it if you have made no changes to it as there is a new .c file.
author Rene Dudfield <renesd@gmail.com>
date Sat, 01 Sep 2007 08:47:33 +0000
parents
children a249a10980f0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/bufferproxy.c	Sat Sep 01 08:47:33 2007 +0000
@@ -0,0 +1,302 @@
+/*
+  pygame - Python Game Library
+  Copyright (C) 2007  Marcus von Appen
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Library General Public
+  License as published by the Free Software Foundation; either
+  version 2 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Library General Public License for more details.
+
+  You should have received a copy of the GNU Library General Public
+  License along with this library; if not, write to the Free
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#define PYGAMEAPI_BUFFERPROXY_INTERNAL
+
+#include "pygame.h"
+#include "pygamedocs.h"
+
+typedef struct
+{
+    PyObject_HEAD
+    PyObject *dict;     /* dict for subclassing */
+    PyObject *weakrefs; /* Weakrefs for subclassing */
+    void *buffer;       /* Pointer to the buffer of the parent object. */
+    Py_ssize_t length;  /* Length of the buffer. */
+    PyObject *parent;   /* Parent object associated with this object. */
+    PyObject *lock;     /* Lock object for the surface. */
+
+} PyBufferProxy;
+
+static PyObject* _bufferproxy_new (PyTypeObject *type, PyObject *args,
+                                   PyObject *kwds);
+static void _bufferproxy_dealloc (PyBufferProxy *self);
+static PyObject* _bufferproxy_get_dict (PyBufferProxy *self, void *closure);
+static PyObject* _bufferproxy_repr (PyBufferProxy *self);
+
+/* Buffer methods */
+static Py_ssize_t _bufferproxy_getreadbuf (PyBufferProxy *buffer,
+                                           Py_ssize_t _index,
+                                           const void **ptr);
+static Py_ssize_t _bufferproxy_getwritebuf (PyBufferProxy *buffer,
+                                            Py_ssize_t _index,
+                                            const void **ptr);
+static Py_ssize_t _bufferproxy_getsegcount (PyBufferProxy *buffer,
+                                            Py_ssize_t *lenp);
+
+/* C API interfaces */
+static PyObject* PyBufferProxy_New (PyObject *parent, void *buffer,
+                                    Py_ssize_t length, PyObject *lock);
+
+/**
+ * Methods, which are bound to the PyBufferProxy type.
+ */
+static PyMethodDef _bufferproxy_methods[] =
+{
+    { NULL, NULL, 0, NULL }
+};
+
+/**
+ * Getters and setters for the PyBufferProxy.
+ */
+static PyGetSetDef _bufferproxy_getsets[] =
+{
+    { "__dict__", (getter) _bufferproxy_get_dict, NULL, NULL, NULL },
+    { NULL, NULL, NULL, NULL, NULL }
+};
+
+
+/**
+ * Buffer interface support for the PyBufferProxy.
+ */
+static PyBufferProcs _bufferproxy_as_buffer =
+{
+        (readbufferproc) _bufferproxy_getreadbuf,
+        (writebufferproc) _bufferproxy_getwritebuf,
+        (segcountproc) _bufferproxy_getsegcount,
+        NULL,
+};
+
+static PyTypeObject PyBufferProxy_Type =
+{
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "BufferProxy",               /* tp_name */
+    sizeof (PyBufferProxy),      /* tp_basicsize */
+    0,                          /* tp_itemsize */
+    (destructor) _bufferproxy_dealloc, /* tp_dealloc */
+    0,                          /* tp_print */
+    0,                          /* tp_getattr */
+    0,                          /* tp_setattr */
+    0,                          /* tp_compare */
+    _bufferproxy_repr,          /* tp_repr */
+    0,                          /* tp_as_number */
+    0,                          /* tp_as_sequence */
+    0,                          /* tp_as_mapping */
+    0,                          /* tp_hash */
+    0,                          /* tp_call */
+    0,                          /* tp_str */
+    0,                          /* tp_getattro */
+    0,                          /* tp_setattro */
+    &_bufferproxy_as_buffer,    /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,
+    "",                         /* tp_doc */
+    0,                          /* tp_traverse */
+    0,                          /* tp_clear */
+    0,                          /* tp_richcompare */
+    offsetof (PyBufferProxy, weakrefs),  /* tp_weaklistoffset */
+    0,                          /* tp_iter */
+    0,                          /* tp_iternext */
+    _bufferproxy_methods,       /* tp_methods */
+    0,                          /* tp_members */
+    _bufferproxy_getsets,       /* tp_getset */
+    0,                          /* tp_base */
+    0,                          /* tp_dict */
+    0,                          /* tp_descr_get */
+    0,                          /* tp_descr_set */
+    offsetof (PyBufferProxy, dict), /* tp_dictoffset */
+    0,                          /* tp_init */
+    0,                          /* tp_alloc */
+    _bufferproxy_new,               /* tp_new */
+    0,                          /* tp_free */
+    0,                          /* tp_is_gc */
+    0,                          /* tp_bases */
+    0,                          /* tp_mro */
+    0,                          /* tp_cache */
+    0,                          /* tp_subclasses */
+    0,                          /* tp_weaklist */
+    0                           /* tp_del */
+};
+
+/**
+ * Creates a new PyBufferProxy.
+ */
+static PyObject*
+_bufferproxy_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyBufferProxy *self = (PyBufferProxy *) type->tp_alloc (type, 0);
+    if (!self)
+        return NULL;
+
+    self->weakrefs = NULL;
+    self->dict = NULL;
+    self->parent = NULL;
+    self->buffer = NULL;
+    self->lock = NULL;
+    return (PyObject *) self;
+}
+
+/**
+ * Deallocates the PyBufferProxy and its members.
+ */
+static void
+_bufferproxy_dealloc (PyBufferProxy *self)
+{
+    if (self->weakrefs)
+        PyObject_ClearWeakRefs ((PyObject *) self);
+    if (self->lock)
+    {
+        Py_DECREF (self->lock);
+    }
+    Py_XDECREF (self->dict);
+    self->ob_type->tp_free ((PyObject *) self);
+}
+
+/**** Getter and setter access ****/
+
+/**
+ * Getter for PyBufferProxy.__dict__.
+ */
+static PyObject*
+_bufferproxy_get_dict (PyBufferProxy *self, void *closure)
+{
+    if (!self->dict)
+    {
+	self->dict = PyDict_New ();
+        if (!self->dict)
+            return NULL;
+    }
+
+    Py_INCREF (self->dict);
+    return self->dict;
+}
+
+static PyObject*
+_bufferproxy_repr (PyBufferProxy *self)
+{
+/* zd is for Py_size_t which python < 2.5 doesn't have. */
+#if PY_VERSION_HEX < 0x02050000
+    return PyString_FromFormat("<BufferProxy(%d)>", self->length);
+#else
+    return PyString_FromFormat("<BufferProxy(%zd)>", self->length);
+#endif
+}
+
+/**** Buffer interfaces ****/
+
+static Py_ssize_t
+_bufferproxy_getreadbuf (PyBufferProxy *buffer, Py_ssize_t _index,
+                         const void **ptr)
+{
+    if (_index != 0)
+    {
+        PyErr_SetString (PyExc_SystemError,
+                         "Accessing non-existent buffer segment");
+        return -1;
+    }
+
+    if (!buffer->parent)
+    {
+        *ptr = NULL;
+        return 0;
+    }
+
+    *ptr = buffer->buffer;
+    return buffer->length;
+}
+
+static Py_ssize_t
+_bufferproxy_getwritebuf (PyBufferProxy *buffer, Py_ssize_t _index,
+                          const void **ptr)
+{
+    if (_index != 0)
+    {
+        PyErr_SetString (PyExc_SystemError, 
+                         "Accessing non-existent array segment");
+        return -1;
+    }
+
+    if (!buffer->parent)
+    {
+        *ptr = NULL;
+        return 0;
+    }
+
+    *ptr = buffer->buffer;
+    return buffer->length;
+}
+
+static Py_ssize_t
+_bufferproxy_getsegcount (PyBufferProxy *buffer, Py_ssize_t *lenp)
+{
+    if (!buffer->parent)
+    {
+        *lenp = 0;
+        return 0;
+    }
+
+    if (lenp)
+        *lenp = buffer->length;
+    return 1;
+}
+
+static PyObject*
+PyBufferProxy_New (PyObject *parent, void *buffer, Py_ssize_t length,
+                   PyObject *lock)
+{
+    PyBufferProxy *buf;
+
+    buf = (PyBufferProxy *) _bufferproxy_new (&PyBufferProxy_Type, NULL, NULL);
+
+    if (!buf)
+        return NULL;
+    buf->buffer = buffer;
+    buf->length = length;
+    buf->lock = lock;
+    buf->parent = parent;
+    return (PyObject *) buf;
+}
+
+PYGAME_EXPORT
+void initbufferproxy (void)
+{
+    PyObject *module;
+    PyObject *dict;
+    PyObject *apiobj;
+    static void* c_api[PYGAMEAPI_BUFFERPROXY_NUMSLOTS];
+
+    if (PyType_Ready (&PyBufferProxy_Type) < 0)
+        return;
+
+    /* create the module */
+    module = Py_InitModule3 ("bufferproxy", NULL, NULL);
+    PyBufferProxy_Type.tp_getattro = PyObject_GenericGetAttr;
+    Py_INCREF (&PyBufferProxy_Type);
+    PyModule_AddObject (module, "BufferProxy", (PyObject *)&PyBufferProxy_Type);
+    dict = PyModule_GetDict (module);
+
+    c_api[0] = &PyBufferProxy_Type;
+    c_api[1] = PyBufferProxy_New;
+    apiobj = PyCObject_FromVoidPtr (c_api, NULL);
+    PyDict_SetItemString (dict, PYGAMEAPI_LOCAL_ENTRY, apiobj);
+    Py_DECREF (apiobj);
+
+
+}