Mercurial > pygame
view src/_view.c @ 3194:9fcb7abf3185 default tip
Remove some gcc 4.7.2 compiler warnings
| author | Lenard Lindstrom <len-l@telus.net> |
|---|---|
| date | Tue, 23 Apr 2013 19:53:36 -0700 |
| parents | 841b902f3d15 |
| children |
line wrap: on
line source
/* pygame - Python Game Library Module adapted from bufferproxy.c, 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 */ /* This module exports an object which provides a C level interface to another object's buffer. For now only an array structure - __array_struct__ - interface is exposed. When memoryview is ready it will replace the View object. */ #define NO_PYGAME_C_API #include "pygame.h" #include "pgcompat.h" #include "pgview.h" typedef struct { PyObject_HEAD PyObject *capsule; /* Wrapped array struct */ PyObject *parent; /* Object responsible for the view */ PgView_Destructor destructor; /* Optional release callback */ PyObject *pydestructor; /* Python callable destructor */ PyObject *weakrefs; /* There can be reference cycles */ } PgViewObject; static int Pg_GetArrayInterface(PyObject *, PyObject **, PyArrayInterface **); static PyObject *Pg_ArrayStructAsDict(PyArrayInterface *); /** * Helper functions. */ static void _view_default_destructor(PyObject *view) { PgViewObject *v = (PgViewObject *)view; PyObject *rvalue; if (v->pydestructor) { rvalue = PyObject_CallFunctionObjArgs(v->pydestructor, v->capsule, v->parent, 0); PyErr_Clear(); Py_XDECREF(rvalue); } } static PyObject * _view_new_from_type(PyTypeObject *type, PyObject *capsule, PyObject *parent, PgView_Destructor destructor, PyObject *pydestructor) { PgViewObject *self = (PgViewObject *)type->tp_alloc(type, 0); if (!self) { return 0; } self->weakrefs = 0; Py_INCREF(capsule); self->capsule = capsule; if (!parent) { parent = Py_None; } Py_INCREF(parent); self->parent = parent; self->destructor = destructor ? destructor : _view_default_destructor; Py_XINCREF(pydestructor); self->pydestructor = pydestructor; return (PyObject *)self; } static PyObject * _shape_as_tuple(PyArrayInterface *inter_p) { PyObject *shapeobj = PyTuple_New((Py_ssize_t)inter_p->nd); PyObject *lengthobj; Py_ssize_t i; if (!shapeobj) { return 0; } for (i = 0; i < inter_p->nd; ++i) { lengthobj = PyInt_FromLong((long)inter_p->shape[i]); if (!lengthobj) { Py_DECREF(shapeobj); return 0; } PyTuple_SET_ITEM(shapeobj, i, lengthobj); } return shapeobj; } #if SDL_BYTEORDER == SDL_LIL_ENDIAN #define MY_ENDIAN '<' #define OTHER_ENDIAN '>' #else #define MY_ENDIAN '>' #define OTHER_ENDIAN '<' #endif static PyObject * _typekind_as_str(PyArrayInterface *inter_p) { return Text_FromFormat("%c%c%i", inter_p->flags & PAI_NOTSWAPPED ? MY_ENDIAN : OTHER_ENDIAN, inter_p->typekind, inter_p->itemsize); } #undef MY_ENDIAN #undef OTHER_ENDIAN static PyObject *_strides_as_tuple(PyArrayInterface *inter_p) { PyObject *stridesobj = PyTuple_New((Py_ssize_t)inter_p->nd); PyObject *lengthobj; Py_ssize_t i; if (!stridesobj) { return 0; } for (i = 0; i < inter_p->nd; ++i) { lengthobj = PyInt_FromLong((long)inter_p->strides[i]); if (!lengthobj) { Py_DECREF(stridesobj); return 0; } PyTuple_SET_ITEM(stridesobj, i, lengthobj); } return stridesobj; } static PyObject *_data_as_tuple(PyArrayInterface *inter_p) { long readonly = (inter_p->flags & PAI_WRITEABLE) == 0; return Py_BuildValue("NN", PyLong_FromVoidPtr(inter_p->data), PyBool_FromLong(readonly)); } /** * Creates a new PgViewObject. */ static PyObject * _view_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *capsule; PyObject *parent = 0; PyObject *pydestructor = 0; char *keywords[] = {"capsule", "parent", "destructor", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:View", keywords, &capsule, &parent, &pydestructor)) { return 0; } if (pydestructor == Py_None) { pydestructor = 0; } return _view_new_from_type(type, capsule, parent, 0, pydestructor); } /** * Deallocates the PgViewObject and its members. */ static void _view_dealloc(PgViewObject *self) { PgView_Destructor destructor = self->destructor; /* Guard against recursion */ self->destructor = 0; if (!destructor) { return; } destructor((PyObject *)self); Py_DECREF(self->capsule); Py_DECREF(self->parent); Py_XDECREF(self->pydestructor); if (self->weakrefs) { PyObject_ClearWeakRefs((PyObject *)self); } Py_TYPE(self)->tp_free(self); } /**** Getter and setter access ****/ static PyObject * _view_get_arraystruct(PgViewObject *self, PyObject *closure) { Py_INCREF(self->capsule); return self->capsule; } static PyObject * _view_get_parent(PgViewObject *self, PyObject *closure) { if (!self->parent) { Py_RETURN_NONE; } Py_INCREF(self->parent); return self->parent; } /**** Methods ****/ /** * Representation method. */ static PyObject * _view_repr (PgViewObject *self) { return Text_FromFormat("<%s(%p)>", Py_TYPE(self)->tp_name, self->capsule); } /** * Getters and setters for the PgViewObject. */ static PyGetSetDef _view_getsets[] = { {"__array_struct__", (getter)_view_get_arraystruct, 0, 0, 0}, {"parent", (getter)_view_get_parent, 0, 0, 0}, {0, 0, 0, 0, 0} }; static PyTypeObject PgView_Type = { TYPE_HEAD (NULL, 0) "pygame._view.View", /* tp_name */ sizeof (PgViewObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)_view_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)_view_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 */ 0, /* tp_as_buffer */ (Py_TPFLAGS_HAVE_WEAKREFS | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_CLASS), "Object view as an array struct\n", 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(PgViewObject, weakrefs), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ _view_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ _view_new, /* tp_new */ 0, /* tp_free */ #ifndef __SYMBIAN32__ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ 0 /* tp_del */ #endif }; /**** Module methods ***/ static PyObject * get_array_interface(PyObject *self, PyObject *arg) { PyObject *cobj; PyArrayInterface *inter_p; PyObject *dictobj; if (Pg_GetArrayInterface(arg, &cobj, &inter_p)) { return 0; } dictobj = Pg_ArrayStructAsDict(inter_p); Py_DECREF(cobj); return dictobj; } static PyMethodDef _view_methods[] = { { "get_array_interface", get_array_interface, METH_O, "return an array struct interface as an interface dictionary" }, {0, 0, 0, 0} }; /**** Public C api ***/ static PyObject * PgView_New(PyObject *capsule, PyObject *parent, PgView_Destructor destructor) { if (!capsule) { PyErr_SetString(PyExc_TypeError, "the capsule argument is required"); return 0; } return _view_new_from_type(&PgView_Type, capsule, parent, destructor, 0); } static PyObject * PgView_GetCapsule(PyObject *view) { PyObject *capsule = ((PgViewObject *)view)->capsule; Py_INCREF(capsule); return capsule; } static PyObject * PgView_GetParent(PyObject *view) { PyObject *parent = ((PgViewObject *)view)->parent; Py_INCREF(parent); return parent; } static int Pg_GetArrayInterface(PyObject *obj, PyObject **cobj_p, PyArrayInterface **inter_p) { PyObject *cobj = PyObject_GetAttrString(obj, "__array_struct__"); PyArrayInterface *inter = NULL; if (cobj == NULL) { if (PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); PyErr_SetString(PyExc_ValueError, "no C-struct array interface"); } return -1; } #if PG_HAVE_COBJECT if (PyCObject_Check(cobj)) { inter = (PyArrayInterface *)PyCObject_AsVoidPtr(cobj); } #endif #if PG_HAVE_CAPSULE if (PyCapsule_IsValid(cobj, NULL)) { inter = (PyArrayInterface *)PyCapsule_GetPointer(cobj, NULL); } #endif if (inter == NULL || /* conditional or */ inter->two != 2 ) { Py_DECREF(cobj); PyErr_SetString(PyExc_ValueError, "invalid array interface"); return -1; } *cobj_p = cobj; *inter_p = inter; return 0; } static PyObject * Pg_ArrayStructAsDict(PyArrayInterface *inter_p) { PyObject *dictobj = Py_BuildValue("{sisNsNsNsN}", "version", (int)3, "typestr", _typekind_as_str(inter_p), "shape", _shape_as_tuple(inter_p), "strides", _strides_as_tuple(inter_p), "data", _data_as_tuple(inter_p)); if (!dictobj) { return 0; } if (inter_p->flags & PAI_ARR_HAS_DESCR) { if (!inter_p->descr) { Py_DECREF(dictobj); PyErr_SetString(PyExc_ValueError, "Array struct has descr flag set" " but no descriptor"); return 0; } if (PyDict_SetItemString(dictobj, "descr", inter_p->descr)) { return 0; } } return dictobj; } /*DOC*/ static char _view_doc[] = /*DOC*/ "exports View, a generic wrapper object for an array " /*DOC*/ "struct capsule"; MODINIT_DEFINE(_view) { PyObject *module; PyObject *apiobj; static void* c_api[PYGAMEAPI_VIEW_NUMSLOTS]; #if PY3 static struct PyModuleDef _module = { PyModuleDef_HEAD_INIT, "_view", _view_doc, -1, _view_methods, NULL, NULL, NULL, NULL }; #endif if (PyType_Ready(&PgView_Type) < 0) { MODINIT_ERROR; } /* create the module */ #if PY3 module = PyModule_Create(&_module); #else module = Py_InitModule3(MODPREFIX "_view", _view_methods, _view_doc); #endif Py_INCREF(&PgView_Type); if (PyModule_AddObject(module, "View", (PyObject *)&PgView_Type)) { Py_DECREF(&PgView_Type); DECREF_MOD(module); MODINIT_ERROR; } #if PYGAMEAPI_VIEW_NUMSLOTS != 6 #error export slot count mismatch #endif c_api[0] = &PgView_Type; c_api[1] = PgView_New; c_api[2] = PgView_GetCapsule; c_api[3] = PgView_GetParent; c_api[4] = Pg_GetArrayInterface; c_api[5] = Pg_ArrayStructAsDict; apiobj = encapsulate_api(c_api, "_view"); if (apiobj == NULL) { DECREF_MOD(module); MODINIT_ERROR; } if (PyModule_AddObject(module, PYGAMEAPI_LOCAL_ENTRY, apiobj)) { Py_DECREF(apiobj); DECREF_MOD(module); MODINIT_ERROR; } MODINIT_RETURN(module); }
