2
pygame - Python Game Library
3
Copyright (C) 2000-2001 Pete Shinners
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public
7
License as published by the Free Software Foundation; either
8
version 2 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public
16
License along with this library; if not, write to the Free
17
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
* internal surface locking support for python objects
26
#define PYGAMEAPI_SURFLOCK_INTERNAL
31
/*extra Surface documentation*/
32
#if 0 /*extra help, only for docs, not docstrings*/
33
/*DOC*/ static char doc_Surface_EXTRA[] =
34
/*DOC*/ "Any functions that directly access a surface's pixel data will\n"
35
/*DOC*/ "need that surface to be lock()'ed. These functions can lock()\n"
36
/*DOC*/ "and unlock() the surfaces themselves without assistance. But, if\n"
37
/*DOC*/ "a function will be called many times, there will be a lot of overhead\n"
38
/*DOC*/ "for multiple locking and unlocking of the surface. It is best to lock\n"
39
/*DOC*/ "the surface manually before making the function call many times, and\n"
40
/*DOC*/ "then unlocking when you are finished. All functions that need a locked\n"
41
/*DOC*/ "surface will say so in their docs.\n"
43
/*DOC*/ "Also remember that you will want to leave the surface locked for the\n"
44
/*DOC*/ "shortest amount of time needed.\n"
47
/*DOC*/ "Here is the quick breakdown of how packed pixels work (don't worry if\n"
48
/*DOC*/ "you don't quite understand this, it is only here for informational\n"
49
/*DOC*/ "purposes, it is not needed). Each colorplane mask can be used to\n"
50
/*DOC*/ "isolate the values for a colorplane from the packed pixel color.\n"
51
/*DOC*/ "Therefore PACKED_COLOR & RED_MASK == REDPLANE. Note that the\n"
52
/*DOC*/ "REDPLANE is not exactly the red color value, but it is the red\n"
53
/*DOC*/ "color value bitwise left shifted a certain amount. The losses and\n"
54
/*DOC*/ "masks can be used to convert back and forth between each\n"
55
/*DOC*/ "colorplane and the actual color for that plane. Here are the\n"
56
/*DOC*/ "final formulas used be map and unmap.\n"
57
/*DOC*/ "PACKED_COLOR = RED>>losses[0]<<shifts[0] |\n"
58
/*DOC*/ " GREEN>>losses[1]<<shifts[1] | BLUE>>losses[2]<<shifts[2]\n"
59
/*DOC*/ "RED = PACKED_COLOR & masks[0] >> shifts[0] << losses[0]\n"
60
/*DOC*/ "GREEN = PACKED_COLOR & masks[1] >> shifts[1] << losses[1]\n"
61
/*DOC*/ "BLUE = PACKED_COLOR & masks[2] >> shifts[2] << losses[2]\n"
62
/*DOC*/ "There is also an alpha channel for some Surfaces.\n"
71
static int PySurface_Lock(PyObject* surfobj);
72
static int PySurface_Unlock(PyObject* surfobj);
76
static void PySurface_Prep(PyObject* surfobj)
78
struct SubSurface_Data* data = ((PySurfaceObject*)surfobj)->subsurface;
81
SDL_Surface* surf = PySurface_AsSurface(surfobj);
82
SDL_Surface* owner = PySurface_AsSurface(data->owner);
83
PySurface_Lock(data->owner);
84
surf->pixels = ((char*)owner->pixels) + data->pixeloffset;
88
static void PySurface_Unprep(PyObject* surfobj)
90
struct SubSurface_Data* data = ((PySurfaceObject*)surfobj)->subsurface;
92
PySurface_Unlock(data->owner);
95
static int PySurface_Lock(PyObject* surfobj)
97
PySurfaceObject* surf = (PySurfaceObject*)surfobj;
99
PySurface_Prep(surfobj);
100
if(!surf->lockcount && (surf->subsurface || !surf->surf->pixels))
102
if(SDL_LockSurface(surf->surf) == -1)
104
PyErr_SetString(PyExc_RuntimeError, "error locking surface");
114
static int PySurface_Unlock(PyObject* surfobj)
116
PySurfaceObject* surf = (PySurfaceObject*)surfobj;
118
if(!surf->lockcount && surf->didlock)
121
SDL_UnlockSurface(surf->surf);
123
if(surf->lockcount < 0)
125
PyErr_SetString(PyExc_RuntimeError, "attempt to unlock an unlocked surface");
129
PySurface_Unprep(surfobj);
137
/* lifetimelock object internals */
142
} PyLifetimeLockObject;
144
static void lifelock_dealloc(PyObject* self)
146
PyLifetimeLockObject* lifelock = (PyLifetimeLockObject*)self;
148
PySurface_Unlock(lifelock->surface);
149
Py_DECREF(lifelock->surface);
154
static PyTypeObject PyLifetimeLock_Type =
156
PyObject_HEAD_INIT(NULL)
158
"SurfLifeLock", /*name*/
159
sizeof(PyLifetimeLockObject),/*basic size*/
161
lifelock_dealloc, /*dealloc*/
165
static PyObject* PySurface_LockLifetime(PyObject* surf)
167
PyLifetimeLockObject* life;
168
if(!surf) return RAISE(PyExc_SDLError, SDL_GetError());
170
if(!PySurface_Lock(surf))
173
life = PyObject_NEW(PyLifetimeLockObject, &PyLifetimeLock_Type);
176
life->surface = surf;
179
return (PyObject*)life;
186
static PyMethodDef surflock__builtins__[] =
193
void initsurflock(void)
195
PyObject *module, *dict, *apiobj;
196
static void* c_api[PYGAMEAPI_SURFLOCK_NUMSLOTS];
198
PyType_Init(PyLifetimeLock_Type);
201
/* Create the module and add the functions */
202
module = Py_InitModule3("surflock", surflock__builtins__, "Surface locking support");
203
dict = PyModule_GetDict(module);
205
/* export the c api */
206
c_api[0] = PySurface_Prep;
207
c_api[1] = PySurface_Unprep;
208
c_api[2] = PySurface_Lock;
209
c_api[3] = PySurface_Unlock;
210
c_api[4] = PySurface_LockLifetime;
211
apiobj = PyCObject_FromVoidPtr(c_api, NULL);
212
PyDict_SetItemString(dict, PYGAMEAPI_LOCAL_ENTRY, apiobj);